8229844: Remove attempt_rebias parameter from revoke_and_rebias()
authorpchilanomate
Tue, 27 Aug 2019 20:10:06 +0000
changeset 57893 49fea19f0726
parent 57892 fb6cd98e4dec
child 57894 01b9c26e2651
8229844: Remove attempt_rebias parameter from revoke_and_rebias() Summary: Removed attempt_rebias parameter and merged fast_enter() and slow_enter() into enter() Reviewed-by: dholmes, rehn, coleenp, dcubed
src/hotspot/cpu/aarch64/aarch64.ad
src/hotspot/cpu/sparc/macroAssembler_sparc.cpp
src/hotspot/cpu/x86/macroAssembler_x86.cpp
src/hotspot/share/c1/c1_Runtime1.cpp
src/hotspot/share/interpreter/interpreterRuntime.cpp
src/hotspot/share/jvmci/jvmciRuntime.cpp
src/hotspot/share/prims/jvmtiEnvBase.cpp
src/hotspot/share/runtime/biasedLocking.cpp
src/hotspot/share/runtime/biasedLocking.hpp
src/hotspot/share/runtime/deoptimization.cpp
src/hotspot/share/runtime/sharedRuntime.cpp
src/hotspot/share/runtime/synchronizer.cpp
src/hotspot/share/runtime/synchronizer.hpp
test/hotspot/gtest/oops/test_markOop.cpp
--- a/src/hotspot/cpu/aarch64/aarch64.ad	Tue Aug 27 19:22:58 2019 +0200
+++ b/src/hotspot/cpu/aarch64/aarch64.ad	Tue Aug 27 20:10:06 2019 +0000
@@ -3569,7 +3569,7 @@
     // Store a non-null value into the box to avoid looking like a re-entrant
     // lock. The fast-path monitor unlock code checks for
     // markWord::monitor_value so use markWord::unused_mark which has the
-    // relevant bit set, and also matches ObjectSynchronizer::slow_enter.
+    // relevant bit set, and also matches ObjectSynchronizer::enter.
     __ mov(tmp, (address)markWord::unused_mark().value());
     __ str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes()));
 
--- a/src/hotspot/cpu/sparc/macroAssembler_sparc.cpp	Tue Aug 27 19:22:58 2019 +0200
+++ b/src/hotspot/cpu/sparc/macroAssembler_sparc.cpp	Tue Aug 27 20:10:06 2019 +0000
@@ -2607,8 +2607,8 @@
 // -   Successful Stack-lock: box->dhw == mark.
 //     box->dhw must contain the displaced mark word value
 // -   Failure -- icc.ZFlag == 0 and box->dhw is undefined.
-//     The slow-path fast_enter() and slow_enter() operators
-//     are responsible for setting box->dhw = NonZero (typically markWord::unused_mark()).
+//     The slow-path enter() is responsible for setting
+//     box->dhw = NonZero (typically markWord::unused_mark()).
 // -   Biased: box->dhw is undefined
 //
 // SPARC refworkload performance - specifically jetstream and scimark - are
--- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp	Tue Aug 27 19:22:58 2019 +0200
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp	Tue Aug 27 20:10:06 2019 +0000
@@ -1620,8 +1620,8 @@
 // See also: cmpFastLock and cmpFastUnlock.
 //
 // What follows is a specialized inline transliteration of the code
-// in slow_enter() and slow_exit().  If we're concerned about I$ bloat
-// another option would be to emit TrySlowEnter and TrySlowExit methods
+// in enter() and exit(). If we're concerned about I$ bloat another
+// option would be to emit TrySlowEnter and TrySlowExit methods
 // at startup-time.  These methods would accept arguments as
 // (rax,=Obj, rbx=Self, rcx=box, rdx=Scratch) and return success-failure
 // indications in the icc.ZFlag.  Fast_Lock and Fast_Unlock would simply
--- a/src/hotspot/share/c1/c1_Runtime1.cpp	Tue Aug 27 19:22:58 2019 +0200
+++ b/src/hotspot/share/c1/c1_Runtime1.cpp	Tue Aug 27 20:10:06 2019 +0000
@@ -705,19 +705,11 @@
     Atomic::inc(BiasedLocking::slow_path_entry_count_addr());
   }
   Handle h_obj(thread, obj);
