mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8249192: MonitorInfo stores raw oops across safepoints
Change raw oops in MonitorInfo to Handles and update Resource/HandleMarks. Reviewed-by: sspitsyn, dholmes, coleenp, dcubed
This commit is contained in:
parent
bb6647c845
commit
6d665ed31f
8 changed files with 62 additions and 45 deletions
|
@ -724,13 +724,13 @@ JvmtiEnvBase::get_locked_objects_in_frame(JavaThread* calling_thread, JavaThread
|
||||||
javaVFrame *jvf, GrowableArray<jvmtiMonitorStackDepthInfo*>* owned_monitors_list, jint stack_depth) {
|
javaVFrame *jvf, GrowableArray<jvmtiMonitorStackDepthInfo*>* owned_monitors_list, jint stack_depth) {
|
||||||
jvmtiError err = JVMTI_ERROR_NONE;
|
jvmtiError err = JVMTI_ERROR_NONE;
|
||||||
ResourceMark rm;
|
ResourceMark rm;
|
||||||
|
HandleMark hm;
|
||||||
|
|
||||||
GrowableArray<MonitorInfo*>* mons = jvf->monitors();
|
GrowableArray<MonitorInfo*>* mons = jvf->monitors();
|
||||||
if (mons->is_empty()) {
|
if (mons->is_empty()) {
|
||||||
return err; // this javaVFrame holds no monitors
|
return err; // this javaVFrame holds no monitors
|
||||||
}
|
}
|
||||||
|
|
||||||
HandleMark hm;
|
|
||||||
oop wait_obj = NULL;
|
oop wait_obj = NULL;
|
||||||
{
|
{
|
||||||
// The ObjectMonitor* can't be async deflated since we are either
|
// The ObjectMonitor* can't be async deflated since we are either
|
||||||
|
@ -1005,7 +1005,6 @@ JvmtiEnvBase::get_object_monitor_usage(JavaThread* calling_thread, jobject objec
|
||||||
// as lightweight locks before inflating the monitor are not included.
|
// as lightweight locks before inflating the monitor are not included.
|
||||||
// We have to count the number of recursive monitor entries the hard way.
|
// We have to count the number of recursive monitor entries the hard way.
|
||||||
// We pass a handle to survive any GCs along the way.
|
// We pass a handle to survive any GCs along the way.
|
||||||
ResourceMark rm(current_thread);
|
|
||||||
ret.entry_count = count_locked_objects(owning_thread, hobj);
|
ret.entry_count = count_locked_objects(owning_thread, hobj);
|
||||||
}
|
}
|
||||||
// implied else: entry_count == 0
|
// implied else: entry_count == 0
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -288,6 +288,9 @@ void LiveFrameStream::fill_live_stackframe(Handle stackFrame,
|
||||||
const methodHandle& method, TRAPS) {
|
const methodHandle& method, TRAPS) {
|
||||||
fill_stackframe(stackFrame, method, CHECK);
|
fill_stackframe(stackFrame, method, CHECK);
|
||||||
if (_jvf != NULL) {
|
if (_jvf != NULL) {
|
||||||
|
ResourceMark rm(THREAD);
|
||||||
|
HandleMark hm(THREAD);
|
||||||
|
|
||||||
StackValueCollection* locals = _jvf->locals();
|
StackValueCollection* locals = _jvf->locals();
|
||||||
StackValueCollection* expressions = _jvf->expressions();
|
StackValueCollection* expressions = _jvf->expressions();
|
||||||
GrowableArray<MonitorInfo*>* monitors = _jvf->monitors();
|
GrowableArray<MonitorInfo*>* monitors = _jvf->monitors();
|
||||||
|
|
|
@ -906,8 +906,10 @@ void BiasedLocking::preserve_marks() {
|
||||||
_preserved_mark_stack = new (ResourceObj::C_HEAP, mtGC) GrowableArray<markWord>(10, mtGC);
|
_preserved_mark_stack = new (ResourceObj::C_HEAP, mtGC) GrowableArray<markWord>(10, mtGC);
|
||||||
_preserved_oop_stack = new (ResourceObj::C_HEAP, mtGC) GrowableArray<Handle>(10, mtGC);
|
_preserved_oop_stack = new (ResourceObj::C_HEAP, mtGC) GrowableArray<Handle>(10, mtGC);
|
||||||
|
|
||||||
ResourceMark rm;
|
|
||||||
Thread* cur = Thread::current();
|
Thread* cur = Thread::current();
|
||||||
|
ResourceMark rm(cur);
|
||||||
|
HandleMark hm(cur);
|
||||||
|
|
||||||
for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thread = jtiwh.next(); ) {
|
for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thread = jtiwh.next(); ) {
|
||||||
if (thread->has_last_Java_frame()) {
|
if (thread->has_last_Java_frame()) {
|
||||||
RegisterMap rm(thread);
|
RegisterMap rm(thread);
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
@ -218,6 +216,7 @@ static bool eliminate_allocations(JavaThread* thread, int exec_mode, CompiledMet
|
||||||
}
|
}
|
||||||
|
|
||||||
static void eliminate_locks(JavaThread* thread, GrowableArray<compiledVFrame*>* chunk, bool realloc_failures) {
|
static void eliminate_locks(JavaThread* thread, GrowableArray<compiledVFrame*>* chunk, bool realloc_failures) {
|
||||||
|
HandleMark hm;
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
bool first = true;
|
bool first = true;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1535,6 +1534,8 @@ void Deoptimization::revoke_from_deopt_handler(JavaThread* thread, frame fr, Reg
|
||||||
if (!UseBiasedLocking) {
|
if (!UseBiasedLocking) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
ResourceMark rm;
|
||||||
|
HandleMark hm;
|
||||||
GrowableArray<Handle>* objects_to_revoke = new GrowableArray<Handle>();
|
GrowableArray<Handle>* objects_to_revoke = new GrowableArray<Handle>();
|
||||||
get_monitors_from_stack(objects_to_revoke, thread, fr, map);
|
get_monitors_from_stack(objects_to_revoke, thread, fr, map);
|
||||||
|
|
||||||
|
|
|
@ -165,6 +165,7 @@ void javaVFrame::print_locked_object_class_name(outputStream* st, Handle obj, co
|
||||||
void javaVFrame::print_lock_info_on(outputStream* st, int frame_count) {
|
void javaVFrame::print_lock_info_on(outputStream* st, int frame_count) {
|
||||||
Thread* THREAD = Thread::current();
|
Thread* THREAD = Thread::current();
|
||||||
ResourceMark rm(THREAD);
|
ResourceMark rm(THREAD);
|
||||||
|
HandleMark hm(THREAD);
|
||||||
|
|
||||||
// If this is the first frame and it is java.lang.Object.wait(...)
|
// If this is the first frame and it is java.lang.Object.wait(...)
|
||||||
// then print out the receiver. Locals are not always available,
|
// then print out the receiver. Locals are not always available,
|
||||||
|
@ -447,6 +448,21 @@ void interpretedVFrame::set_locals(StackValueCollection* values) const {
|
||||||
entryVFrame::entryVFrame(const frame* fr, const RegisterMap* reg_map, JavaThread* thread)
|
entryVFrame::entryVFrame(const frame* fr, const RegisterMap* reg_map, JavaThread* thread)
|
||||||
: externalVFrame(fr, reg_map, thread) {}
|
: externalVFrame(fr, reg_map, thread) {}
|
||||||
|
|
||||||
|
MonitorInfo::MonitorInfo(oop owner, BasicLock* lock, bool eliminated, bool owner_is_scalar_replaced) {
|
||||||
|
Thread* thread = Thread::current();
|
||||||
|
if (!owner_is_scalar_replaced) {
|
||||||
|
_owner = Handle(thread, owner);
|
||||||
|
_owner_klass = Handle();
|
||||||
|
} else {
|
||||||
|
assert(eliminated, "monitor should be eliminated for scalar replaced object");
|
||||||
|
_owner = Handle();
|
||||||
|
_owner_klass = Handle(thread, owner);
|
||||||
|
}
|
||||||
|
_lock = lock;
|
||||||
|
_eliminated = eliminated;
|
||||||
|
_owner_is_scalar_replaced = owner_is_scalar_replaced;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
void vframeStreamCommon::found_bad_method_frame() const {
|
void vframeStreamCommon::found_bad_method_frame() const {
|
||||||
// 6379830 Cut point for an assertion that occasionally fires when
|
// 6379830 Cut point for an assertion that occasionally fires when
|
||||||
|
@ -612,6 +628,8 @@ static void print_stack_values(const char* title, StackValueCollection* values)
|
||||||
|
|
||||||
void javaVFrame::print() {
|
void javaVFrame::print() {
|
||||||
ResourceMark rm;
|
ResourceMark rm;
|
||||||
|
HandleMark hm;
|
||||||
|
|
||||||
vframe::print();
|
vframe::print();
|
||||||
tty->print("\t");
|
tty->print("\t");
|
||||||
method()->print_value();
|
method()->print_value();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -30,6 +30,7 @@
|
||||||
#include "code/location.hpp"
|
#include "code/location.hpp"
|
||||||
#include "oops/oop.hpp"
|
#include "oops/oop.hpp"
|
||||||
#include "runtime/frame.hpp"
|
#include "runtime/frame.hpp"
|
||||||
|
#include "runtime/handles.inline.hpp"
|
||||||
#include "runtime/stackValue.hpp"
|
#include "runtime/stackValue.hpp"
|
||||||
#include "runtime/stackValueCollection.hpp"
|
#include "runtime/stackValueCollection.hpp"
|
||||||
#include "utilities/growableArray.hpp"
|
#include "utilities/growableArray.hpp"
|
||||||
|
@ -241,34 +242,22 @@ class entryVFrame: public externalVFrame {
|
||||||
// 2) the monitor lock
|
// 2) the monitor lock
|
||||||
class MonitorInfo : public ResourceObj {
|
class MonitorInfo : public ResourceObj {
|
||||||
private:
|
private:
|
||||||
oop _owner; // the object owning the monitor
|
Handle _owner; // the object owning the monitor
|
||||||
BasicLock* _lock;
|
BasicLock* _lock;
|
||||||
oop _owner_klass; // klass (mirror) if owner was scalar replaced
|
Handle _owner_klass; // klass (mirror) if owner was scalar replaced
|
||||||
bool _eliminated;
|
bool _eliminated;
|
||||||
bool _owner_is_scalar_replaced;
|
bool _owner_is_scalar_replaced;
|
||||||
public:
|
public:
|
||||||
// Constructor
|
// Constructor
|
||||||
MonitorInfo(oop owner, BasicLock* lock, bool eliminated, bool owner_is_scalar_replaced) {
|
MonitorInfo(oop owner, BasicLock* lock, bool eliminated, bool owner_is_scalar_replaced);
|
||||||
if (!owner_is_scalar_replaced) {
|
|
||||||
_owner = owner;
|
|
||||||
_owner_klass = NULL;
|
|
||||||
} else {
|
|
||||||
assert(eliminated, "monitor should be eliminated for scalar replaced object");
|
|
||||||
_owner = NULL;
|
|
||||||
_owner_klass = owner;
|
|
||||||
}
|
|
||||||
_lock = lock;
|
|
||||||
_eliminated = eliminated;
|
|
||||||
_owner_is_scalar_replaced = owner_is_scalar_replaced;
|
|
||||||
}
|
|
||||||
// Accessors
|
// Accessors
|
||||||
oop owner() const {
|
oop owner() const {
|
||||||
assert(!_owner_is_scalar_replaced, "should not be called for scalar replaced object");
|
assert(!_owner_is_scalar_replaced, "should not be called for scalar replaced object");
|
||||||
return _owner;
|
return _owner();
|
||||||
}
|
}
|
||||||
oop owner_klass() const {
|
oop owner_klass() const {
|
||||||
assert(_owner_is_scalar_replaced, "should not be called for not scalar replaced object");
|
assert(_owner_is_scalar_replaced, "should not be called for not scalar replaced object");
|
||||||
return _owner_klass;
|
return _owner_klass();
|
||||||
}
|
}
|
||||||
BasicLock* lock() const { return _lock; }
|
BasicLock* lock() const { return _lock; }
|
||||||
bool eliminated() const { return _eliminated; }
|
bool eliminated() const { return _eliminated; }
|
||||||
|
|
|
@ -70,28 +70,32 @@ void vframeArrayElement::fill_in(compiledVFrame* vf, bool realloc_failures) {
|
||||||
|
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
// Get the monitors off-stack
|
{
|
||||||
|
ResourceMark rm;
|
||||||
|
HandleMark hm;
|
||||||
|
// Get the monitors off-stack
|
||||||
|
|
||||||
GrowableArray<MonitorInfo*>* list = vf->monitors();
|
GrowableArray<MonitorInfo*>* list = vf->monitors();
|
||||||
if (list->is_empty()) {
|
if (list->is_empty()) {
|
||||||
_monitors = NULL;
|
_monitors = NULL;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Allocate monitor chunk
|
// Allocate monitor chunk
|
||||||
_monitors = new MonitorChunk(list->length());
|
_monitors = new MonitorChunk(list->length());
|
||||||
vf->thread()->add_monitor_chunk(_monitors);
|
vf->thread()->add_monitor_chunk(_monitors);
|
||||||
|
|
||||||
// Migrate the BasicLocks from the stack to the monitor chunk
|
// Migrate the BasicLocks from the stack to the monitor chunk
|
||||||
for (index = 0; index < list->length(); index++) {
|
for (index = 0; index < list->length(); index++) {
|
||||||
MonitorInfo* monitor = list->at(index);
|
MonitorInfo* monitor = list->at(index);
|
||||||
assert(!monitor->owner_is_scalar_replaced() || realloc_failures, "object should be reallocated already");
|
assert(!monitor->owner_is_scalar_replaced() || realloc_failures, "object should be reallocated already");
|
||||||
BasicObjectLock* dest = _monitors->at(index);
|
BasicObjectLock* dest = _monitors->at(index);
|
||||||
if (monitor->owner_is_scalar_replaced()) {
|
if (monitor->owner_is_scalar_replaced()) {
|
||||||
dest->set_obj(NULL);
|
dest->set_obj(NULL);
|
||||||
} else {
|
} else {
|
||||||
assert(monitor->owner() == NULL || (!monitor->owner()->is_unlocked() && !monitor->owner()->has_bias_pattern()), "object must be null or locked, and unbiased");
|
assert(monitor->owner() == NULL || (!monitor->owner()->is_unlocked() && !monitor->owner()->has_bias_pattern()), "object must be null or locked, and unbiased");
|
||||||
dest->set_obj(monitor->owner());
|
dest->set_obj(monitor->owner());
|
||||||
monitor->lock()->move_to(monitor->owner(), dest->lock());
|
monitor->lock()->move_to(monitor->owner(), dest->lock());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -567,6 +567,7 @@ StackFrameInfo::StackFrameInfo(javaVFrame* jvf, bool with_lock_info) {
|
||||||
_locked_monitors = NULL;
|
_locked_monitors = NULL;
|
||||||
if (with_lock_info) {
|
if (with_lock_info) {
|
||||||
ResourceMark rm;
|
ResourceMark rm;
|
||||||
|
HandleMark hm;
|
||||||
GrowableArray<MonitorInfo*>* list = jvf->locked_monitors();
|
GrowableArray<MonitorInfo*>* list = jvf->locked_monitors();
|
||||||
int length = list->length();
|
int length = list->length();
|
||||||
if (length > 0) {
|
if (length > 0) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue