--- old/src/hotspot/share/runtime/synchronizer.cpp 2019-04-25 12:04:44.240813900 -0400 +++ new/src/hotspot/share/runtime/synchronizer.cpp 2019-04-25 12:04:43.764813908 -0400 @@ -1175,6 +1175,15 @@ take->_header = NULL; take->set_owner(NULL); take->_contentions = 0; + + if (take->ref_count() < 0) { + // Add back max_jint to restore the ref_count field to its + // proper value. + Atomic::add(max_jint, &take->_ref_count); + + assert(take->ref_count() >= 0, "must not be negative: ref_count=%d", + take->ref_count()); + } } guarantee(!take->is_busy(), "invariant"); take->Recycle(); @@ -1776,11 +1785,13 @@ // makes contentions negative as signals to contending threads that // an async deflation is in progress. There are a number of checks // as part of the protocol to make sure that the calling thread has -// not lost the race to a contending thread. +// not lost the race to a contending thread or to a thread that just +// wants to use the ObjectMonitor*. // // The ObjectMonitor has been successfully async deflated when: -// (owner == DEFLATER_MARKER && contentions < 0). Contending threads -// that see those values know to retry their operation. +// (owner == DEFLATER_MARKER && contentions < 0 && ref_count < 0). +// Contending threads or ObjectMonitor* using threads that see those +// values know to retry their operation. // bool ObjectSynchronizer::deflate_monitor_using_JT(ObjectMonitor* mid, ObjectMonitor** freeHeadp, @@ -1815,22 +1826,28 @@ } if (Atomic::cmpxchg(-max_jint, &mid->_contentions, (jint)0) == 0) { - // Make contentions negative to force racing threads to retry. - // This is the second part of the async deflation dance. + // Make contentions negative to force any contending threads to + // retry. This is the second part of the async deflation dance. - if (mid->_owner == DEFLATER_MARKER && mid->ref_count() == 0) { + if (mid->_owner == DEFLATER_MARKER && + Atomic::cmpxchg(-max_jint, &mid->_ref_count, (jint)0) == 0) { // If owner is still DEFLATER_MARKER, then we have successfully - // signaled any racing threads to retry. If it is not, then we + // signaled any contending threads to retry. If it is not, then we // have lost the race to an entering thread and the ObjectMonitor - // is now busy. If the ObjectMonitor* is in use, then we have - // lost that race. This is the third and final part of the async - // deflation dance. + // is now busy. If we cannot make ref_count negative (because the + // ObjectMonitor* is in use), then we have lost that race instead. + // This is the third and final part of the async deflation dance. // Note: This owner check solves the ABA problem with contentions // where another thread acquired the ObjectMonitor, finished // using it and restored the contentions to zero. - // Note: This ref_count check solves the race with save_om_ptr() - // where its ref_count increment happens after the first ref_count - // check in this function and before contentions is made negative. + // Note: Making ref_count negative solves the race with + // ObjectMonitor::save_om_ptr() where its ref_count increment + // happens after the first ref_count check in this function. + // Note: Making ref_count negative must happen after the third + // part check of "owner == DEFLATER_MARKER". When save_om_ptr() + // retries, it will call install_displaced_markword_in_object() + // which will disconnect the object from the ObjectMonitor so + // deflation must happen. // Sanity checks for the races: guarantee(mid->_waiters == 0, "must be 0: waiters=%d", mid->_waiters);