< prev index next >
src/share/vm/runtime/synchronizer.cpp
Print this page
rev 13114 : 8180932: Parallelize safepoint cleanup
Summary: Provide infrastructure to do safepoint cleanup tasks using parallel worker threads
Reviewed-by: dholmes, rehn
*** 1691,1705 ****
}
}
return deflated_count;
}
! void ObjectSynchronizer::deflate_idle_monitors() {
assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
- int nInuse = 0; // currently associated with objects
- int nInCirculation = 0; // extant
- int nScavenged = 0; // reclaimed
bool deflated = false;
ObjectMonitor * freeHeadp = NULL; // Local SLL of scavenged monitors
ObjectMonitor * freeTailp = NULL;
--- 1691,1708 ----
}
}
return deflated_count;
}
! void ObjectSynchronizer::prepare_deflate_idle_monitors(DeflateMonitorCounters* counters) {
! counters->nInuse = 0; // currently associated with objects
! counters->nInCirculation = 0; // extant
! counters->nScavenged = 0; // reclaimed
! }
!
! void ObjectSynchronizer::deflate_idle_monitors(DeflateMonitorCounters* counters) {
assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
bool deflated = false;
ObjectMonitor * freeHeadp = NULL; // Local SLL of scavenged monitors
ObjectMonitor * freeTailp = NULL;
*** 1708,1745 ****
// And in case the vm thread is acquiring a lock during a safepoint
// See e.g. 6320749
Thread::muxAcquire(&gListLock, "scavenge - return");
if (MonitorInUseLists) {
! int inUse = 0;
! 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;
! nScavenged += deflated_count;
! nInuse += gOmInUseCount;
}
} else {
PaddedEnd<ObjectMonitor> * block =
(PaddedEnd<ObjectMonitor> *)OrderAccess::load_ptr_acquire(&gBlockList);
for (; block != NULL; block = (PaddedEnd<ObjectMonitor> *)next(block)) {
// Iterate over all extant monitors - Scavenge all idle monitors.
assert(block->object() == CHAINMARKER, "must be a block header");
! nInCirculation += _BLOCKSIZE;
for (int i = 1; i < _BLOCKSIZE; i++) {
ObjectMonitor* mid = (ObjectMonitor*)&block[i];
oop obj = (oop)mid->object();
if (obj == NULL) {
--- 1711,1739 ----
// And in case the vm thread is acquiring a lock during a safepoint
// See e.g. 6320749
Thread::muxAcquire(&gListLock, "scavenge - return");
if (MonitorInUseLists) {
! // Note: the thread-local monitors lists get deflated in
! // a separate pass. See deflate_thread_local_monitors().
// For moribund threads, scan gOmInUseList
if (gOmInUseList) {
! counters->nInCirculation += gOmInUseCount;
int deflated_count = deflate_monitor_list((ObjectMonitor **)&gOmInUseList, &freeHeadp, &freeTailp);
gOmInUseCount-= deflated_count;
! counters->nScavenged += deflated_count;
! counters->nInuse += gOmInUseCount;
}
} else {
PaddedEnd<ObjectMonitor> * block =
(PaddedEnd<ObjectMonitor> *)OrderAccess::load_ptr_acquire(&gBlockList);
for (; block != NULL; block = (PaddedEnd<ObjectMonitor> *)next(block)) {
// Iterate over all extant monitors - Scavenge all idle monitors.
assert(block->object() == CHAINMARKER, "must be a block header");
! counters->nInCirculation += _BLOCKSIZE;
for (int i = 1; i < _BLOCKSIZE; i++) {
ObjectMonitor* mid = (ObjectMonitor*)&block[i];
oop obj = (oop)mid->object();
if (obj == NULL) {
*** 1752,1800 ****
}
deflated = deflate_monitor(mid, obj, &freeHeadp, &freeTailp);
if (deflated) {
mid->FreeNext = NULL;
! nScavenged++;
} else {
! nInuse++;
}
}
}
}
! gMonitorFreeCount += nScavenged;
// Consider: audit gFreeList to ensure that gMonitorFreeCount and list agree.
if (ObjectMonitor::Knob_Verbose) {
tty->print_cr("INFO: Deflate: InCirc=%d InUse=%d Scavenged=%d "
"ForceMonitorScavenge=%d : pop=%d free=%d",
! nInCirculation, nInuse, nScavenged, ForceMonitorScavenge,
gMonitorPopulation, gMonitorFreeCount);
tty->flush();
}
ForceMonitorScavenge = 0; // Reset
// Move the scavenged monitors back to the global free list.
if (freeHeadp != NULL) {
! guarantee(freeTailp != NULL && nScavenged > 0, "invariant");
assert(freeTailp->FreeNext == NULL, "invariant");
// constant-time list splice - prepend scavenged segment to gFreeList
freeTailp->FreeNext = gFreeList;
gFreeList = freeHeadp;
}
Thread::muxRelease(&gListLock);
-
- OM_PERFDATA_OP(Deflations, inc(nScavenged));
- OM_PERFDATA_OP(MonExtant, set_value(nInCirculation));
-
- // TODO: Add objectMonitor leak detection.
- // Audit/inventory the objectMonitors -- make sure they're all accounted for.
- GVars.stwRandom = os::random();
- GVars.stwCycle++;
}
// Monitor cleanup on JavaThread::exit
// Iterate through monitor cache and attempt to release thread's monitors
--- 1746,1830 ----
}
deflated = deflate_monitor(mid, obj, &freeHeadp, &freeTailp);
if (deflated) {
mid->FreeNext = NULL;
! counters->nScavenged++;
} else {
! counters->nInuse++;
}
}
}
}
! // Move the scavenged monitors back to the global free list.
! if (freeHeadp != NULL) {
! guarantee(freeTailp != NULL && counters->nScavenged > 0, "invariant");
! assert(freeTailp->FreeNext == NULL, "invariant");
! // constant-time list splice - prepend scavenged segment to gFreeList
! freeTailp->FreeNext = gFreeList;
! gFreeList = freeHeadp;
! }
! Thread::muxRelease(&gListLock);
!
! }
!
! void ObjectSynchronizer::finish_deflate_idle_monitors(DeflateMonitorCounters* counters) {
! gMonitorFreeCount += counters->nScavenged;
// Consider: audit gFreeList to ensure that gMonitorFreeCount and list agree.
if (ObjectMonitor::Knob_Verbose) {
tty->print_cr("INFO: Deflate: InCirc=%d InUse=%d Scavenged=%d "
"ForceMonitorScavenge=%d : pop=%d free=%d",
! counters->nInCirculation, counters->nInuse, counters->nScavenged, ForceMonitorScavenge,
gMonitorPopulation, gMonitorFreeCount);
tty->flush();
}
ForceMonitorScavenge = 0; // Reset
+ OM_PERFDATA_OP(Deflations, inc(counters->nScavenged));
+ OM_PERFDATA_OP(MonExtant, set_value(counters->nInCirculation));
+
+ // TODO: Add objectMonitor leak detection.
+ // Audit/inventory the objectMonitors -- make sure they're all accounted for.
+ GVars.stwRandom = os::random();
+ GVars.stwCycle++;
+ }
+
+ void ObjectSynchronizer::deflate_thread_local_monitors(Thread* thread, DeflateMonitorCounters* counters) {
+ assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
+ if (! MonitorInUseLists) return;
+
+ ObjectMonitor * freeHeadp = NULL; // Local SLL of scavenged monitors
+ ObjectMonitor * freeTailp = NULL;
+
+ int deflated_count = deflate_monitor_list(thread->omInUseList_addr(), &freeHeadp, &freeTailp);
+
+ Thread::muxAcquire(&gListLock, "scavenge - return");
+
+ // Adjust counters
+ counters->nInCirculation += thread->omInUseCount;
+ thread->omInUseCount-= deflated_count;
+ if (ObjectMonitor::Knob_VerifyInUse) {
+ verifyInUse(thread);
+ }
+ counters->nScavenged += deflated_count;
+ counters->nInuse += thread->omInUseCount;
+ gMonitorFreeCount += deflated_count;
+
// Move the scavenged monitors back to the global free list.
if (freeHeadp != NULL) {
! guarantee(freeTailp != NULL && deflated_count > 0, "invariant");
assert(freeTailp->FreeNext == NULL, "invariant");
+
// constant-time list splice - prepend scavenged segment to gFreeList
freeTailp->FreeNext = gFreeList;
gFreeList = freeHeadp;
}
Thread::muxRelease(&gListLock);
}
// Monitor cleanup on JavaThread::exit
// Iterate through monitor cache and attempt to release thread's monitors
< prev index next >