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