diff a/src/hotspot/share/runtime/synchronizer.cpp b/src/hotspot/share/runtime/synchronizer.cpp --- a/src/hotspot/share/runtime/synchronizer.cpp +++ b/src/hotspot/share/runtime/synchronizer.cpp @@ -2221,123 +2221,122 @@ // Easy checks are first - the ObjectMonitor is busy or ObjectMonitor* // is in use so no deflation. return false; } - if (mid->try_set_owner_from(NULL, DEFLATER_MARKER) == NULL) { - // ObjectMonitor is not owned by another thread. Our setting - // owner to DEFLATER_MARKER forces any contending thread through - // the slow path. This is just the first part of the async - // deflation dance. - - if (mid->_contentions != 0 || mid->_waiters != 0) { - // Another thread has raced to enter the ObjectMonitor after - // mid->is_busy() above or has already entered and waited on - // it which makes it busy so no deflation. Restore owner to - // NULL if it is still DEFLATER_MARKER. - mid->try_set_owner_from(DEFLATER_MARKER, NULL); - return false; - } + if (mid->try_set_owner_from(NULL, DEFLATER_MARKER) != NULL) { + // The owner field is no longer NULL so we lost the race since the + // ObjectMonitor is now busy. + return false; + } + // ObjectMonitor is not owned by another thread. Our setting + // owner to DEFLATER_MARKER forces any contending thread through + // the slow path. This is just the first part of the async + // deflation dance. - if (Atomic::cmpxchg(&mid->_ref_count, (jint)0, -max_jint) == 0) { - // Make ref_count negative to force any contending threads or - // ObjectMonitor* using threads to retry. This is the second - // part of the async deflation dance. - - 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 - // is now busy. This is the third and final part of the async - // deflation dance. - // Note: This owner check solves the ABA problem with ref_count - // where another thread acquired the ObjectMonitor, finished - // using it and restored the ref_count to zero. - - // Sanity checks for the races: - guarantee(mid->_contentions == 0, "must be 0: contentions=%d", - mid->_contentions); - guarantee(mid->_waiters == 0, "must be 0: waiters=%d", mid->_waiters); - guarantee(mid->_cxq == NULL, "must be no contending threads: cxq=" - INTPTR_FORMAT, p2i(mid->_cxq)); - guarantee(mid->_EntryList == NULL, - "must be no entering threads: EntryList=" INTPTR_FORMAT, - p2i(mid->_EntryList)); - - const oop obj = (oop) mid->object(); - if (log_is_enabled(Trace, monitorinflation)) { - ResourceMark rm; - log_trace(monitorinflation)("deflate_monitor_using_JT: " - "object=" INTPTR_FORMAT ", mark=" - INTPTR_FORMAT ", type='%s'", - p2i(obj), obj->mark().value(), - obj->klass()->external_name()); - } + if (mid->_contentions != 0 || mid->_waiters != 0) { + // Another thread has raced to enter the ObjectMonitor after + // mid->is_busy() above or has already entered and waited on + // it which makes it busy so no deflation. Restore owner to + // NULL if it is still DEFLATER_MARKER. + mid->try_set_owner_from(DEFLATER_MARKER, NULL); + return false; + } - // Install the old mark word if nobody else has already done it. - mid->install_displaced_markword_in_object(obj); - mid->clear_using_JT(); + // Make ref_count negative to force any contending threads or + // ObjectMonitor* using threads to retry. This is the second + // part of the async deflation dance. + if (Atomic::cmpxchg(&mid->_ref_count, (jint)0, -max_jint) != 0) { + // The ref_count was no longer 0 so we lost the race since the + // ObjectMonitor is now busy or the ObjectMonitor* is now is use. + // Restore owner to NULL if it is still DEFLATER_MARKER: + mid->try_set_owner_from(DEFLATER_MARKER, NULL); + return false; + } - assert(mid->object() == NULL, "must be NULL: object=" INTPTR_FORMAT, - p2i(mid->object())); - assert(mid->is_free(), "must be free: allocation_state=%d", - (int) mid->allocation_state()); + if (!mid->owner_is_DEFLATER_MARKER()) { + // The owner was changed from DEFLATER_MARKER so we lost the + // race since the ObjectMonitor is now busy. + + // Add back max_jint to restore the ref_count field to its + // proper value (which may not be what we saw above): + Atomic::add(&mid->_ref_count, max_jint); - // Move the deflated ObjectMonitor to the working free list - // defined by free_head_p and free_tail_p. - if (*free_head_p == NULL) { - // First one on the list. - *free_head_p = mid; - } - if (*free_tail_p != NULL) { - // We append to the list so the caller can use mid->_next_om - // to fix the linkages in its context. - ObjectMonitor* prevtail = *free_tail_p; - // Should have been cleaned up by the caller: - om_lock(prevtail); #ifdef ASSERT - ObjectMonitor* l_next_om = unmarked_next(prevtail); + jint l_ref_count = mid->ref_count(); #endif - assert(l_next_om == NULL, "must be NULL: _next_om=" INTPTR_FORMAT, p2i(l_next_om)); - prevtail->set_next_om(mid); // prevtail now points to mid (and is unlocked) - } - *free_tail_p = mid; - - // At this point, mid->_next_om still refers to its current - // value and another ObjectMonitor's _next_om field still - // refers to this ObjectMonitor. Those linkages have to be - // cleaned up by the caller who has the complete context. - - // We leave owner == DEFLATER_MARKER and ref_count < 0 - // to force any racing threads to retry. - return true; // Success, ObjectMonitor has been deflated. - } - - // The owner was changed from DEFLATER_MARKER so we lost the - // race since the ObjectMonitor is now busy. + assert(l_ref_count >= 0, "must not be negative: l_ref_count=%d, ref_count=%d", + l_ref_count, mid->ref_count()); + return false; + } - // Add back max_jint to restore the ref_count field to its - // proper value (which may not be what we saw above): - Atomic::add(&mid->_ref_count, max_jint); + // 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 + // is now busy. This is the third and final part of the async + // deflation dance. + // Note: This owner check solves the ABA problem with ref_count + // where another thread acquired the ObjectMonitor, finished + // using it and restored the ref_count to zero. + + // Sanity checks for the races: + guarantee(mid->_contentions == 0, "must be 0: contentions=%d", + mid->_contentions); + guarantee(mid->_waiters == 0, "must be 0: waiters=%d", mid->_waiters); + guarantee(mid->_cxq == NULL, "must be no contending threads: cxq=" + INTPTR_FORMAT, p2i(mid->_cxq)); + guarantee(mid->_EntryList == NULL, + "must be no entering threads: EntryList=" INTPTR_FORMAT, + p2i(mid->_EntryList)); + + const oop obj = (oop) mid->object(); + if (log_is_enabled(Trace, monitorinflation)) { + ResourceMark rm; + log_trace(monitorinflation)("deflate_monitor_using_JT: " + "object=" INTPTR_FORMAT ", mark=" + INTPTR_FORMAT ", type='%s'", + p2i(obj), obj->mark().value(), + obj->klass()->external_name()); + } + + // Install the old mark word if nobody else has already done it. + mid->install_displaced_markword_in_object(obj); + mid->clear_using_JT(); + + assert(mid->object() == NULL, "must be NULL: object=" INTPTR_FORMAT, + p2i(mid->object())); + assert(mid->is_free(), "must be free: allocation_state=%d", + (int) mid->allocation_state()); + // Move the deflated ObjectMonitor to the working free list + // defined by free_head_p and free_tail_p. + if (*free_head_p == NULL) { + // First one on the list. + *free_head_p = mid; + } + if (*free_tail_p != NULL) { + // We append to the list so the caller can use mid->_next_om + // to fix the linkages in its context. + ObjectMonitor* prevtail = *free_tail_p; + // Should have been cleaned up by the caller: + om_lock(prevtail); #ifdef ASSERT - jint l_ref_count = mid->ref_count(); + ObjectMonitor* l_next_om = unmarked_next(prevtail); #endif - assert(l_ref_count >= 0, "must not be negative: l_ref_count=%d, ref_count=%d", - l_ref_count, mid->ref_count()); - return false; - } - - // The ref_count was no longer 0 so we lost the race since the - // ObjectMonitor is now busy or the ObjectMonitor* is now is use. - // Restore owner to NULL if it is still DEFLATER_MARKER: - mid->try_set_owner_from(DEFLATER_MARKER, NULL); + assert(l_next_om == NULL, "must be NULL: _next_om=" INTPTR_FORMAT, p2i(l_next_om)); + prevtail->set_next_om(mid); // prevtail now points to mid (and is unlocked) } + *free_tail_p = mid; - // The owner field is no longer NULL so we lost the race since the - // ObjectMonitor is now busy. - return false; + // At this point, mid->_next_om still refers to its current + // value and another ObjectMonitor's _next_om field still + // refers to this ObjectMonitor. Those linkages have to be + // cleaned up by the caller who has the complete context. + + // We leave owner == DEFLATER_MARKER and ref_count < 0 + // to force any racing threads to retry. + return true; // Success, ObjectMonitor has been deflated. } // Walk a given monitor list, and deflate idle monitors. // The given list could be a per-thread list or a global list. //