< prev index next >

src/share/vm/runtime/synchronizer.cpp

Print this page
rev 13349 : imported patch deflate.patch

@@ -963,10 +963,14 @@
 }
 
 
 void ObjectSynchronizer::oops_do(OopClosure* f) {
   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
+  if (MonitorInUseLists) {
+    global_used_oops_do(f);
+    return;
+  }
   PaddedEnd<ObjectMonitor> * block =
     (PaddedEnd<ObjectMonitor> *)OrderAccess::load_ptr_acquire(&gBlockList);
   for (; block != NULL; block = (PaddedEnd<ObjectMonitor> *)next(block)) {
     assert(block->object() == CHAINMARKER, "must be a block header");
     for (int i = 1; i < _BLOCKSIZE; i++) {

@@ -1615,11 +1619,12 @@
 // Walk a given monitor list, and deflate idle monitors
 // The given list could be a per-thread list or a global list
 // Caller acquires gListLock
 int ObjectSynchronizer::deflate_monitor_list(ObjectMonitor** listHeadp,
                                              ObjectMonitor** freeHeadp,
-                                             ObjectMonitor** freeTailp) {
+                                             ObjectMonitor** freeTailp,
+                                             OopClosure* cl) {
   ObjectMonitor* mid;
   ObjectMonitor* next;
   ObjectMonitor* cur_mid_in_use = NULL;
   int deflated_count = 0;
 

@@ -1636,10 +1641,13 @@
       next = mid->FreeNext;
       mid->FreeNext = NULL;  // This mid is current tail in the freeHeadp list
       mid = next;
       deflated_count++;
     } else {
+      if (obj != NULL && cl != NULL) {
+        cl->do_oop((oop*) mid->object_addr());
+      }
       cur_mid_in_use = mid;
       mid = mid->FreeNext;
     }
   }
   return deflated_count;

@@ -1654,29 +1662,23 @@
 
   ObjectMonitor * freeHeadp = NULL;  // Local SLL of scavenged monitors
   ObjectMonitor * freeTailp = NULL;
 
   TEVENT(deflate_idle_monitors);
+  if (MonitorInUseLists) {
+    if (! Universe::heap()->supports_per_thread_monitor_deflation() ||
+        ForceMonitorScavenge == 1) {
+      Universe::heap()->deflate_idle_monitors_all_threads();
+    }
+  }
+
   // Prevent omFlush from changing mids in Thread dtor's during deflation
   // And in case the vm thread is acquiring a lock during a safepoint
   // See e.g. 6320749
   Thread::muxAcquire(&gListLock, "scavenge - return");
 
   if (MonitorInUseLists) {
-    if (! DeflateIdleMonitorsPerThread) {
-      for (JavaThread* cur = Threads::first(); cur != NULL; cur = cur->next()) {
-        nInCirculation+= cur->omInUseCount;
-        int deflated_count = deflate_monitor_list(cur->omInUseList_addr(), &freeHeadp, &freeTailp);
-        cur->omInUseCount-= deflated_count;
-        if (ObjectMonitor::Knob_VerifyInUse) {
-          verifyInUse(cur);
-        }
-        nScavenged += deflated_count;
-        nInuse += cur->omInUseCount;
-      }
-    }
-
     // For moribund threads, scan gOmInUseList
     if (gOmInUseList) {
       nInCirculation += gOmInUseCount;
       int deflated_count = deflate_monitor_list((ObjectMonitor **)&gOmInUseList, &freeHeadp, &freeTailp);
       gOmInUseCount-= deflated_count;

@@ -1746,19 +1748,20 @@
   // Audit/inventory the objectMonitors -- make sure they're all accounted for.
   GVars.stwRandom = os::random();
   GVars.stwCycle++;
 }
 
-void ObjectSynchronizer::deflate_idle_monitors_per_thread(Thread* thread) {
+void ObjectSynchronizer::deflate_idle_monitors_and_oops_do(Thread* thread, OopClosure* cl) {
   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
   if (! MonitorInUseLists) return;
-  if (! DeflateIdleMonitorsPerThread) return;
+  if (ForceMonitorScavenge == 1) return;
+  assert(Universe::heap()->supports_per_thread_monitor_deflation(), "only call this when supported by GC");
 
   ObjectMonitor * freeHeadp = NULL;  // Local SLL of scavenged monitors
   ObjectMonitor * freeTailp = NULL;
 
-  int deflated_count = deflate_monitor_list(thread->omInUseList_addr(), &freeHeadp, &freeTailp);
+  int deflated_count = deflate_monitor_list(thread->omInUseList_addr(), &freeHeadp, &freeTailp, cl);
   thread->omInUseCount-= deflated_count;
   if (ObjectMonitor::Knob_VerifyInUse) {
     verifyInUse(thread);
   }
 

@@ -1774,10 +1777,49 @@
     gFreeList = freeHeadp;
     Thread::muxRelease(&gListLock);
   }
 }
 
+void ObjectSynchronizer::deflate_idle_monitors_all_threads() {
+  assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
+  assert(MonitorInUseLists, "only call this with MonitorInUseLists");
+
+  int nInuse = 0;              // currently associated with objects
+  int nInCirculation = 0;      // extant
+  int nScavenged = 0;          // reclaimed
+
+  ObjectMonitor * freeHeadp = NULL;  // Local SLL of scavenged monitors
+  ObjectMonitor * freeTailp = NULL;
+
+  Thread::muxAcquire(&gListLock, "scavenge - return");
+  for (JavaThread* cur = Threads::first(); cur != NULL; cur = cur->next()) {
+    nInCirculation+= cur->omInUseCount;
+    int deflated_count = deflate_monitor_list(cur->omInUseList_addr(), &freeHeadp, &freeTailp);
+    cur->omInUseCount-= deflated_count;
+    if (ObjectMonitor::Knob_VerifyInUse) {
+      verifyInUse(cur);
+    }
+    nScavenged += deflated_count;
+    nInuse += cur->omInUseCount;
+  }
+
+  // Move the scavenged monitors back to the global free list.
+  if (freeHeadp != NULL) {
+    guarantee(freeTailp != NULL && nScavenged > 0, "invariant");
+    assert(freeTailp->FreeNext == NULL, "invariant");
+
+    gMonitorFreeCount += nScavenged;
+    // constant-time list splice - prepend scavenged segment to gFreeList
+    freeTailp->FreeNext = gFreeList;
+    gFreeList = freeHeadp;
+  }
+
+  gMonitorFreeCount += nScavenged;
+
+  Thread::muxRelease(&gListLock);
+}
+
 // Monitor cleanup on JavaThread::exit
 
 // Iterate through monitor cache and attempt to release thread's monitors
 // Gives up on a particular monitor if an exception occurs, but continues
 // the overall iteration, swallowing the exception.
< prev index next >