-  if (UseBiasedLocking) {
-    // Retry fast entry if bias is revoked to avoid unnecessary inflation
-    ObjectSynchronizer::fast_enter(h_obj, lock->lock(), true, CHECK);
-  } else {
-    if (UseFastLocking) {
-      // When using fast locking, the compiled code has already tried the fast case
-      assert(obj == lock->obj(), "must match");
-      ObjectSynchronizer::slow_enter(h_obj, lock->lock(), THREAD);
-    } else {
-      lock->set_obj(obj);
-      ObjectSynchronizer::fast_enter(h_obj, lock->lock(), false, THREAD);
-    }
+  if (!UseFastLocking) {
+    lock->set_obj(obj);
   }
+  assert(obj == lock->obj(), "must match");
+  ObjectSynchronizer::enter(h_obj, lock->lock(), THREAD);
 JRT_END
 
 
@@ -730,12 +722,7 @@
 
   oop obj = lock->obj();
   assert(oopDesc::is_oop(obj), "must be NULL or an object");
-  if (UseFastLocking) {
-    // When using fast locking, the compiled code has already tried the fast case
-    ObjectSynchronizer::slow_exit(obj, lock->lock(), THREAD);
-  } else {
-    ObjectSynchronizer::fast_exit(obj, lock->lock(), THREAD);
-  }
+  ObjectSynchronizer::exit(obj, lock->lock(), THREAD);
 JRT_END
 
 // Cf. OptoRuntime::deoptimize_caller_frame
--- a/src/hotspot/share/interpreter/interpreterRuntime.cpp	Tue Aug 27 19:22:58 2019 +0200
+++ b/src/hotspot/share/interpreter/interpreterRuntime.cpp	Tue Aug 27 20:10:06 2019 +0000
@@ -771,12 +771,7 @@
   Handle h_obj(thread, elem->obj());
   assert(Universe::heap()->is_in_reserved_or_null(h_obj()),
          "must be NULL or an object");
-  if (UseBiasedLocking) {
-    // Retry fast entry if bias is revoked to avoid unnecessary inflation
-    ObjectSynchronizer::fast_enter(h_obj, elem->lock(), true, CHECK);
-  } else {
-    ObjectSynchronizer::slow_enter(h_obj, elem->lock(), CHECK);
-  }
+  ObjectSynchronizer::enter(h_obj, elem->lock(), CHECK);
   assert(Universe::heap()->is_in_reserved_or_null(elem->obj()),
          "must be NULL or an object");
 #ifdef ASSERT
@@ -796,7 +791,7 @@
   if (elem == NULL || h_obj()->is_unlocked()) {
     THROW(vmSymbols::java_lang_IllegalMonitorStateException());
   }
-  ObjectSynchronizer::slow_exit(h_obj(), elem->lock(), thread);
+  ObjectSynchronizer::exit(h_obj(), elem->lock(), thread);
   // Free entry. This must be done here, since a pending exception might be installed on
   // exit. If it is not cleared, the exception handling code will try to unlock the monitor again.
   elem->set_obj(NULL);
--- a/src/hotspot/share/jvmci/jvmciRuntime.cpp	Tue Aug 27 19:22:58 2019 +0200
+++ b/src/hotspot/share/jvmci/jvmciRuntime.cpp	Tue Aug 27 20:10:06 2019 +0000
@@ -394,17 +394,7 @@
   }
   Handle h_obj(thread, obj);
   assert(oopDesc::is_oop(h_obj()), "must be NULL or an object");
-  if (UseBiasedLocking) {
-    // Retry fast entry if bias is revoked to avoid unnecessary inflation
-    ObjectSynchronizer::fast_enter(h_obj, lock, true, CHECK);
-  } else {
-    if (JVMCIUseFastLocking) {
-      // When using fast locking, the compiled code has already tried the fast case
-      ObjectSynchronizer::slow_enter(h_obj, lock, THREAD);
-    } else {
-      ObjectSynchronizer::fast_enter(h_obj, lock, false, THREAD);
-    }
-  }
+  ObjectSynchronizer::enter(h_obj, lock, THREAD);
   TRACE_jvmci_3("%s: exiting locking slow with obj=" INTPTR_FORMAT, thread->name(), p2i(obj));
 JRT_END
 
@@ -426,12 +416,7 @@
   }
 #endif
 
-  if (JVMCIUseFastLocking) {
-    // When using fast locking, the compiled code has already tried the fast case
-    ObjectSynchronizer::slow_exit(obj, lock, THREAD);
-  } else {
-    ObjectSynchronizer::fast_exit(obj, lock, THREAD);
-  }
+  ObjectSynchronizer::exit(obj, lock, THREAD);
   IF_TRACE_jvmci_3 {
     char type[O_BUFLEN];
     obj->klass()->name()->as_C_string(type, O_BUFLEN);
--- a/src/hotspot/share/prims/jvmtiEnvBase.cpp	Tue Aug 27 19:22:58 2019 +0200
+++ b/src/hotspot/share/prims/jvmtiEnvBase.cpp	Tue Aug 27 20:10:06 2019 +0000
@@ -960,7 +960,7 @@
     if (at_safepoint) {
       BiasedLocking::revoke_at_safepoint(hobj);
     } else {
-      BiasedLocking::revoke_and_rebias(hobj, false, calling_thread);
+      BiasedLocking::revoke(hobj, calling_thread);
     }
 
     address owner = NULL;
--- a/src/hotspot/share/runtime/biasedLocking.cpp	Tue Aug 27 19:22:58 2019 +0200
+++ b/src/hotspot/share/runtime/biasedLocking.cpp	Tue Aug 27 20:10:06 2019 +0000
@@ -157,7 +157,7 @@
 
 // After the call, *biased_locker will be set to obj->mark()->biased_locker() if biased_locker != NULL,
 // AND it is a living thread. Otherwise it will not be updated, (i.e. the caller is responsible for initialization).
-BiasedLocking::Condition BiasedLocking::single_revoke_at_safepoint(oop obj, bool allow_rebias, bool is_bulk, JavaThread* requesting_thread, JavaThread** biased_locker) {
+void BiasedLocking::single_revoke_at_safepoint(oop obj, bool is_bulk, JavaThread* requesting_thread, JavaThread** biased_locker) {
   assert(SafepointSynchronize::is_at_safepoint(), "must be done at safepoint");
   assert(Thread::current()->is_VM_thread(), "must be VMThread");
 
@@ -173,11 +173,10 @@
                               obj->klass()->external_name(),
                               (intptr_t) requesting_thread);
     }
-    return NOT_BIASED;
+    return;
   }
 
   uint age = mark.age();
