--- old/src/hotspot/share/runtime/objectMonitor.hpp 2020-07-14 21:33:18.000000000 -0400 +++ new/src/hotspot/share/runtime/objectMonitor.hpp 2020-07-14 21:33:18.000000000 -0400 @@ -330,8 +330,10 @@ void* object() const; void* object_addr(); void set_object(void* obj); + void release_set_allocation_state(AllocationState s); void set_allocation_state(AllocationState s); AllocationState allocation_state() const; + AllocationState allocation_state_acquire() const; bool is_free() const; bool is_old() const; bool is_new() const; --- old/src/hotspot/share/runtime/objectMonitor.inline.hpp 2020-07-14 21:33:19.000000000 -0400 +++ new/src/hotspot/share/runtime/objectMonitor.inline.hpp 2020-07-14 21:33:19.000000000 -0400 @@ -191,6 +191,10 @@ return prev; } +inline void ObjectMonitor::release_set_allocation_state(ObjectMonitor::AllocationState s) { + Atomic::release_store((int*)&_allocation_state, (int)s); +} + inline void ObjectMonitor::set_allocation_state(ObjectMonitor::AllocationState s) { _allocation_state = s; } @@ -199,12 +203,16 @@ return _allocation_state; } +inline ObjectMonitor::AllocationState ObjectMonitor::allocation_state_acquire() const { + return (AllocationState)Atomic::load_acquire((int*)&_allocation_state); +} + inline bool ObjectMonitor::is_free() const { return _allocation_state == Free; } inline bool ObjectMonitor::is_old() const { - return _allocation_state == Old; + return allocation_state_acquire() == Old; } inline bool ObjectMonitor::is_new() const { --- old/src/hotspot/share/runtime/synchronizer.cpp 2020-07-14 21:33:20.000000000 -0400 +++ new/src/hotspot/share/runtime/synchronizer.cpp 2020-07-14 21:33:20.000000000 -0400 @@ -1908,7 +1908,8 @@ // Once ObjectMonitor is configured and the object is associated // with the ObjectMonitor, it is safe to allow async deflation: assert(m->is_new(), "freshly allocated monitor must be new"); - m->set_allocation_state(ObjectMonitor::Old); + // Release semantics needed to keep allocation_state from floating up. + m->release_set_allocation_state(ObjectMonitor::Old); // Hopefully the performance counters are allocated on distinct cache lines // to avoid false sharing on MP systems ... @@ -1965,6 +1966,8 @@ // Once the ObjectMonitor is configured and object is associated // with the ObjectMonitor, it is safe to allow async deflation: assert(m->is_new(), "freshly allocated monitor must be new"); + // Release semantics are not needed to keep allocation_state from + // floating up since cas_set_mark() takes care of it. m->set_allocation_state(ObjectMonitor::Old); // Hopefully the performance counters are allocated on distinct