8180175: ObjectSynchronizer only needs to iterate in-use monitors
authorrkennke
Wed, 17 May 2017 23:36:19 +0200
changeset 46474 c872a196b75f
parent 46473 d43055e806c9
child 46475 75902cea18af
child 46476 8ead62daaa47
child 46482 10dde7fbed26
8180175: ObjectSynchronizer only needs to iterate in-use monitors Summary: When using -XX:+MonitorInUseLists, then only iterate in-use monitors. Reviewed-by: zgu, dholmes, rehn
hotspot/src/share/vm/runtime/synchronizer.cpp
hotspot/src/share/vm/runtime/synchronizer.hpp
hotspot/src/share/vm/runtime/thread.cpp
--- a/hotspot/src/share/vm/runtime/synchronizer.cpp	Wed May 17 23:18:19 2017 +0200
+++ b/hotspot/src/share/vm/runtime/synchronizer.cpp	Wed May 17 23:36:19 2017 +0200
@@ -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<ObjectMonitor> * block =
     (PaddedEnd<ObjectMonitor> *)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
--- a/hotspot/src/share/vm/runtime/synchronizer.hpp	Wed May 17 23:18:19 2017 +0200
+++ b/hotspot/src/share/vm/runtime/synchronizer.hpp	Wed May 17 23:36:19 2017 +0200
@@ -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
--- a/hotspot/src/share/vm/runtime/thread.cpp	Wed May 17 23:18:19 2017 +0200
+++ b/hotspot/src/share/vm/runtime/thread.cpp	Wed May 17 23:36:19 2017 +0200
@@ -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*)) {