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:
Thomas Schatzl 2020-07-23 21:10:52 +02:00
parent bb6647c845
commit 6d665ed31f
8 changed files with 62 additions and 45 deletions

View file

@ -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

View file

@ -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();

View file

@ -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);

View file

@ -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);

View file

@ -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();

View file

@ -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; }

View file

@ -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());
}
} }
} }
} }

View file

@ -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) {