# HG changeset patch # User rkennke # Date 1495056979 -7200 # Wed May 17 23:36:19 2017 +0200 # Node ID 0e1fc72e7ffbeec0e23cf512a3adccbf468401d9 # Parent 445d08e24553222b011b8d5cf5c3ee22d703805b 8180175: ObjectSynchronizer only needs to iterate in-use monitors Summary: When using -XX:+MonitorInUseLists, then only iterate in-use monitors. Reviewed-by: zgu,dholmes diff --git a/src/share/vm/runtime/synchronizer.cpp b/src/share/vm/runtime/synchronizer.cpp --- a/src/share/vm/runtime/synchronizer.cpp +++ b/src/share/vm/runtime/synchronizer.cpp @@ -964,6 +964,17 @@ 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"); PaddedEnd * block = (PaddedEnd *)OrderAccess::load_ptr_acquire(&gBlockList); @@ -978,6 +989,26 @@ } } +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 diff --git a/src/share/vm/runtime/synchronizer.hpp b/src/share/vm/runtime/synchronizer.hpp --- a/src/share/vm/runtime/synchronizer.hpp +++ b/src/share/vm/runtime/synchronizer.hpp @@ -136,6 +136,8 @@ ObjectMonitor** freeHeadp, ObjectMonitor** freeTailp); 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 static void sanity_checks(const bool verbose, @@ -156,6 +158,14 @@ static ObjectMonitor * volatile gOmInUseList; // count of entries in gOmInUseList 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 diff --git a/src/share/vm/runtime/thread.cpp b/src/share/vm/runtime/thread.cpp --- a/src/share/vm/runtime/thread.cpp +++ b/src/share/vm/runtime/thread.cpp @@ -792,6 +792,12 @@ // Do oop for ThreadShadow f->do_oop((oop*)&_pending_exception); 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*)) {