< prev index next > src/hotspot/share/runtime/synchronizer.cpp
Print this page
// 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 (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());
- }
! // 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
! ObjectMonitor* l_next_om = unmarked_next(prevtail);
#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.
! // 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);
#ifdef ASSERT
! jint l_ref_count = mid->ref_count();
#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);
}
! // The owner field is no longer NULL so we lost the race since the
! // ObjectMonitor is now busy.
! return false;
}
// Walk a given monitor list, and deflate idle monitors.
// The given list could be a per-thread list or a global list.
//
// 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) {
! // 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 (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;
! }
! // 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;
+ }
! 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);
#ifdef ASSERT
! jint l_ref_count = mid->ref_count();
#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;
! }
! // 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
! ObjectMonitor* l_next_om = unmarked_next(prevtail);
#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.
}
// Walk a given monitor list, and deflate idle monitors.
// The given list could be a per-thread list or a global list.
//
< prev index next >