8180175: ObjectSynchronizer only needs to iterate in-use monitors

When using -XX:+MonitorInUseLists, then only iterate in-use monitors.

Reviewed-by: zgu, dholmes, rehn
This commit is contained in:
Roman Kennke 2017-05-17 23:36:19 +02:00
parent ae8a3dd115
commit 553d1e815b
3 changed files with 47 additions and 0 deletions

View file

@ -964,6 +964,17 @@ static inline ObjectMonitor* next(ObjectMonitor* block) {
void ObjectSynchronizer::oops_do(OopClosure* f) { void ObjectSynchronizer::oops_do(OopClosure* f) {
if (MonitorInUseLists) {
// When using thread local monitor lists, we only scan the
// global used list here (for moribund threads), and
// the thread-local monitors in Thread::oops_do().
global_used_oops_do(f);
} else {
global_oops_do(f);
}
}
void ObjectSynchronizer::global_oops_do(OopClosure* f) {
assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
PaddedEnd<ObjectMonitor> * block = PaddedEnd<ObjectMonitor> * block =
(PaddedEnd<ObjectMonitor> *)OrderAccess::load_ptr_acquire(&gBlockList); (PaddedEnd<ObjectMonitor> *)OrderAccess::load_ptr_acquire(&gBlockList);
@ -978,6 +989,26 @@ void ObjectSynchronizer::oops_do(OopClosure* f) {
} }
} }
void ObjectSynchronizer::global_used_oops_do(OopClosure* f) {
assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
list_oops_do(gOmInUseList, f);
}
void ObjectSynchronizer::thread_local_used_oops_do(Thread* thread, OopClosure* f) {
assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
list_oops_do(thread->omInUseList, f);
}
void ObjectSynchronizer::list_oops_do(ObjectMonitor* list, OopClosure* f) {
assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
ObjectMonitor* mid;
for (mid = list; mid != NULL; mid = mid->FreeNext) {
if (mid->object() != NULL) {
f->do_oop((oop*)mid->object_addr());
}
}
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// ObjectMonitor Lifecycle // ObjectMonitor Lifecycle

View file

@ -136,6 +136,8 @@ class ObjectSynchronizer : AllStatic {
ObjectMonitor** freeHeadp, ObjectMonitor** freeHeadp,
ObjectMonitor** freeTailp); ObjectMonitor** freeTailp);
static void oops_do(OopClosure* f); static void oops_do(OopClosure* f);
// Process oops in thread local used monitors
static void thread_local_used_oops_do(Thread* thread, OopClosure* f);
// debugging // debugging
static void sanity_checks(const bool verbose, static void sanity_checks(const bool verbose,
@ -156,6 +158,14 @@ class ObjectSynchronizer : AllStatic {
static ObjectMonitor * volatile gOmInUseList; static ObjectMonitor * volatile gOmInUseList;
// count of entries in gOmInUseList // count of entries in gOmInUseList
static int gOmInUseCount; static int gOmInUseCount;
// Process oops in all monitors
static void global_oops_do(OopClosure* f);
// Process oops in all global used monitors (i.e. moribund thread's monitors)
static void global_used_oops_do(OopClosure* f);
// Process oops in monitors on the given list
static void list_oops_do(ObjectMonitor* list, OopClosure* f);
}; };
// ObjectLocker enforced balanced locking and can never thrown an // ObjectLocker enforced balanced locking and can never thrown an

View file

@ -792,6 +792,12 @@ void Thread::oops_do(OopClosure* f, CodeBlobClosure* cf) {
// Do oop for ThreadShadow // Do oop for ThreadShadow
f->do_oop((oop*)&_pending_exception); f->do_oop((oop*)&_pending_exception);
handle_area()->oops_do(f); handle_area()->oops_do(f);
if (MonitorInUseLists) {
// When using thread local monitor lists, we scan them here,
// and the remaining global monitors in ObjectSynchronizer::oops_do().
ObjectSynchronizer::thread_local_used_oops_do(this, f);
}
} }
void Thread::metadata_handles_do(void f(Metadata*)) { void Thread::metadata_handles_do(void f(Metadata*)) {