-  markWord   biased_prototype = markWord::biased_locking_prototype().set_age(age);
   markWord unbiased_prototype = markWord::prototype().set_age(age);
 
   // Log at "info" level if not bulk, else "trace" level
@@ -185,23 +184,21 @@
     ResourceMark rm;
     log_info(biasedlocking)("Revoking bias of object " INTPTR_FORMAT ", mark "
                             INTPTR_FORMAT ", type %s, prototype header " INTPTR_FORMAT
-                            ", allow rebias %d, requesting thread " INTPTR_FORMAT,
+                            ", requesting thread " INTPTR_FORMAT,
                             p2i((void *)obj),
                             mark.value(),
                             obj->klass()->external_name(),
                             obj->klass()->prototype_header().value(),
-                            (allow_rebias ? 1 : 0),
                             (intptr_t) requesting_thread);
   } else {
     ResourceMark rm;
     log_trace(biasedlocking)("Revoking bias of object " INTPTR_FORMAT " , mark "
                              INTPTR_FORMAT " , type %s , prototype header " INTPTR_FORMAT
-                             " , allow rebias %d , requesting thread " INTPTR_FORMAT,
+                             " , requesting thread " INTPTR_FORMAT,
                              p2i((void *)obj),
                              mark.value(),
                              obj->klass()->external_name(),
                              obj->klass()->prototype_header().value(),
-                             (allow_rebias ? 1 : 0),
                              (intptr_t) requesting_thread);
   }
 
@@ -210,16 +207,15 @@
     // Object is anonymously biased. We can get here if, for
     // example, we revoke the bias due to an identity hash code
     // being computed for an object.
-    if (!allow_rebias) {
-      obj->set_mark(unbiased_prototype);
-    }
+    obj->set_mark(unbiased_prototype);
+
     // Log at "info" level if not bulk, else "trace" level
     if (!is_bulk) {
       log_info(biasedlocking)("  Revoked bias of anonymously-biased object");
     } else {
       log_trace(biasedlocking)("  Revoked bias of anonymously-biased object");
     }
-    return BIAS_REVOKED;
+    return;
   }
 
   // Handle case where the thread toward which the object was biased has exited
@@ -231,11 +227,7 @@
     thread_is_alive = tlh.includes(biased_thread);
   }
   if (!thread_is_alive) {
-    if (allow_rebias) {
-      obj->set_mark(biased_prototype);
-    } else {
-      obj->set_mark(unbiased_prototype);
-    }
+    obj->set_mark(unbiased_prototype);
     // Log at "info" level if not bulk, else "trace" level
     if (!is_bulk) {
       log_info(biasedlocking)("  Revoked bias of object biased toward dead thread ("
@@ -244,7 +236,7 @@
       log_trace(biasedlocking)("  Revoked bias of object biased toward dead thread ("
                                PTR_FORMAT ")", p2i(biased_thread));
     }
-    return BIAS_REVOKED;
+    return;
   }
 
   // Log at "info" level if not bulk, else "trace" level
@@ -301,20 +293,14 @@
     } else {
       log_trace(biasedlocking)("  Revoked bias of currently-unlocked object");
     }
-    if (allow_rebias) {
-      obj->set_mark(biased_prototype);
-    } else {
-      // Store the unlocked value into the object's header.
-      obj->set_mark(unbiased_prototype);
-    }
+    // Store the unlocked value into the object's header.
+    obj->set_mark(unbiased_prototype);
   }
 
   // If requested, return information on which thread held the bias
   if (biased_locker != NULL) {
     *biased_locker = biased_thread;
   }
-
-  return BIAS_REVOKED;
 }
 
 
@@ -379,10 +365,7 @@
 }
 
 
-BiasedLocking::Condition BiasedLocking::bulk_revoke_or_rebias_at_safepoint(oop o,
-                                                                   bool bulk_rebias,
-                                                                   bool attempt_rebias_of_object,
-                                                                   JavaThread* requesting_thread) {
+void BiasedLocking::bulk_revoke_at_safepoint(oop o, bool bulk_rebias, JavaThread* requesting_thread) {
   assert(SafepointSynchronize::is_at_safepoint(), "must be done at safepoint");
   assert(Thread::current()->is_VM_thread(), "must be VMThread");
 
@@ -437,7 +420,7 @@
 
       // At this point we're done. All we have to do is potentially
       // adjust the header of the given object to revoke its bias.
-      single_revoke_at_safepoint(o, attempt_rebias_of_object && klass->prototype_header().has_bias_pattern(), true, requesting_thread, NULL);
+      single_revoke_at_safepoint(o, true, requesting_thread, NULL);
     } else {
       if (log_is_enabled(Info, biasedlocking)) {
         ResourceMark rm;
@@ -459,36 +442,20 @@
           oop owner = mon_info->owner();
           markWord mark = owner->mark();
           if ((owner->klass() == k_o) && mark.has_bias_pattern()) {
-            single_revoke_at_safepoint(owner, false, true, requesting_thread, NULL);
+            single_revoke_at_safepoint(owner, true, requesting_thread, NULL);
           }
         }
       }
 
       // Must force the bias of the passed object to be forcibly revoked
       // as well to ensure guarantees to callers
-      single_revoke_at_safepoint(o, false, true, requesting_thread, NULL);
+      single_revoke_at_safepoint(o, true, requesting_thread, NULL);
     }
   } // ThreadsListHandle is destroyed here.
 
   log_info(biasedlocking)("* Ending bulk revocation");
 
