--- old/src/hotspot/share/runtime/synchronizer.cpp 2019-07-11 14:36:37.000000000 -0400 +++ new/src/hotspot/share/runtime/synchronizer.cpp 2019-07-11 14:36:37.000000000 -0400 @@ -255,6 +255,16 @@ assert(m->_recursions == 0, "invariant"); return true; } + + if (AsyncDeflateIdleMonitors && + Atomic::cmpxchg(Self, &m->_owner, DEFLATER_MARKER) == DEFLATER_MARKER) { + // The deflation protocol finished the first part (setting owner), + // but it failed the second part (making ref_count negative) and + // bailed. Or the ObjectMonitor was async deflated and reused. + // Acquired the monitor. + assert(m->_recursions == 0, "invariant"); + return true; + } } break; } @@ -1021,6 +1031,13 @@ return false; } +// Returns true if MonitorBound is set (> 0) and if the specified +// cnt is > MonitorBound. Otherwise returns false. +static bool is_MonitorBound_exceeded(const int cnt) { + const int mx = MonitorBound; + return mx > 0 && cnt > mx; +} + bool ObjectSynchronizer::is_async_deflation_needed() { if (!AsyncDeflateIdleMonitors) { return false; @@ -1039,6 +1056,10 @@ _last_async_deflation_time_ns = os::javaTimeNanos(); return true; } + if (is_MonitorBound_exceeded(gMonitorPopulation - gMonitorFreeCount)) { + // Not enough ObjectMonitors on the global free list. + return true; + } return false; } @@ -1111,6 +1132,9 @@ // Constraining monitor pool growth via MonitorBound ... // +// If MonitorBound is not set (<= 0), MonitorBound checks are disabled. +// +// When safepoint deflation is being used (!AsyncDeflateIdleMonitors): // The monitor pool is grow-only. We scavenge at STW safepoint-time, but the // the rate of scavenging is driven primarily by GC. As such, we can find // an inordinate number of monitors in circulation. @@ -1124,8 +1148,26 @@ // See also: GuaranteedSafepointInterval // // The current implementation uses asynchronous VM operations. +// +// When safepoint deflation is being used and MonitorBound is set, the +// boundry applies to (gMonitorPopulation - gMonitorFreeCount), i.e., +// if there are not enough ObjectMonitors on the global free list, then +// a safepoint deflation is induced. Picking a good MonitorBound value +// is non-trivial. +// +// When async deflation is being used: +// The monitor pool is still grow-only. Async deflation is requested +// by a safepoint's cleanup phase or by the ServiceThread at periodic +// intervals when is_async_deflation_needed() returns true. In +// addition to other policies that are checked, if there are not +// enough ObjectMonitors on the global free list, then +// is_async_deflation_needed() will return true. The ServiceThread +// calls deflate_global_idle_monitors_using_JT() and also sets the +// per-thread omShouldDeflateIdleMonitors flag as needed. static void InduceScavenge(Thread * Self, const char * Whence) { + assert(!AsyncDeflateIdleMonitors, "is not used by async deflation"); + // Induce STW safepoint to trim monitors // Ultimately, this results in a call to deflate_idle_monitors() in the near future. // More precisely, trigger an asynchronous STW safepoint as the number @@ -1157,9 +1199,10 @@ // Deflate any per-thread idle monitors for this JavaThread if // this is not an internal inflation; internal inflations can // occur in places where it is not safe to pause for a safepoint. - // Clean up your own mess. (Gibbs Rule 45) Otherwise, skip this + // Clean up your own mess (Gibbs Rule 45). Otherwise, skip this // deflation. deflate_global_idle_monitors_using_JT() is called - // by the ServiceThread. + // by the ServiceThread. Per-thread async deflation is triggered + // by the ServiceThread via omShouldDeflateIdleMonitors. debug_only(jt->check_for_valid_safepoint_state(false);) ObjectSynchronizer::deflate_per_thread_idle_monitors_using_JT(); } @@ -1203,10 +1246,12 @@ gFreeList = take->FreeNext; guarantee(take->object() == NULL, "invariant"); if (AsyncDeflateIdleMonitors) { - // Clear any values we allowed to linger during async deflation. + // We allowed 3 field values to linger during async deflation. + // We clear header and restore ref_count here, but we leave + // owner == DEFLATER_MARKER so the simple C2 ObjectMonitor + // enter optimization can no longer race with async deflation + // and reuse. take->_header = NULL; - take->set_owner(NULL); - if (take->ref_count() < 0) { // Add back max_jint to restore the ref_count field to its // proper value. @@ -1224,8 +1269,9 @@ Self->omFreeProvision += 1 + (Self->omFreeProvision/2); if (Self->omFreeProvision > MAXPRIVATE) Self->omFreeProvision = MAXPRIVATE; - const int mx = MonitorBound; - if (mx > 0 && (gMonitorPopulation-gMonitorFreeCount) > mx) { + if (!AsyncDeflateIdleMonitors && + is_MonitorBound_exceeded(gMonitorPopulation - gMonitorFreeCount)) { + // Not enough ObjectMonitors on the global free list. // We can't safely induce a STW safepoint from omAlloc() as our thread // state may not be appropriate for such activities and callers may hold // naked oops, so instead we defer the action. @@ -1673,6 +1719,9 @@ // prepare m for installation - set monitor to initial state m->Recycle(); m->set_header(mark); + // If we leave _owner == DEFLATER_MARKER here, then the simple C2 + // ObjectMonitor enter optimization can no longer race with async + // deflation and reuse. m->set_object(object); m->_Responsible = NULL; m->_SpinDuration = ObjectMonitor::Knob_SpinLimit; // consider: keep metastats by type/class @@ -1715,6 +1764,7 @@ // We maintain a list of in-use monitors for each thread. // +// For safepoint based deflation: // deflate_thread_local_monitors() scans a single thread's in-use list, while // deflate_idle_monitors() scans only a global list of in-use monitors which // is populated only as a thread dies (see omFlush()). @@ -1733,6 +1783,11 @@ // typically drives the scavenge rate. Large heaps can mean infrequent GC, // which in turn can mean large(r) numbers of ObjectMonitors in circulation. // This is an unfortunate aspect of this design. +// +// For async deflation: +// If a special deflation request is made, then the safepoint based +// deflation mechanism is used. Otherwise, an async deflation request +// is registered with the ServiceThread and it is notified. void ObjectSynchronizer::do_safepoint_work(DeflateMonitorCounters* _counters) { assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); @@ -1771,7 +1826,9 @@ const markOop dmw = mid->header(); guarantee(dmw->is_neutral(), "invariant: header=" INTPTR_FORMAT, p2i(dmw)); - if (mid->is_busy()) { + if (mid->is_busy() || mid->ref_count() != 0) { + // Easy checks are first - the ObjectMonitor is busy or ObjectMonitor* + // is in use so no deflation. deflated = false; } else { // Deflate the monitor if it is no longer being used @@ -1787,6 +1844,12 @@ // Restore the header back to obj obj->release_set_mark(dmw); + if (AsyncDeflateIdleMonitors) { + // clear() expects the owner field to be NULL and we won't race + // with the simple C2 ObjectMonitor enter optimization since + // we're at a safepoint. + mid->set_owner(NULL); + } mid->clear(); assert(mid->object() == NULL, "invariant: object=" INTPTR_FORMAT, @@ -1857,7 +1920,7 @@ // ObjectMonitor* using threads to retry. This is the second // part of the async deflation dance. - if (mid->_owner == DEFLATER_MARKER) { + if (mid->owner_is_DEFLATER_MARKER()) { // If owner is still DEFLATER_MARKER, then we have successfully // signaled any contending threads to retry. If it is not, then we // have lost the race to an entering thread and the ObjectMonitor @@ -2520,8 +2583,7 @@ void ObjectSynchronizer::chk_free_entry(JavaThread * jt, ObjectMonitor * n, outputStream * out, int *error_cnt_p) { stringStream ss; - if ((!AsyncDeflateIdleMonitors && n->is_busy()) || - (AsyncDeflateIdleMonitors && n->is_busy_async())) { + if (n->is_busy()) { if (jt != NULL) { out->print_cr("ERROR: jt=" INTPTR_FORMAT ", monitor=" INTPTR_FORMAT ": free per-thread monitor must not be busy: %s", p2i(jt),