< 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 >