-  BiasedLocking::Condition status_code = BIAS_REVOKED;
-
-  if (attempt_rebias_of_object &&
-      o->mark().has_bias_pattern() &&
-      klass->prototype_header().has_bias_pattern()) {
-    markWord new_mark = markWord::encode(requesting_thread, o->mark().age(),
-                                         klass->prototype_header().bias_epoch());
-    o->set_mark(new_mark);
-    status_code = BIAS_REVOKED_AND_REBIASED;
-    log_info(biasedlocking)("  Rebiased object toward thread " INTPTR_FORMAT, (intptr_t) requesting_thread);
-  }
-
-  assert(!o->mark().has_bias_pattern() ||
-         (attempt_rebias_of_object && (o->mark().biased_locker() == requesting_thread)),
-         "bug in bulk bias revocation");
-
-  return status_code;
+  assert(!o->mark().has_bias_pattern(), "bug in bulk bias revocation");
 }
 
 
@@ -509,25 +476,20 @@
   Handle* _obj;
   JavaThread* _requesting_thread;
   bool _bulk_rebias;
-  bool _attempt_rebias_of_object;
-  BiasedLocking::Condition _status_code;
   uint64_t _safepoint_id;
 
 public:
   VM_BulkRevokeBias(Handle* obj, JavaThread* requesting_thread,
-                    bool bulk_rebias,
-                    bool attempt_rebias_of_object)
+                    bool bulk_rebias)
     : _obj(obj)
     , _requesting_thread(requesting_thread)
     , _bulk_rebias(bulk_rebias)
-    , _attempt_rebias_of_object(attempt_rebias_of_object)
-    , _status_code(BiasedLocking::NOT_BIASED)
     , _safepoint_id(0) {}
 
   virtual VMOp_Type type() const { return VMOp_BulkRevokeBias; }
 
   virtual void doit() {
-    _status_code = BiasedLocking::bulk_revoke_or_rebias_at_safepoint((*_obj)(), _bulk_rebias, _attempt_rebias_of_object, _requesting_thread);
+    BiasedLocking::bulk_revoke_at_safepoint((*_obj)(), _bulk_rebias, _requesting_thread);
     _safepoint_id = SafepointSynchronize::safepoint_id();
     clean_up_cached_monitor_info();
   }
@@ -536,10 +498,6 @@
     return _bulk_rebias;
   }
 
-  BiasedLocking::Condition status_code() const {
-    return _status_code;
-  }
-
   uint64_t safepoint_id() const {
     return _safepoint_id;
   }
@@ -769,7 +727,7 @@
 }
 
 
-BiasedLocking::Condition BiasedLocking::revoke_and_rebias(Handle obj, bool attempt_rebias, TRAPS) {
+void BiasedLocking::revoke(Handle obj, TRAPS) {
   assert(!SafepointSynchronize::is_at_safepoint(), "must not be called while at safepoint");
 
   while (true) {
@@ -778,7 +736,12 @@
     // update the heuristics because doing so may cause unwanted bulk
     // revocations (which are expensive) to occur.
     markWord mark = obj->mark();
-    if (mark.is_biased_anonymously() && !attempt_rebias) {
+
+    if (!mark.has_bias_pattern()) {
+      return;
+    }
+
+    if (mark.is_biased_anonymously()) {
       // We are probably trying to revoke the bias of this object due to
       // an identity hash code computation. Try to revoke the bias
       // without a safepoint. This is possible if we can successfully
@@ -789,10 +752,10 @@
       markWord unbiased_prototype = markWord::prototype().set_age(mark.age());
       markWord res_mark = obj->cas_set_mark(unbiased_prototype, mark);
       if (res_mark == biased_value) {
-        return BIAS_REVOKED;
+        return;
       }
       mark = res_mark;  // Refresh mark with the latest value.
-    } else if (mark.has_bias_pattern()) {
+    } else {
       Klass* k = obj->klass();
       markWord prototype_header = k->prototype_header();
       if (!prototype_header.has_bias_pattern()) {
@@ -804,31 +767,20 @@
         // with it.
         obj->cas_set_mark(prototype_header.set_age(mark.age()), mark);
         assert(!obj->mark().has_bias_pattern(), "even if we raced, should still be revoked");
-        return BIAS_REVOKED;
+        return;
       } else if (prototype_header.bias_epoch() != mark.bias_epoch()) {
         // The epoch of this biasing has expired indicating that the
-        // object is effectively unbiased. Depending on whether we need
-        // to rebias or revoke the bias of this object we can do it
-        // efficiently enough with a CAS that we shouldn't update the
+        // object is effectively unbiased. We can revoke the bias of this
+        // object efficiently enough with a CAS that we shouldn't update the
         // heuristics. This is normally done in the assembly code but we
         // can reach this point due to various points in the runtime
         // needing to revoke biases.
         markWord res_mark;
-        if (attempt_rebias) {
-          assert(THREAD->is_Java_thread(), "");
-          markWord biased_value       = mark;
-          markWord rebiased_prototype = markWord::encode((JavaThread*) THREAD, mark.age(), prototype_header.bias_epoch());
-          res_mark = obj->cas_set_mark(rebiased_prototype, mark);
-          if (res_mark == biased_value) {
-            return BIAS_REVOKED_AND_REBIASED;
-          }
-        } else {
-          markWord biased_value       = mark;
-          markWord unbiased_prototype = markWord::prototype().set_age(mark.age());
-          res_mark = obj->cas_set_mark(unbiased_prototype, mark);
-          if (res_mark == biased_value) {
-            return BIAS_REVOKED;
-          }
+        markWord biased_value       = mark;
+        markWord unbiased_prototype = markWord::prototype().set_age(mark.age());
+        res_mark = obj->cas_set_mark(unbiased_prototype, mark);
+        if (res_mark == biased_value) {
+          return;
         }
         mark = res_mark;  // Refresh mark with the latest value.
       }
@@ -836,7 +788,7 @@
 
     HeuristicsResult heuristics = update_heuristics(obj());
     if (heuristics == HR_NOT_BIASED) {
-      return NOT_BIASED;
+      return;
     } else if (heuristics == HR_SINGLE_REVOKE) {
       JavaThread *blt = mark.biased_locker();
       assert(blt != NULL, "invariant");
@@ -855,11 +807,11 @@
         if (event.should_commit()) {
           post_self_revocation_event(&event, obj->klass());
         }
-        return BIAS_REVOKED;
+        return;
       } else {
         BiasedLocking::Condition cond = single_revoke_with_handshake(obj, (JavaThread*)THREAD, blt);
         if (cond != NOT_REVOKED) {
-          return cond;
+          return;
         }
       }
     } else {
@@ -867,13 +819,12 @@
          (heuristics == HR_BULK_REBIAS), "?");
       EventBiasedLockClassRevocation event;
       VM_BulkRevokeBias bulk_revoke(&obj, (JavaThread*)THREAD,
-                                    (heuristics == HR_BULK_REBIAS),
-                                    attempt_rebias);
+                                    (heuristics == HR_BULK_REBIAS));
       VMThread::execute(&bulk_revoke);
       if (event.should_commit()) {
         post_class_revocation_event(&event, obj->klass(), &bulk_revoke);
       }
-      return bulk_revoke.status_code();
+      return;
     }
   }
 }
@@ -901,13 +852,13 @@
   HeuristicsResult heuristics = update_heuristics(obj);
   if (heuristics == HR_SINGLE_REVOKE) {
     JavaThread* biased_locker = NULL;
-    single_revoke_at_safepoint(obj, false, false, NULL, &biased_locker);
+    single_revoke_at_safepoint(obj, false, NULL, &biased_locker);
     if (biased_locker) {
       clean_up_cached_monitor_info(biased_locker);
     }
   } else if ((heuristics == HR_BULK_REBIAS) ||
              (heuristics == HR_BULK_REVOKE)) {
-    bulk_revoke_or_rebias_at_safepoint(obj, (heuristics == HR_BULK_REBIAS), false, NULL);
+    bulk_revoke_at_safepoint(obj, (heuristics == HR_BULK_REBIAS), NULL);
     clean_up_cached_monitor_info();
   }
 }
