--- old/src/hotspot/share/runtime/synchronizer.cpp 2020-02-25 17:44:02.000000000 -0500 +++ new/src/hotspot/share/runtime/synchronizer.cpp 2020-02-25 17:44:01.000000000 -0500 @@ -139,11 +139,10 @@ ObjectMonitor* _in_use_list; DEFINE_PAD_MINUS_SIZE(2, OM_CACHE_LINE_SIZE, sizeof(ObjectMonitor*)); - // Global ObjectMonitor wait list. If HandshakeAfterDeflateIdleMonitors - // is true, deflated ObjectMonitors wait on this list until after a - // handshake or a safepoint for platforms that don't support handshakes. - // After the handshake or safepoint, the deflated ObjectMonitors are - // prepended to free_list. + // Global ObjectMonitor wait list. Deflated ObjectMonitors wait on + // this list until after a handshake or a safepoint for platforms + // that don't support handshakes. After the handshake or safepoint, + // the deflated ObjectMonitors are prepended to free_list. ObjectMonitor* _wait_list; DEFINE_PAD_MINUS_SIZE(3, OM_CACHE_LINE_SIZE, sizeof(ObjectMonitor*)); @@ -320,7 +319,6 @@ // on the list. Also updates om_list_globals._wait_count. static void prepend_list_to_global_wait_list(ObjectMonitor* list, ObjectMonitor* tail, int count) { - assert(HandshakeAfterDeflateIdleMonitors, "sanity check"); prepend_list_to_common(list, tail, count, &om_list_globals._wait_list, &om_list_globals._wait_count); } @@ -535,8 +533,7 @@ m->try_set_owner_from(DEFLATER_MARKER, self) == 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. + // bailed. Acquired the monitor. assert(m->_recursions == 0, "invariant"); return true; } @@ -1035,10 +1032,7 @@ } monitor = omh.om_ptr(); temp = monitor->header(); - // Allow for a lagging install_displaced_markword_in_object() to - // have marked the ObjectMonitor's header/dmw field. - assert(temp.is_neutral() || (AsyncDeflateIdleMonitors && temp.is_marked()), - "invariant: header=" INTPTR_FORMAT, temp.value()); + assert(temp.is_neutral(), "invariant: header=" INTPTR_FORMAT, temp.value()); hash = temp.hash(); if (hash != 0) { // if it has a hash, just return it return hash; @@ -1070,36 +1064,20 @@ monitor = omh.om_ptr(); // Load ObjectMonitor's header/dmw field and see if it has a hash. mark = monitor->header(); - // Allow for a lagging install_displaced_markword_in_object() to - // have marked the ObjectMonitor's header/dmw field. - assert(mark.is_neutral() || (AsyncDeflateIdleMonitors && mark.is_marked()), - "invariant: header=" INTPTR_FORMAT, mark.value()); + assert(mark.is_neutral(), "invariant: header=" INTPTR_FORMAT, mark.value()); hash = mark.hash(); if (hash == 0) { // if it does not have a hash hash = get_next_hash(self, obj); // get a new hash temp = mark.copy_set_hash(hash); // merge the hash into header - if (AsyncDeflateIdleMonitors && temp.is_marked()) { - // A lagging install_displaced_markword_in_object() has marked - // the ObjectMonitor's header/dmw field. We clear it to avoid - // any confusion if we are able to set the hash. - temp.set_unmarked(); - } assert(temp.is_neutral(), "invariant: header=" INTPTR_FORMAT, temp.value()); uintptr_t v = Atomic::cmpxchg((volatile uintptr_t*)monitor->header_addr(), mark.value(), temp.value()); test = markWord(v); if (test != mark) { // The attempt to update the ObjectMonitor's header/dmw field // did not work. This can happen if another thread managed to - // merge in the hash just before our cmpxchg(). With async - // deflation, a lagging install_displaced_markword_in_object() - // could have just marked or just unmarked the header/dmw field. + // merge in the hash just before our cmpxchg(). // If we add any new usages of the header/dmw field, this code // will need to be updated. - if (AsyncDeflateIdleMonitors) { - // Since async deflation gives us two possible reasons for - // the cmwxchg() to fail, it is easier to simply retry. - continue; - } hash = test.hash(); assert(test.is_neutral(), "invariant: header=" INTPTR_FORMAT, test.value()); assert(hash != 0, "should only have lost the race to a thread that set a non-zero hash"); @@ -1265,7 +1243,7 @@ for (int i = _BLOCKSIZE - 1; i > 0; i--) { ObjectMonitor* mid = (ObjectMonitor *)(block + i); ObjectMonitorHandle omh; - if (!mid->is_free() && omh.set_om_ptr_if_safe(mid)) { + if (!mid->is_free() && omh.save_om_ptr_if_safe(mid)) { // The ObjectMonitor* is not free and it has been made safe. if (mid->object() == NULL) { // Only process with closure if the object is set. @@ -1286,10 +1264,8 @@ return false; } if (MonitorUsedDeflationThreshold > 0) { - int monitors_used = population - Atomic::load(&om_list_globals._free_count); - if (HandshakeAfterDeflateIdleMonitors) { - monitors_used -= Atomic::load(&om_list_globals._wait_count); - } + int monitors_used = population - Atomic::load(&om_list_globals._free_count) - + Atomic::load(&om_list_globals._wait_count); int monitor_usage = (monitors_used * 100LL) / population; return monitor_usage > MonitorUsedDeflationThreshold; } @@ -1322,10 +1298,8 @@ return true; } int monitors_used = Atomic::load(&om_list_globals._population) - - Atomic::load(&om_list_globals._free_count); - if (HandshakeAfterDeflateIdleMonitors) { - monitors_used -= Atomic::load(&om_list_globals._wait_count); - } + Atomic::load(&om_list_globals._free_count) - + Atomic::load(&om_list_globals._wait_count); if (is_MonitorBound_exceeded(monitors_used)) { // Not enough ObjectMonitors on the global free list. return true; @@ -1347,7 +1321,7 @@ // Too many monitors in use. return true; } - return needs_monitor_scavenge(); + return needs_monitor_scavenge(); } if (is_special_deflation_requested()) { // For AsyncDeflateIdleMonitors only do a safepoint deflation @@ -1498,11 +1472,10 @@ guarantee(take->object() == NULL, "invariant"); if (AsyncDeflateIdleMonitors) { // 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. + // Clear or restore them as appropriate. take->set_header(markWord::zero()); + // DEFLATER_MARKER is the only non-NULL value we should see here. + take->try_set_owner_from(DEFLATER_MARKER, NULL); if (take->ref_count() < 0) { // Add back max_jint to restore the ref_count field to its // proper value. @@ -2043,9 +2016,10 @@ // 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. + if (AsyncDeflateIdleMonitors) { + // DEFLATER_MARKER is the only non-NULL value we should see here. + m->try_set_owner_from(DEFLATER_MARKER, NULL); + } m->set_object(object); m->_Responsible = NULL; m->_SpinDuration = ObjectMonitor::Knob_SpinLimit; // consider: keep metastats by type/class @@ -2181,10 +2155,8 @@ // 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. DEFLATER_MARKER is the only non-NULL - // value we should see here. + // clear() expects the owner field to be NULL. + // DEFLATER_MARKER is the only non-NULL value we should see here. mid->try_set_owner_from(DEFLATER_MARKER, NULL); } mid->clear(); @@ -2311,8 +2283,7 @@ (int) mid->allocation_state()); // Move the deflated ObjectMonitor to the working free list - // defined by free_head_p and free_tail_p. No races on this list - // so no need for load_acquire() or store_release(). + // defined by free_head_p and free_tail_p. if (*free_head_p == NULL) { // First one on the list. *free_head_p = mid; @@ -2469,8 +2440,8 @@ } while (true) { - // The current mid's next field is marked at this point. If we have - // a cur_mid_in_use, then its next field is also marked at this point. + // The current mid is locked at this point. If we have a + // cur_mid_in_use, then it is also locked at this point. if (next != NULL) { // We lock next so that an om_flush() thread that is behind us @@ -2669,8 +2640,7 @@ // The ServiceThread's async deflation request has been processed. set_is_async_deflation_requested(false); - if (HandshakeAfterDeflateIdleMonitors && - Atomic::load(&om_list_globals._wait_count) > 0) { + if (Atomic::load(&om_list_globals._wait_count) > 0) { // There are deflated ObjectMonitors waiting for a handshake // (or a safepoint) for safety. @@ -2751,7 +2721,10 @@ &free_head_p, &free_tail_p, &saved_mid_in_use_p); } else { - local_deflated_count = deflate_monitor_list_using_JT(&target->om_in_use_list, &target->om_in_use_count, &free_head_p, &free_tail_p, &saved_mid_in_use_p); + local_deflated_count = + deflate_monitor_list_using_JT(&target->om_in_use_list, + &target->om_in_use_count, &free_head_p, + &free_tail_p, &saved_mid_in_use_p); } deflated_count += local_deflated_count; @@ -2771,11 +2744,7 @@ #endif assert(l_next_om == NULL, "must be NULL: _next_om=" INTPTR_FORMAT, p2i(l_next_om)); - if (HandshakeAfterDeflateIdleMonitors) { - prepend_list_to_global_wait_list(free_head_p, free_tail_p, local_deflated_count); - } else { - prepend_list_to_global_free_list(free_head_p, free_tail_p, local_deflated_count); - } + prepend_list_to_global_wait_list(free_head_p, free_tail_p, local_deflated_count); OM_PERFDATA_OP(Deflations, inc(local_deflated_count)); } @@ -3043,10 +3012,8 @@ // Check om_list_globals._free_list and om_list_globals._free_count: chk_global_free_list_and_count(ls, &error_cnt); - if (HandshakeAfterDeflateIdleMonitors) { - // Check om_list_globals._wait_list and om_list_globals._wait_count: - chk_global_wait_list_and_count(ls, &error_cnt); - } + // Check om_list_globals._wait_list and om_list_globals._wait_count: + chk_global_wait_list_and_count(ls, &error_cnt); ls->print_cr("Checking per-thread lists:"); @@ -3433,10 +3400,7 @@ out->print_cr("%18s %10d %10d %10d %10d", "", l_in_use_count, l_free_count, l_wait_count, Atomic::load(&om_list_globals._population)); - pop_count += l_in_use_count + l_free_count; - if (HandshakeAfterDeflateIdleMonitors) { - pop_count += l_wait_count; - } + pop_count += l_in_use_count + l_free_count + l_wait_count; out->print_cr("%18s %10s %10s %10s", "Per-Thread Lists:", "InUse", "Free", "Provision");