--- old/src/hotspot/cpu/aarch64/globals_aarch64.hpp 2020-02-25 17:43:42.000000000 -0500 +++ new/src/hotspot/cpu/aarch64/globals_aarch64.hpp 2020-02-25 17:43:42.000000000 -0500 @@ -71,10 +71,6 @@ // Clear short arrays bigger than one word in an arch-specific way define_pd_global(intx, InitArrayShortSize, BytesPerLong); -// ObjectMonitor ref_count not implemented in C2 fast_lock() or -// fast_unlock() so use a handshake for safety. -define_pd_global(bool, HandshakeAfterDeflateIdleMonitors, true); - #if defined(COMPILER1) || defined(COMPILER2) define_pd_global(intx, InlineSmallCode, 1000); #endif --- old/src/hotspot/cpu/arm/globals_arm.hpp 2020-02-25 17:43:44.000000000 -0500 +++ new/src/hotspot/cpu/arm/globals_arm.hpp 2020-02-25 17:43:43.000000000 -0500 @@ -70,11 +70,6 @@ define_pd_global(intx, InitArrayShortSize, 8*BytesPerLong); -// ObjectMonitor ref_count not implemented in C2 fast_lock() or -// fast_unlock() so use a handshake for safety. -// Will use a safepoint instead of a handshake on this platform. -define_pd_global(bool, HandshakeAfterDeflateIdleMonitors, true); - #define ARCH_FLAGS(develop, \ product, \ diagnostic, \ --- old/src/hotspot/cpu/ppc/globals_ppc.hpp 2020-02-25 17:43:45.000000000 -0500 +++ new/src/hotspot/cpu/ppc/globals_ppc.hpp 2020-02-25 17:43:44.000000000 -0500 @@ -74,10 +74,6 @@ // 2x unrolled loop is shorter with more than 9 HeapWords. define_pd_global(intx, InitArrayShortSize, 9*BytesPerLong); -// ObjectMonitor ref_count not implemented in C2 fast_lock() or -// fast_unlock() so use a handshake for safety. -define_pd_global(bool, HandshakeAfterDeflateIdleMonitors, true); - // Platform dependent flag handling: flags only defined on this platform. #define ARCH_FLAGS(develop, \ product, \ --- old/src/hotspot/cpu/s390/globals_s390.hpp 2020-02-25 17:43:46.000000000 -0500 +++ new/src/hotspot/cpu/s390/globals_s390.hpp 2020-02-25 17:43:45.000000000 -0500 @@ -76,10 +76,6 @@ // 8146801 (Short Array Allocation): No performance work done here yet. define_pd_global(intx, InitArrayShortSize, 1*BytesPerLong); -// ObjectMonitor ref_count not implemented in C2 fast_lock() or -// fast_unlock() so use a handshake for safety. -define_pd_global(bool, HandshakeAfterDeflateIdleMonitors, true); - #define ARCH_FLAGS(develop, \ product, \ diagnostic, \ --- old/src/hotspot/cpu/sparc/globals_sparc.hpp 2020-02-25 17:43:47.000000000 -0500 +++ new/src/hotspot/cpu/sparc/globals_sparc.hpp 2020-02-25 17:43:46.000000000 -0500 @@ -80,10 +80,6 @@ define_pd_global(intx, InitArrayShortSize, 8*BytesPerLong); -// ObjectMonitor ref_count not implemented in C2 fast_lock() or -// fast_unlock() so use a handshake for safety. -define_pd_global(bool, HandshakeAfterDeflateIdleMonitors, true); - #define ARCH_FLAGS(develop, \ product, \ diagnostic, \ --- old/src/hotspot/cpu/x86/globals_x86.hpp 2020-02-25 17:43:48.000000000 -0500 +++ new/src/hotspot/cpu/x86/globals_x86.hpp 2020-02-25 17:43:47.000000000 -0500 @@ -89,21 +89,6 @@ define_pd_global(intx, InitArrayShortSize, 8*BytesPerLong); -#if defined(_LP64) || defined(_WINDOWS) -// ObjectMonitor ref_count is implemented in LP64 C2 fast_lock() -// and fast_unlock() so we don't need the handshake by default. -#ifdef _LP64 -define_pd_global(bool, HandshakeAfterDeflateIdleMonitors, false); -#else -define_pd_global(bool, HandshakeAfterDeflateIdleMonitors, true); -#endif -#else -// ObjectMonitor ref_count not implemented in C2 fast_lock() or -// fast_unlock() so use a handshake for safety. -// Will use a safepoint instead of a handshake on this platform. -define_pd_global(bool, HandshakeAfterDeflateIdleMonitors, true); -#endif - #define ARCH_FLAGS(develop, \ product, \ diagnostic, \ --- old/src/hotspot/cpu/x86/macroAssembler_x86.cpp 2020-02-25 17:43:49.000000000 -0500 +++ new/src/hotspot/cpu/x86/macroAssembler_x86.cpp 2020-02-25 17:43:48.000000000 -0500 @@ -1285,58 +1285,6 @@ #ifdef COMPILER2 -// Increment the ObjectMonitor's ref_count for safety or force a branch -// to 'done' with ICC.ZF=0 to indicate failure/take the slow path. -void MacroAssembler::inc_om_ref_count(Register obj_reg, Register om_reg, Register tmp_reg, Label& done) { - atomic_incl(Address(om_reg, OM_OFFSET_NO_MONITOR_VALUE_TAG(ref_count))); - - Label LGoSlowPath; - if (AsyncDeflateIdleMonitors) { - // Race here if monitor is not owned! The above ref_count bump - // will cause subsequent async deflation to skip it. However, - // previous or concurrent async deflation is a race. - - // First check: if the owner field == DEFLATER_MARKER: - movptr(tmp_reg, Address(om_reg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner))); - // DEFLATER_MARKER == reinterpret_cast(-1) so the compiler - // doesn't like to use the define here: - cmpptr(tmp_reg, -1); - // If marked for async deflation, then take the slow path. This is a - // simpler check than what ObjectMonitorHandle::save_om_ptr() does - // so ObjectMonitor::install_displaced_markword_in_object() doesn't - // have to be implemented in macro assembler. - jccb(Assembler::equal, LGoSlowPath); - - // Second check: if ref_count field <= 0: - movptr(tmp_reg, Address(om_reg, OM_OFFSET_NO_MONITOR_VALUE_TAG(ref_count))); - cmpptr(tmp_reg, 0); - // If async deflation is in the process of bailing out, but has not - // yet restored the ref_count field, then we take the slow path. We - // want a stable ref_count value for the fast path. - jccb(Assembler::lessEqual, LGoSlowPath); - - // Final check: if object field == obj_reg: - cmpptr(obj_reg, Address(om_reg, OM_OFFSET_NO_MONITOR_VALUE_TAG(object))); - // If the ObjectMonitor has been deflated and recycled, then take - // the slow path. - jccb(Assembler::notEqual, LGoSlowPath); - } - - Label LRetToCaller; - // We leave the ref_count incremented to protect the caller's code - // paths against async deflation. - jmpb(LRetToCaller); - - bind(LGoSlowPath); - lock(); - decrementl(Address(om_reg, OM_OFFSET_NO_MONITOR_VALUE_TAG(ref_count))); - // Jump to 'done' with ICC.ZF=0 to indicate failure/take the slow path. - orl(tmp_reg, 1); - jmp(done); - - bind(LRetToCaller); -} - #if INCLUDE_RTM_OPT // Update rtm_counters based on abort status @@ -1570,21 +1518,11 @@ assert(UseRTMLocking, "why call this otherwise?"); assert(tmpReg == rax, ""); assert(scrReg == rdx, ""); - Label L_rtm_retry, L_decrement_retry, L_on_abort, L_local_done; + Label L_rtm_retry, L_decrement_retry, L_on_abort; int owner_offset = OM_OFFSET_NO_MONITOR_VALUE_TAG(owner); // Without cast to int32_t this style of movptr will destroy r10 which is typically obj. movptr(Address(boxReg, 0), (int32_t)intptr_t(markWord::unused_mark().value())); - - if (!HandshakeAfterDeflateIdleMonitors) { - // Increment the ObjectMonitor's ref_count for safety or force the - // enter slow path via DONE_LABEL. - // In rtm_inflated_locking(), initially tmpReg contains the object's - // mark word which, in this case, is the (ObjectMonitor* | monitor_value). - // Also this code uses scrReg as its temporary register. - inc_om_ref_count(objReg, tmpReg /* om_reg */, scrReg /* tmp_reg */, DONE_LABEL); - } - movptr(boxReg, tmpReg); // Save ObjectMonitor address if (RTMRetryCount > 0) { @@ -1606,7 +1544,7 @@ movptr(tmpReg, Address(objReg, oopDesc::mark_offset_in_bytes())); movptr(tmpReg, Address(tmpReg, owner_offset)); testptr(tmpReg, tmpReg); - jcc(Assembler::zero, L_local_done); + jcc(Assembler::zero, DONE_LABEL); if (UseRTMXendForLockBusy) { xend(); jmp(L_decrement_retry); @@ -1641,7 +1579,7 @@ if (RTMRetryCount > 0) { // success done else retry - jccb(Assembler::equal, L_local_done); + jccb(Assembler::equal, DONE_LABEL) ; bind(L_decrement_retry); // Spin and retry if lock is busy. rtm_retry_lock_on_busy(retry_on_busy_count_Reg, boxReg, tmpReg, scrReg, L_rtm_retry); @@ -1649,19 +1587,6 @@ else { bind(L_decrement_retry); } - - // rtm_inflated_locking() exit paths come here except for a failed - // inc_om_ref_count() which goes directly to DONE_LABEL. - bind(L_local_done); - if (!HandshakeAfterDeflateIdleMonitors) { - pushf(); // Preserve flags. - // Decrement the ObjectMonitor's ref_count. - lock(); - decrementl(Address(boxReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(ref_count))); - popf(); // Restore flags so we have the proper ICC.ZF value. - } - - jmp(DONE_LABEL) ; } #endif // INCLUDE_RTM_OPT @@ -1887,33 +1812,14 @@ #else // _LP64 // It's inflated and we use scrReg for ObjectMonitor* in this section. movq(scrReg, tmpReg); - - // Unconditionally set box->_displaced_header = markWord::unused_mark(). - // Without cast to int32_t this style of movptr will destroy r10 which is typically obj. - movptr(Address(boxReg, 0), (int32_t)intptr_t(markWord::unused_mark().value())); - - if (!HandshakeAfterDeflateIdleMonitors) { - // Increment the ObjectMonitor's ref_count for safety or force the - // enter slow path via DONE_LABEL. - // In fast_lock(), scrReg contains the object's mark word which, - // in this case, is the (ObjectMonitor* | monitor_value). Also this - // code uses tmpReg as its temporary register. - inc_om_ref_count(objReg, scrReg /* om_reg */, tmpReg /* tmp_reg */, DONE_LABEL); - } - xorq(tmpReg, tmpReg); lock(); cmpxchgptr(r15_thread, Address(scrReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner))); + // Unconditionally set box->_displaced_header = markWord::unused_mark(). + // Without cast to int32_t this style of movptr will destroy r10 which is typically obj. + movptr(Address(boxReg, 0), (int32_t)intptr_t(markWord::unused_mark().value())); // Intentional fall-through into DONE_LABEL ... // Propagate ICC.ZF from CAS above into DONE_LABEL. - - if (!HandshakeAfterDeflateIdleMonitors) { - pushf(); // Preserve flags. - // Decrement the ObjectMonitor's ref_count. - lock(); - decrementl(Address(scrReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(ref_count))); - popf(); // Restore flags so we have the proper ICC.ZF value. - } #endif // _LP64 #if INCLUDE_RTM_OPT } // use_rtm() @@ -1993,7 +1899,7 @@ jcc (Assembler::zero, DONE_LABEL); // 0 indicates recursive stack-lock movptr(tmpReg, Address(objReg, oopDesc::mark_offset_in_bytes())); // Examine the object's markword testptr(tmpReg, markWord::monitor_value); // Inflated? - jcc (Assembler::zero, Stacked); + jccb (Assembler::zero, Stacked); // It's inflated. #if INCLUDE_RTM_OPT @@ -2004,7 +1910,7 @@ testptr(boxReg, boxReg); jccb(Assembler::notZero, L_regular_inflated_unlock); xend(); - jmp(DONE_LABEL); + jmpb(DONE_LABEL); bind(L_regular_inflated_unlock); } #endif @@ -2066,28 +1972,18 @@ bind (CheckSucc); #else // _LP64 // It's inflated - - if (!HandshakeAfterDeflateIdleMonitors) { - // Increment the ObjectMonitor's ref_count for safety or force the - // exit slow path via DONE_LABEL. - // In fast_unlock(), tmpReg contains the object's mark word which, - // in this case, is the (ObjectMonitor* | monitor_value). Also this - // code uses boxReg as its temporary register. - inc_om_ref_count(objReg, tmpReg /* om_reg */, boxReg /* tmp_reg */, DONE_LABEL); - } - - // Try to avoid passing control into the slow path ... - Label LSuccess, LGoSlowPath; xorptr(boxReg, boxReg); orptr(boxReg, Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(recursions))); - jccb(Assembler::notZero, LGoSlowPath); + jccb (Assembler::notZero, DONE_LABEL); movptr(boxReg, Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(cxq))); orptr(boxReg, Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(EntryList))); jccb (Assembler::notZero, CheckSucc); // Without cast to int32_t this style of movptr will destroy r10 which is typically obj. movptr(Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)), (int32_t)NULL_WORD); - jmpb(LSuccess); + jmpb (DONE_LABEL); + // Try to avoid passing control into the slow_path ... + Label LSuccess, LGoSlowPath ; bind (CheckSucc); // The following optional optimization can be elided if necessary @@ -2136,18 +2032,10 @@ // Intentional fall-through into slow path bind (LGoSlowPath); - if (!HandshakeAfterDeflateIdleMonitors) { - lock(); - decrementl(Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(ref_count))); - } orl (boxReg, 1); // set ICC.ZF=0 to indicate failure jmpb (DONE_LABEL); bind (LSuccess); - if (!HandshakeAfterDeflateIdleMonitors) { - lock(); - decrementl(Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(ref_count))); - } testl (boxReg, 0); // set ICC.ZF=1 to indicate success jmpb (DONE_LABEL); --- old/src/hotspot/cpu/x86/macroAssembler_x86.hpp 2020-02-25 17:43:50.000000000 -0500 +++ new/src/hotspot/cpu/x86/macroAssembler_x86.hpp 2020-02-25 17:43:50.000000000 -0500 @@ -680,7 +680,6 @@ BiasedLockingCounters* counters = NULL); void biased_locking_exit (Register obj_reg, Register temp_reg, Label& done); #ifdef COMPILER2 - void inc_om_ref_count(Register obj_reg, Register om_reg, Register temp_reg, Label& done); // Code used by cmpFastLock and cmpFastUnlock mach instructions in .ad file. // See full desription in macroAssembler_x86.cpp. void fast_lock(Register obj, Register box, Register tmp, --- old/src/hotspot/cpu/zero/globals_zero.hpp 2020-02-25 17:43:51.000000000 -0500 +++ new/src/hotspot/cpu/zero/globals_zero.hpp 2020-02-25 17:43:51.000000000 -0500 @@ -73,10 +73,6 @@ // No performance work done here yet. define_pd_global(bool, CompactStrings, false); -// No ObjectMonitor C2 fast_lock() or fast_unlock() so no need to -// use a handshake for safety. -define_pd_global(bool, HandshakeAfterDeflateIdleMonitors, false); - #define ARCH_FLAGS(develop, \ product, \ diagnostic, \ --- old/src/hotspot/share/oops/markWord.hpp 2020-02-25 17:43:52.000000000 -0500 +++ new/src/hotspot/share/oops/markWord.hpp 2020-02-25 17:43:52.000000000 -0500 @@ -216,10 +216,6 @@ bool is_unlocked() const { return (mask_bits(value(), biased_lock_mask_in_place) == unlocked_value); } - // ObjectMonitor::install_displaced_markword_in_object() uses - // is_marked() on ObjectMonitor::_header as part of the restoration - // protocol for an object's header. In this usage, the mark bits are - // only ever set (and cleared) on the ObjectMonitor::_header field. bool is_marked() const { return (mask_bits(value(), lock_mask_in_place) == marked_value); } --- old/src/hotspot/share/prims/jvmtiEnvBase.cpp 2020-02-25 17:43:53.000000000 -0500 +++ new/src/hotspot/share/prims/jvmtiEnvBase.cpp 2020-02-25 17:43:53.000000000 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it --- old/src/hotspot/share/runtime/basicLock.cpp 2020-02-25 17:43:54.000000000 -0500 +++ new/src/hotspot/share/runtime/basicLock.cpp 2020-02-25 17:43:54.000000000 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it --- old/src/hotspot/share/runtime/globals.hpp 2020-02-25 17:43:55.000000000 -0500 +++ new/src/hotspot/share/runtime/globals.hpp 2020-02-25 17:43:55.000000000 -0500 @@ -708,10 +708,6 @@ "MonitorUsedDeflationThreshold is exceeded (0 is off).") \ range(0, max_jint) \ \ - diagnostic_pd(bool, HandshakeAfterDeflateIdleMonitors, \ - "Handshake with all JavaThreads after async deflating idle " \ - "monitors to force threads to leave C2 monitor code.") \ - \ experimental(intx, MonitorUsedDeflationThreshold, 90, \ "Percentage of used monitors before triggering deflation (0 is " \ "off). The check is performed on GuaranteedSafepointInterval " \ --- old/src/hotspot/share/runtime/init.cpp 2020-02-25 17:43:56.000000000 -0500 +++ new/src/hotspot/share/runtime/init.cpp 2020-02-25 17:43:56.000000000 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it --- old/src/hotspot/share/runtime/objectMonitor.cpp 2020-02-25 17:43:57.000000000 -0500 +++ new/src/hotspot/share/runtime/objectMonitor.cpp 2020-02-25 17:43:57.000000000 -0500 @@ -271,8 +271,7 @@ 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(_recursions == 0, "invariant"); return; } @@ -449,45 +448,21 @@ return; } - // A non-NULL dmw has to be either neutral (not locked and not marked) - // or is already participating in this restoration protocol. - assert(dmw.is_neutral() || (dmw.is_marked() && dmw.hash() == 0), - "failed precondition: dmw=" INTPTR_FORMAT, dmw.value()); - - markWord marked_dmw = markWord::zero(); - if (!dmw.is_marked() && dmw.hash() == 0) { - // This dmw has not yet started the restoration protocol so we - // mark a copy of the dmw to begin the protocol. - // Note: A dmw with a hashcode does not take this code path. - marked_dmw = dmw.set_marked(); - - // All of the callers to this function can be racing with each - // other trying to update the _header field. - dmw = (markWord) Atomic::cmpxchg(&_header, dmw, marked_dmw); - if (dmw.value() == 0) { - // ObjectMonitor's header/dmw has been cleared so the object's - // header has already been restored. - return; - } - // The _header field is now marked. The winner's 'dmw' variable - // contains the original, unmarked header/dmw value and any - // losers have a marked header/dmw value that will be cleaned - // up below. - } - - if (dmw.is_marked()) { - // Clear the mark from the header/dmw copy in preparation for - // possible restoration from this thread. - assert(dmw.hash() == 0, "hashcode must be 0: dmw=" INTPTR_FORMAT, - dmw.value()); - dmw = dmw.set_unmarked(); - } - assert(dmw.is_neutral(), "must be neutral: dmw=" INTPTR_FORMAT, dmw.value()); + // A non-NULL dmw has to be neutral (not locked and not marked). + ADIM_guarantee(dmw.is_neutral(), "must be neutral: dmw=" INTPTR_FORMAT, dmw.value()); // Install displaced mark word if the object's header still points // to this ObjectMonitor. All racing callers to this function will // reach this point, but only one can win. - obj->cas_set_mark(dmw, markWord::encode(this)); + markWord res = obj->cas_set_mark(dmw, markWord::encode(this)); + if (res != markWord::encode(this)) { + // This should be rare so log at the Info level when it happens. + log_info(monitorinflation)("install_displaced_markword_in_object: " + "failed cas_set_mark: new_mark=" INTPTR_FORMAT + ", old_mark=" INTPTR_FORMAT ", res=" INTPTR_FORMAT, + dmw.value(), markWord::encode(this).value(), + res.value()); + } // Note: It does not matter which thread restored the header/dmw // into the object's header. The thread deflating the monitor just @@ -537,8 +512,7 @@ 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(_succ != Self, "invariant"); assert(_Responsible != Self, "invariant"); return; @@ -664,8 +638,7 @@ 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. break; } @@ -797,8 +770,7 @@ 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. break; } @@ -2125,6 +2097,8 @@ // The ObjectMonitor could have been deflated and reused for // another object before we bumped the ref_count so make sure // our object still refers to this ObjectMonitor. + // Note: With handshakes after deflation is this race even + // possible anymore? const markWord tmp = object->mark(); if (!tmp.has_monitor() || tmp.monitor() != om_ptr) { // Async deflation and reuse won the race so we have to retry. @@ -2162,7 +2136,7 @@ // saved. This function returns false if the specified ObjectMonitor* // is NULL or if we have lost a race with async deflation; the caller // can retry as appropriate. -bool ObjectMonitorHandle::set_om_ptr_if_safe(ObjectMonitor* om_ptr) { +bool ObjectMonitorHandle::save_om_ptr_if_safe(ObjectMonitor* om_ptr) { if (om_ptr == NULL) { return false; // Nothing to save if input is NULL } @@ -2280,7 +2254,7 @@ st->print_cr(" _pad_buf2 = {"); st->print_cr(" [0] = '\\0'"); st->print_cr(" ..."); - st->print_cr(" [%d] = '\\0'", (int)sizeof(_pad_buf1) - 1); + st->print_cr(" [%d] = '\\0'", (int)sizeof(_pad_buf2) - 1); st->print_cr(" }"); st->print_cr(" _next_om = " INTPTR_FORMAT, p2i(next_om())); st->print_cr(" _recursions = " INTX_FORMAT, _recursions); --- old/src/hotspot/share/runtime/objectMonitor.hpp 2020-02-25 17:43:58.000000000 -0500 +++ new/src/hotspot/share/runtime/objectMonitor.hpp 2020-02-25 17:43:58.000000000 -0500 @@ -223,7 +223,6 @@ static int header_offset_in_bytes() { return offset_of(ObjectMonitor, _header); } static int object_offset_in_bytes() { return offset_of(ObjectMonitor, _object); } static int owner_offset_in_bytes() { return offset_of(ObjectMonitor, _owner); } - static int ref_count_offset_in_bytes() { return offset_of(ObjectMonitor, _ref_count); } static int recursions_offset_in_bytes() { return offset_of(ObjectMonitor, _recursions); } static int cxq_offset_in_bytes() { return offset_of(ObjectMonitor, _cxq); } static int succ_offset_in_bytes() { return offset_of(ObjectMonitor, _succ); } @@ -396,7 +395,7 @@ // increment the ref_count. bool save_om_ptr(oop object, markWord mark); // Save the specified ObjectMonitor* if safe and increment the ref_count. - bool set_om_ptr_if_safe(ObjectMonitor* om_ptr); + bool save_om_ptr_if_safe(ObjectMonitor* om_ptr); // Unset the _om_ptr field and decrement the ref_count. void unset_om_ptr(); --- old/src/hotspot/share/runtime/objectMonitor.inline.hpp 2020-02-25 17:43:59.000000000 -0500 +++ new/src/hotspot/share/runtime/objectMonitor.inline.hpp 2020-02-25 17:43:59.000000000 -0500 @@ -89,8 +89,7 @@ // list, we leave those three fields alone; owner == DEFLATER_MARKER // and ref_count < 0 will force any racing threads to retry. The // header field is used by install_displaced_markword_in_object() - // in the last part of the deflation protocol so we cannot check - // its value here. + // to restore the object's header so we cannot check its value here. guarantee(_owner == NULL || _owner == DEFLATER_MARKER, "must be NULL or DEFLATER_MARKER: owner=" INTPTR_FORMAT, p2i(_owner)); --- old/src/hotspot/share/runtime/safepoint.cpp 2020-02-25 17:44:00.000000000 -0500 +++ new/src/hotspot/share/runtime/safepoint.cpp 2020-02-25 17:44:00.000000000 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it --- 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"); --- old/src/hotspot/share/runtime/thread.hpp 2020-02-25 17:44:03.000000000 -0500 +++ new/src/hotspot/share/runtime/thread.hpp 2020-02-25 17:44:02.000000000 -0500 @@ -625,7 +625,7 @@ // For tracking the heavyweight monitor the thread is pending on. ObjectMonitor* current_pending_monitor(ObjectMonitorHandle* omh_p) { - if (omh_p->set_om_ptr_if_safe(_current_pending_monitor)) { + if (omh_p->save_om_ptr_if_safe(_current_pending_monitor)) { return omh_p->om_ptr(); // Return the safe ObjectMonitor*. } return NULL; @@ -651,7 +651,7 @@ // For tracking the ObjectMonitor on which this thread called Object.wait() ObjectMonitor* current_waiting_monitor(ObjectMonitorHandle* omh_p) { - if (omh_p->set_om_ptr_if_safe(_current_waiting_monitor)) { + if (omh_p->save_om_ptr_if_safe(_current_waiting_monitor)) { return omh_p->om_ptr(); // Return the safe ObjectMonitor*. } return NULL; --- old/src/hotspot/share/runtime/vframe.cpp 2020-02-25 17:44:04.000000000 -0500 +++ new/src/hotspot/share/runtime/vframe.cpp 2020-02-25 17:44:03.000000000 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it --- old/src/hotspot/share/runtime/vmOperations.cpp 2020-02-25 17:44:05.000000000 -0500 +++ new/src/hotspot/share/runtime/vmOperations.cpp 2020-02-25 17:44:04.000000000 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it --- old/src/hotspot/share/services/threadService.cpp 2020-02-25 17:44:06.000000000 -0500 +++ new/src/hotspot/share/services/threadService.cpp 2020-02-25 17:44:05.000000000 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it --- old/test/hotspot/gtest/oops/test_markWord.cpp 2020-02-25 17:44:07.000000000 -0500 +++ new/test/hotspot/gtest/oops/test_markWord.cpp 2020-02-25 17:44:07.000000000 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it --- old/test/hotspot/jtreg/runtime/logging/SafepointCleanupTest.java 2020-02-25 17:44:08.000000000 -0500 +++ new/test/hotspot/jtreg/runtime/logging/SafepointCleanupTest.java 2020-02-25 17:44:08.000000000 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it --- old/test/jdk/java/rmi/server/UnicastRemoteObject/unexportObject/UnexportLeak.java 2020-02-25 17:44:09.000000000 -0500 +++ new/test/jdk/java/rmi/server/UnicastRemoteObject/unexportObject/UnexportLeak.java 2020-02-25 17:44:09.000000000 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -74,7 +74,7 @@ } /** - * Force desperate garbage collection so that all WeakReference instances + * Force desparate garbage collection so that all WeakReference instances * will be cleared. */ private static void flushRefs() { @@ -85,9 +85,6 @@ chain.addElement(hungry); } } catch (OutOfMemoryError e) { - // An inflated Java monitor can keep 'obj' alive so request - // an explicit GC to make sure things are cleaned up. - System.gc(); } } }