@@ -920,10 +871,10 @@
     oop obj = (objs->at(i))();
     HeuristicsResult heuristics = update_heuristics(obj);
     if (heuristics == HR_SINGLE_REVOKE) {
-      single_revoke_at_safepoint(obj, false, false, NULL, NULL);
+      single_revoke_at_safepoint(obj, false, NULL, NULL);
     } else if ((heuristics == HR_BULK_REBIAS) ||
                (heuristics == HR_BULK_REVOKE)) {
-      bulk_revoke_or_rebias_at_safepoint(obj, (heuristics == HR_BULK_REBIAS), false, NULL);
+      bulk_revoke_at_safepoint(obj, (heuristics == HR_BULK_REBIAS), NULL);
     }
   }
   clean_up_cached_monitor_info();
--- a/src/hotspot/share/runtime/biasedLocking.hpp	Tue Aug 27 19:22:58 2019 +0200
+++ b/src/hotspot/share/runtime/biasedLocking.hpp	Tue Aug 27 20:10:06 2019 +0000
@@ -168,13 +168,12 @@
   enum Condition {
     NOT_BIASED = 1,
     BIAS_REVOKED = 2,
-    BIAS_REVOKED_AND_REBIASED = 3,
-    NOT_REVOKED = 4
+    NOT_REVOKED = 3
   };
 
 private:
-  static Condition single_revoke_at_safepoint(oop obj, bool allow_rebias, bool is_bulk, JavaThread* requester, JavaThread** biaser);
-  static Condition bulk_revoke_or_rebias_at_safepoint(oop o, bool bulk_rebias, bool attempt_rebias, JavaThread* requester);
+  static void single_revoke_at_safepoint(oop obj, bool is_bulk, JavaThread* requester, JavaThread** biaser);
+  static void bulk_revoke_at_safepoint(oop o, bool bulk_rebias, JavaThread* requester);
   static Condition single_revoke_with_handshake(Handle obj, JavaThread *requester, JavaThread *biaser);
   static void walk_stack_and_revoke(oop obj, JavaThread* biased_locker);
 
@@ -189,12 +188,13 @@
   static bool enabled();
 
   // This should be called by JavaThreads to revoke the bias of an object
-  static Condition revoke_and_rebias(Handle obj, bool attempt_rebias, TRAPS);
+  static void revoke(Handle obj, TRAPS);
+
+  static void revoke_at_safepoint(Handle obj);
 
-  // These do not allow rebiasing; they are used by deoptimization to
-  // ensure that monitors on the stack can be migrated
+  // These are used by deoptimization to ensure that monitors on the stack
+  // can be migrated
   static void revoke(GrowableArray<Handle>* objs, JavaThread *biaser);
