< prev index next >
src/hotspot/share/runtime/synchronizer.cpp
Print this page
rev 54612 : Checkpoint latest preliminary review patches for full OpenJDK review; merge with 8222295.patch.
rev 54613 : imported patch dcubed.monitor_deflate_conc.v2.01
rev 54614 : imported patch dcubed.monitor_deflate_conc.v2.02
rev 54615 : imported patch dcubed.monitor_deflate_conc.v2.03
@@ -348,12 +348,10 @@
// Interpreter/Compiler Slow Case
// This routine is used to handle interpreter/compiler slow case
// We don't need to use fast path here, because it must have been
// failed in the interpreter/compiler code.
void ObjectSynchronizer::slow_enter(Handle obj, BasicLock* lock, TRAPS) {
- bool do_loop = true;
- while (do_loop) {
markOop mark = obj->mark();
assert(!mark->has_bias_pattern(), "should not see bias pattern here");
if (mark->is_neutral()) {
// Anticipate successful CAS -- the ST of the displaced mark must
@@ -376,12 +374,11 @@
// must be non-zero to avoid looking like a re-entrant lock,
// and must not look locked either.
lock->set_displaced_header(markOopDesc::unused_mark());
ObjectMonitorHandle omh;
inflate(&omh, THREAD, obj(), inflate_cause_monitor_enter);
- do_loop = !omh.om_ptr()->enter(THREAD);
- }
+ omh.om_ptr()->enter(THREAD);
}
// This routine is used to handle interpreter/compiler slow case
// We don't need to use fast path here, because it must have
// failed in the interpreter/compiler code. Simply use the heavy
@@ -419,16 +416,13 @@
if (UseBiasedLocking) {
BiasedLocking::revoke_and_rebias(obj, false, THREAD);
assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now");
}
- bool do_loop = true;
- while (do_loop) {
ObjectMonitorHandle omh;
inflate(&omh, THREAD, obj(), inflate_cause_vm_internal);
- do_loop = !omh.om_ptr()->reenter(recursion, THREAD);
- }
+ omh.om_ptr()->reenter(recursion, THREAD);
}
// -----------------------------------------------------------------------------
// JNI locks on java objects
// NOTE: must use heavy weight monitor to handle jni monitor enter
void ObjectSynchronizer::jni_enter(Handle obj, TRAPS) {
@@ -436,16 +430,13 @@
if (UseBiasedLocking) {
BiasedLocking::revoke_and_rebias(obj, false, THREAD);
assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now");
}
THREAD->set_current_pending_monitor_is_from_java(false);
- bool do_loop = true;
- while (do_loop) {
ObjectMonitorHandle omh;
inflate(&omh, THREAD, obj(), inflate_cause_jni_enter);
- do_loop = !omh.om_ptr()->enter(THREAD);
- }
+ omh.om_ptr()->enter(THREAD);
THREAD->set_current_pending_monitor_is_from_java(true);
}
// NOTE: must use heavy weight monitor to handle jni monitor exit
void ObjectSynchronizer::jni_exit(oop obj, Thread* THREAD) {
@@ -1172,11 +1163,10 @@
guarantee(take->object() == NULL, "invariant");
if (AsyncDeflateIdleMonitors) {
// Clear any values we allowed to linger during async deflation.
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);
@@ -1780,18 +1770,18 @@
// Deflate the specified ObjectMonitor if not in-use using a JavaThread.
// Returns true if it was deflated and false otherwise.
//
// The async deflation protocol sets owner to DEFLATER_MARKER and
-// makes contentions negative as signals to contending threads that
+// makes ref_count 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 or to a thread that just
// wants to use the ObjectMonitor*.
//
// The ObjectMonitor has been successfully async deflated when:
-// (owner == DEFLATER_MARKER && contentions < 0 && ref_count < 0).
+// (owner == DEFLATER_MARKER && 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,
@@ -1813,45 +1803,37 @@
// 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->_waiters != 0 || mid->ref_count() != 0) {
+ if (mid->_contentions != 0 || mid->_waiters != 0) {
// Another thread has raced to enter the ObjectMonitor after
- // mid->is_busy() above and has already waited on it which
- // makes it busy so no deflation. Or the ObjectMonitor* is
- // in use for some other operation like inflate(). Restore
- // owner to NULL if it is still DEFLATER_MARKER.
+ // 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.
Atomic::cmpxchg((void*)NULL, &mid->_owner, DEFLATER_MARKER);
return false;
}
- if (Atomic::cmpxchg(-max_jint, &mid->_contentions, (jint)0) == 0) {
- // Make contentions negative to force any contending threads to
- // retry. This is the second part of the async deflation dance.
+ if (Atomic::cmpxchg(-max_jint, &mid->_ref_count, (jint)0) == 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 == DEFLATER_MARKER &&
- Atomic::cmpxchg(-max_jint, &mid->_ref_count, (jint)0) == 0) {
+ if (mid->_owner == 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. 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
+ // 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 contentions to zero.
- // 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.
+ // 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,
@@ -1896,33 +1878,31 @@
// At this point, mid->FreeNext still refers to its current
// value and another ObjectMonitor's FreeNext 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 contentions < 0
+ // 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 or ObjectMonitor*
- // is in use so we lost the race since the ObjectMonitor is now
- // busy.
-
- // Restore owner to NULL if it is still DEFLATER_MARKER:
- Atomic::cmpxchg((void*)NULL, &mid->_owner, 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 contentions field to its
+ // Add back max_jint to restore the ref_count field to its
// proper value (which may not be what we saw above):
- Atomic::add(max_jint, &mid->_contentions);
+ Atomic::add(max_jint, &mid->_ref_count);
- assert(mid->_contentions >= 0, "must not be negative: contentions=%d",
- mid->_contentions);
+ assert(mid->ref_count() >= 0, "must not be negative: ref_count=%d",
+ mid->ref_count());
+ return false;
}
- // The contentions was no longer 0 so we lost the race since the
- // ObjectMonitor is now busy.
- assert(mid->_owner != DEFLATER_MARKER, "must not be DEFLATER_MARKER");
+ // 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:
+ Atomic::cmpxchg((void*)NULL, &mid->_owner, DEFLATER_MARKER);
}
// The owner field is no longer NULL so we lost the race since the
// ObjectMonitor is now busy.
return false;
< prev index next >