< 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 (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.
//
< prev index next >