-  static void revoke_at_safepoint(Handle obj);
   static void revoke_at_safepoint(GrowableArray<Handle>* objs);
 
   static void print_counters() { _counters.print(); }
--- a/src/hotspot/share/runtime/deoptimization.cpp	Tue Aug 27 19:22:58 2019 +0200
+++ b/src/hotspot/share/runtime/deoptimization.cpp	Tue Aug 27 20:10:06 2019 +0000
@@ -1264,7 +1264,7 @@
           obj->set_mark(unbiased_prototype);
         }
         BasicLock* lock = mon_info->lock();
-        ObjectSynchronizer::slow_enter(obj, lock, thread);
+        ObjectSynchronizer::enter(obj, lock, thread);
         assert(mon_info->owner()->is_locked(), "object must be locked now");
       }
     }
@@ -1374,7 +1374,7 @@
       for (int j = 0; j < monitors->number_of_monitors(); j++) {
         BasicObjectLock* src = monitors->at(j);
         if (src->obj() != NULL) {
-          ObjectSynchronizer::fast_exit(src->obj(), src->lock(), thread);
+          ObjectSynchronizer::exit(src->obj(), src->lock(), thread);
         }
       }
       array->element(i)->free_monitors(thread);
--- a/src/hotspot/share/runtime/sharedRuntime.cpp	Tue Aug 27 19:22:58 2019 +0200
+++ b/src/hotspot/share/runtime/sharedRuntime.cpp	Tue Aug 27 20:10:06 2019 +0000
@@ -2091,12 +2091,7 @@
     Atomic::inc(BiasedLocking::slow_path_entry_count_addr());
   }
   Handle h_obj(THREAD, obj);
-  if (UseBiasedLocking) {
-    // Retry fast entry if bias is revoked to avoid unnecessary inflation
-    ObjectSynchronizer::fast_enter(h_obj, lock, true, CHECK);
-  } else {
-    ObjectSynchronizer::slow_enter(h_obj, lock, CHECK);
-  }
+  ObjectSynchronizer::enter(h_obj, lock, CHECK);
   assert(!HAS_PENDING_EXCEPTION, "Should have no exception here");
   JRT_BLOCK_END
 JRT_END
@@ -2127,7 +2122,7 @@
   {
     // Exit must be non-blocking, and therefore no exceptions can be thrown.
     EXCEPTION_MARK;
-    ObjectSynchronizer::slow_exit(obj, lock, THREAD);
+    ObjectSynchronizer::exit(obj, lock, THREAD);
   }
 
 #ifdef MIGHT_HAVE_PENDING
--- a/src/hotspot/share/runtime/synchronizer.cpp	Tue Aug 27 19:22:58 2019 +0200
+++ b/src/hotspot/share/runtime/synchronizer.cpp	Tue Aug 27 20:10:06 2019 +0000
@@ -257,31 +257,48 @@
 }
 
 // -----------------------------------------------------------------------------
-//  Fast Monitor Enter/Exit
-// This the fast monitor enter. The interpreter and compiler use
-// some assembly copies of this code. Make sure update those code
-// if the following function is changed. The implementation is
-// extremely sensitive to race condition. Be careful.
+// Monitor Enter/Exit
+// The interpreter and compiler assembly code tries to lock using the fast path
+// of this algorithm. Make sure to update that code if the following function is
+// changed. The implementation is extremely sensitive to race condition. Be careful.
 
-void ObjectSynchronizer::fast_enter(Handle obj, BasicLock* lock,
-                                    bool attempt_rebias, TRAPS) {
+void ObjectSynchronizer::enter(Handle obj, BasicLock* lock, TRAPS) {
   if (UseBiasedLocking) {
     if (!SafepointSynchronize::is_at_safepoint()) {
-      BiasedLocking::Condition cond = BiasedLocking::revoke_and_rebias(obj, attempt_rebias, THREAD);
-      if (cond == BiasedLocking::BIAS_REVOKED_AND_REBIASED) {
-        return;
-      }
+      BiasedLocking::revoke(obj, THREAD);
     } else {
-      assert(!attempt_rebias, "can not rebias toward VM thread");
       BiasedLocking::revoke_at_safepoint(obj);
     }
-    assert(!obj->mark().has_bias_pattern(), "biases should be revoked by now");
   }
 
-  slow_enter(obj, lock, THREAD);
+  markWord 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
+    // be visible <= the ST performed by the CAS.
+    lock->set_displaced_header(mark);
+    if (mark == obj()->cas_set_mark(markWord::from_pointer(lock), mark)) {
+      return;
+    }
+    // Fall through to inflate() ...
+  } else if (mark.has_locker() &&
+             THREAD->is_lock_owned((address)mark.locker())) {
+    assert(lock != mark.locker(), "must not re-lock the same lock");
+    assert(lock != (BasicLock*)obj->mark().value(), "don't relock with same BasicLock");
+    lock->set_displaced_header(markWord::from_pointer(NULL));
+    return;
+  }
+
+  // The object header will never be displaced to this lock,
+  // so it does not matter what the value is, except that it
+  // must be non-zero to avoid looking like a re-entrant lock,
+  // and must not look locked either.
+  lock->set_displaced_header(markWord::unused_mark());
+  inflate(THREAD, obj(), inflate_cause_monitor_enter)->enter(THREAD);
 }
 
-void ObjectSynchronizer::fast_exit(oop object, BasicLock* lock, TRAPS) {
+void ObjectSynchronizer::exit(oop object, BasicLock* lock, TRAPS) {
   markWord mark = object->mark();
   // We cannot check for Biased Locking if we are racing an inflation.
   assert(mark == markWord::INFLATING() ||
@@ -331,47 +348,6 @@
 }
 
 // -----------------------------------------------------------------------------
-// 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) {
-  markWord 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
-    // be visible <= the ST performed by the CAS.
-    lock->set_displaced_header(mark);
-    if (mark == obj()->cas_set_mark(markWord::from_pointer(lock), mark)) {
-      return;
-    }
-    // Fall through to inflate() ...
-  } else if (mark.has_locker() &&
-             THREAD->is_lock_owned((address)mark.locker())) {
-    assert(lock != mark.locker(), "must not re-lock the same lock");
-    assert(lock != (BasicLock*)obj->mark().value(), "don't relock with same BasicLock");
-    lock->set_displaced_header(markWord::from_pointer(NULL));
-    return;
-  }
-
-  // The object header will never be displaced to this lock,
-  // so it does not matter what the value is, except that it
-  // must be non-zero to avoid looking like a re-entrant lock,
-  // and must not look locked either.
-  lock->set_displaced_header(markWord::unused_mark());
-  inflate(THREAD, obj(), inflate_cause_monitor_enter)->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
-// weight monitor should be ok, unless someone find otherwise.
-void ObjectSynchronizer::slow_exit(oop object, BasicLock* lock, TRAPS) {
-  fast_exit(object, lock, THREAD);
-}
-
-// -----------------------------------------------------------------------------
 // Class Loader  support to workaround deadlocks on the class loader lock objects
 // Also used by GC
 // complete_exit()/reenter() are used to wait on a nested lock
@@ -385,7 +361,7 @@
 // NOTE: must use heavy weight monitor to handle complete_exit/reenter()
 intptr_t ObjectSynchronizer::complete_exit(Handle obj, TRAPS) {
   if (UseBiasedLocking) {
-    BiasedLocking::revoke_and_rebias(obj, false, THREAD);
+    BiasedLocking::revoke(obj, THREAD);
     assert(!obj->mark().has_bias_pattern(), "biases should be revoked by now");
   }
 
@@ -397,7 +373,7 @@
 // NOTE: must use heavy weight monitor to handle complete_exit/reenter()
 void ObjectSynchronizer::reenter(Handle obj, intptr_t recursion, TRAPS) {
   if (UseBiasedLocking) {
-    BiasedLocking::revoke_and_rebias(obj, false, THREAD);
+    BiasedLocking::revoke(obj, THREAD);
     assert(!obj->mark().has_bias_pattern(), "biases should be revoked by now");
   }
 
@@ -411,7 +387,7 @@
 void ObjectSynchronizer::jni_enter(Handle obj, TRAPS) {
   // the current locking is from JNI instead of Java code
   if (UseBiasedLocking) {
-    BiasedLocking::revoke_and_rebias(obj, false, THREAD);
+    BiasedLocking::revoke(obj, THREAD);
     assert(!obj->mark().has_bias_pattern(), "biases should be revoked by now");
   }
   THREAD->set_current_pending_monitor_is_from_java(false);
@@ -423,7 +399,7 @@
 void ObjectSynchronizer::jni_exit(oop obj, Thread* THREAD) {
   if (UseBiasedLocking) {
     Handle h_obj(THREAD, obj);
-    BiasedLocking::revoke_and_rebias(h_obj, false, THREAD);
+    BiasedLocking::revoke(h_obj, THREAD);
     obj = h_obj();
   }
   assert(!obj->mark().has_bias_pattern(), "biases should be revoked by now");
@@ -447,13 +423,13 @@
   _obj = obj;
 
   if (_dolock) {
-    ObjectSynchronizer::fast_enter(_obj, &_lock, false, _thread);
+    ObjectSynchronizer::enter(_obj, &_lock, _thread);
   }
 }
 
 ObjectLocker::~ObjectLocker() {
   if (_dolock) {
-    ObjectSynchronizer::fast_exit(_obj(), &_lock, _thread);
+    ObjectSynchronizer::exit(_obj(), &_lock, _thread);
   }
 }
 
@@ -463,7 +439,7 @@
 // NOTE: must use heavy weight monitor to handle wait()
 int ObjectSynchronizer::wait(Handle obj, jlong millis, TRAPS) {
   if (UseBiasedLocking) {
-    BiasedLocking::revoke_and_rebias(obj, false, THREAD);
+    BiasedLocking::revoke(obj, THREAD);
     assert(!obj->mark().has_bias_pattern(), "biases should be revoked by now");
   }
   if (millis < 0) {
@@ -483,7 +459,7 @@
 
 void ObjectSynchronizer::waitUninterruptibly(Handle obj, jlong millis, TRAPS) {
   if (UseBiasedLocking) {
-    BiasedLocking::revoke_and_rebias(obj, false, THREAD);
+    BiasedLocking::revoke(obj, THREAD);
     assert(!obj->mark().has_bias_pattern(), "biases should be revoked by now");
   }
   if (millis < 0) {
@@ -494,7 +470,7 @@
 
 void ObjectSynchronizer::notify(Handle obj, TRAPS) {
   if (UseBiasedLocking) {
-    BiasedLocking::revoke_and_rebias(obj, false, THREAD);
+    BiasedLocking::revoke(obj, THREAD);
     assert(!obj->mark().has_bias_pattern(), "biases should be revoked by now");
   }
 
@@ -508,7 +484,7 @@
 // NOTE: see comment of notify()
 void ObjectSynchronizer::notifyall(Handle obj, TRAPS) {
   if (UseBiasedLocking) {
-    BiasedLocking::revoke_and_rebias(obj, false, THREAD);
+    BiasedLocking::revoke(obj, THREAD);
     assert(!obj->mark().has_bias_pattern(), "biases should be revoked by now");
   }
 
@@ -695,7 +671,7 @@
       assert(Universe::verify_in_progress() ||
              !SafepointSynchronize::is_at_safepoint(),
              "biases should not be seen by VM thread here");
-      BiasedLocking::revoke_and_rebias(hobj, false, JavaThread::current());
+      BiasedLocking::revoke(hobj, JavaThread::current());
       obj = hobj();
       assert(!obj->mark().has_bias_pattern(), "biases should be revoked by now");
     }
@@ -794,7 +770,7 @@
 bool ObjectSynchronizer::current_thread_holds_lock(JavaThread* thread,
                                                    Handle h_obj) {
   if (UseBiasedLocking) {
-    BiasedLocking::revoke_and_rebias(h_obj, false, thread);
+    BiasedLocking::revoke(h_obj, thread);
     assert(!h_obj->mark().has_bias_pattern(), "biases should be revoked by now");
   }
 
@@ -833,7 +809,7 @@
 
   if (UseBiasedLocking && h_obj()->mark().has_bias_pattern()) {
     // CASE: biased
-    BiasedLocking::revoke_and_rebias(h_obj, false, self);
+    BiasedLocking::revoke(h_obj, self);
     assert(!h_obj->mark().has_bias_pattern(),
            "biases should be revoked by now");
   }
@@ -869,7 +845,7 @@
     if (SafepointSynchronize::is_at_safepoint()) {
       BiasedLocking::revoke_at_safepoint(h_obj);
     } else {
-      BiasedLocking::revoke_and_rebias(h_obj, false, JavaThread::current());
+      BiasedLocking::revoke(h_obj, JavaThread::current());
     }
     assert(!h_obj->mark().has_bias_pattern(), "biases should be revoked by now");
   }
@@ -1463,8 +1439,7 @@
     // CAS inflates the object *and* confers ownership to the inflating thread.
     // In the current implementation we use a 2-step mechanism where we CAS()
     // to inflate and then CAS() again to try to swing _owner from NULL to Self.
-    // An inflateTry() method that we could call from fast_enter() and slow_enter()
-    // would be useful.
+    // An inflateTry() method that we could call from enter() would be useful.
 
     // Catch if the object's header is not neutral (not locked and
     // not marked is what we care about here).
--- a/src/hotspot/share/runtime/synchronizer.hpp	Tue Aug 27 19:22:58 2019 +0200
+++ b/src/hotspot/share/runtime/synchronizer.hpp	Tue Aug 27 20:10:06 2019 +0000
@@ -65,22 +65,9 @@
   // exit must be implemented non-blocking, since the compiler cannot easily handle
   // deoptimization at monitor exit. Hence, it does not take a Handle argument.
 
-  // This is full version of monitor enter and exit. I choose not
-  // to use enter() and exit() in order to make sure user be ware
-  // of the performance and semantics difference. They are normally
-  // used by ObjectLocker etc. The interpreter and compiler use
-  // assembly copies of these routines. Please keep them synchronized.
-  //
-  // attempt_rebias flag is used by UseBiasedLocking implementation
-  static void fast_enter(Handle obj, BasicLock* lock, bool attempt_rebias,
-                         TRAPS);
-  static void fast_exit(oop obj, BasicLock* lock, Thread* THREAD);
-
-  // WARNING: They are ONLY used to handle the slow cases. They should
-  // only be used when the fast cases failed. Use of these functions
-  // without previous fast case check may cause fatal error.
-  static void slow_enter(Handle obj, BasicLock* lock, TRAPS);
-  static void slow_exit(oop obj, BasicLock* lock, Thread* THREAD);
+  // This is the "slow path" version of monitor enter and exit.
+  static void enter(Handle obj, BasicLock* lock, TRAPS);
+  static void exit(oop obj, BasicLock* lock, Thread* THREAD);
 
   // Used only to handle jni locks or other unmatched monitor enter/exit
   // Internally they will use heavy weight monitor.
--- a/test/hotspot/gtest/oops/test_markOop.cpp	Tue Aug 27 19:22:58 2019 +0200
+++ b/test/hotspot/gtest/oops/test_markOop.cpp	Tue Aug 27 20:10:06 2019 +0000
@@ -98,9 +98,10 @@
   // Lock using biased locking.
   BasicObjectLock lock;
   lock.set_obj(obj);
-  markWord mark = obj->mark().incr_bias_epoch();
-  obj->set_mark(mark);
-  ObjectSynchronizer::fast_enter(h_obj, lock.lock(), true, THREAD);
+  markWord prototype_header = obj->klass()->prototype_header();
+  markWord mark = obj->mark();
+  markWord biased_mark = markWord::encode((JavaThread*) THREAD, mark.age(), prototype_header.bias_epoch());
+  obj->set_mark(biased_mark);
   // Look for the biased_locker in markWord, not prototype_header.
 #ifdef _LP64
   assert_not_test_pattern(h_obj, "mark(is_biased biased_locker=0x0000000000000000");