src/hotspot/share/runtime/objectMonitor.cpp
changeset 51860 54aafb3ba9ab
parent 51704 2368e8e9cec6
child 51960 bb1d5dd64897
--- a/src/hotspot/share/runtime/objectMonitor.cpp	Tue Sep 25 11:24:59 2018 +0800
+++ b/src/hotspot/share/runtime/objectMonitor.cpp	Mon Sep 24 22:12:07 2018 -0700
@@ -101,39 +101,15 @@
 // The knob* variables are effectively final.  Once set they should
 // never be modified hence.  Consider using __read_mostly with GCC.
 
-int ObjectMonitor::Knob_ExitRelease  = 0;
-int ObjectMonitor::Knob_InlineNotify = 1;
-int ObjectMonitor::Knob_Verbose      = 0;
-int ObjectMonitor::Knob_VerifyInUse  = 0;
-int ObjectMonitor::Knob_VerifyMatch  = 0;
 int ObjectMonitor::Knob_SpinLimit    = 5000;    // derived by an external tool -
 
-static int Knob_ReportSettings      = 0;
-static int Knob_SpinBase            = 0;       // Floor AKA SpinMin
-static int Knob_SpinBackOff         = 0;       // spin-loop backoff
-static int Knob_CASPenalty          = -1;      // Penalty for failed CAS
-static int Knob_OXPenalty           = -1;      // Penalty for observed _owner change
-static int Knob_SpinSetSucc         = 1;       // spinners set the _succ field
-static int Knob_SpinEarly           = 1;
-static int Knob_SuccEnabled         = 1;       // futile wake throttling
-static int Knob_SuccRestrict        = 0;       // Limit successors + spinners to at-most-one
-static int Knob_MaxSpinners         = -1;      // Should be a function of # CPUs
 static int Knob_Bonus               = 100;     // spin success bonus
 static int Knob_BonusB              = 100;     // spin success bonus
 static int Knob_Penalty             = 200;     // spin failure penalty
 static int Knob_Poverty             = 1000;
-static int Knob_SpinAfterFutile     = 1;       // Spin after returning from park()
 static int Knob_FixedSpin           = 0;
-static int Knob_OState              = 3;       // Spinner checks thread state of _owner
-static int Knob_UsePause            = 1;
-static int Knob_ExitPolicy          = 0;
 static int Knob_PreSpin             = 10;      // 20-100 likely better
-static int Knob_ResetEvent          = 0;
-static int BackOffMask              = 0;
 
-static int Knob_FastHSSEC           = 0;
-static int Knob_MoveNotifyee        = 2;       // notify() - disposition of notifyee
-static int Knob_QMode               = 0;       // EntryList-cxq policy - queue discipline
 static volatile int InitDone        = 0;
 
 // -----------------------------------------------------------------------------
@@ -299,7 +275,7 @@
   // transitions.  The following spin is strictly optional ...
   // Note that if we acquire the monitor from an initial spin
   // we forgo posting JVMTI events and firing DTRACE probes.
-  if (Knob_SpinEarly && TrySpin (Self) > 0) {
+  if (TrySpin(Self) > 0) {
     assert(_owner == Self, "invariant");
     assert(_recursions == 0, "invariant");
     assert(((oop)(object()))->mark() == markOopDesc::encode(this), "invariant");
@@ -461,7 +437,7 @@
   // to the owner.  This has subtle but beneficial affinity
   // effects.
 
-  if (TrySpin (Self) > 0) {
+  if (TrySpin(Self) > 0) {
     assert(_owner == Self, "invariant");
     assert(_succ != Self, "invariant");
     assert(_Responsible != Self, "invariant");
@@ -583,20 +559,14 @@
     // We can defer clearing _succ until after the spin completes
     // TrySpin() must tolerate being called with _succ == Self.
     // Try yet another round of adaptive spinning.
-    if ((Knob_SpinAfterFutile & 1) && TrySpin(Self) > 0) break;
+    if (TrySpin(Self) > 0) break;
 
     // We can find that we were unpark()ed and redesignated _succ while
     // we were spinning.  That's harmless.  If we iterate and call park(),
     // park() will consume the event and return immediately and we'll
     // just spin again.  This pattern can repeat, leaving _succ to simply
-    // spin on a CPU.  Enable Knob_ResetEvent to clear pending unparks().
-    // Alternately, we can sample fired() here, and if set, forgo spinning
-    // in the next iteration.
+    // spin on a CPU.
 
-    if ((Knob_ResetEvent & 1) && Self->_ParkEvent->fired()) {
-      Self->_ParkEvent->reset();
-      OrderAccess::fence();
-    }
     if (_succ == Self) _succ = NULL;
 
     // Invariant: after clearing _succ a thread *must* retry _owner before parking.
@@ -675,9 +645,7 @@
 // contended slow-path from EnterI().  We use ReenterI() only for
 // monitor reentry in wait().
 //
-// In the future we should reconcile EnterI() and ReenterI(), adding
-// Knob_Reset and Knob_SpinAfterFutile support and restructuring the
-// loop accordingly.
+// In the future we should reconcile EnterI() and ReenterI().
 
 void ObjectMonitor::ReenterI(Thread * Self, ObjectWaiter * SelfNode) {
   assert(Self != NULL, "invariant");
@@ -929,181 +897,60 @@
   for (;;) {
     assert(THREAD == _owner, "invariant");
 
-    if (Knob_ExitPolicy == 0) {
-      // release semantics: prior loads and stores from within the critical section
-      // must not float (reorder) past the following store that drops the lock.
-      // On SPARC that requires MEMBAR #loadstore|#storestore.
-      // But of course in TSO #loadstore|#storestore is not required.
-      // I'd like to write one of the following:
-      // A.  OrderAccess::release() ; _owner = NULL
-      // B.  OrderAccess::loadstore(); OrderAccess::storestore(); _owner = NULL;
-      // Unfortunately OrderAccess::release() and OrderAccess::loadstore() both
-      // store into a _dummy variable.  That store is not needed, but can result
-      // in massive wasteful coherency traffic on classic SMP systems.
-      // Instead, I use release_store(), which is implemented as just a simple
-      // ST on x64, x86 and SPARC.
-      OrderAccess::release_store(&_owner, (void*)NULL);   // drop the lock
-      OrderAccess::storeload();                        // See if we need to wake a successor
-      if ((intptr_t(_EntryList)|intptr_t(_cxq)) == 0 || _succ != NULL) {
-        return;
-      }
-      // Other threads are blocked trying to acquire the lock.
+    // release semantics: prior loads and stores from within the critical section
+    // must not float (reorder) past the following store that drops the lock.
+    // On SPARC that requires MEMBAR #loadstore|#storestore.
+    // But of course in TSO #loadstore|#storestore is not required.
+    OrderAccess::release_store(&_owner, (void*)NULL);   // drop the lock
+    OrderAccess::storeload();                        // See if we need to wake a successor
+    if ((intptr_t(_EntryList)|intptr_t(_cxq)) == 0 || _succ != NULL) {
+      return;
+    }
+    // Other threads are blocked trying to acquire the lock.
 
-      // Normally the exiting thread is responsible for ensuring succession,
-      // but if other successors are ready or other entering threads are spinning
-      // then this thread can simply store NULL into _owner and exit without
-      // waking a successor.  The existence of spinners or ready successors
-      // guarantees proper succession (liveness).  Responsibility passes to the
-      // ready or running successors.  The exiting thread delegates the duty.
-      // More precisely, if a successor already exists this thread is absolved
-      // of the responsibility of waking (unparking) one.
-      //
-      // The _succ variable is critical to reducing futile wakeup frequency.
-      // _succ identifies the "heir presumptive" thread that has been made
-      // ready (unparked) but that has not yet run.  We need only one such
-      // successor thread to guarantee progress.
-      // See http://www.usenix.org/events/jvm01/full_papers/dice/dice.pdf
-      // section 3.3 "Futile Wakeup Throttling" for details.
-      //
-      // Note that spinners in Enter() also set _succ non-null.
-      // In the current implementation spinners opportunistically set
-      // _succ so that exiting threads might avoid waking a successor.
-      // Another less appealing alternative would be for the exiting thread
-      // to drop the lock and then spin briefly to see if a spinner managed
-      // to acquire the lock.  If so, the exiting thread could exit
-      // immediately without waking a successor, otherwise the exiting
-      // thread would need to dequeue and wake a successor.
-      // (Note that we'd need to make the post-drop spin short, but no
-      // shorter than the worst-case round-trip cache-line migration time.
-      // The dropped lock needs to become visible to the spinner, and then
-      // the acquisition of the lock by the spinner must become visible to
-      // the exiting thread).
+    // Normally the exiting thread is responsible for ensuring succession,
+    // but if other successors are ready or other entering threads are spinning
+    // then this thread can simply store NULL into _owner and exit without
+    // waking a successor.  The existence of spinners or ready successors
+    // guarantees proper succession (liveness).  Responsibility passes to the
+    // ready or running successors.  The exiting thread delegates the duty.
+    // More precisely, if a successor already exists this thread is absolved
+    // of the responsibility of waking (unparking) one.
+    //
+    // The _succ variable is critical to reducing futile wakeup frequency.
+    // _succ identifies the "heir presumptive" thread that has been made
+    // ready (unparked) but that has not yet run.  We need only one such
+    // successor thread to guarantee progress.
+    // See http://www.usenix.org/events/jvm01/full_papers/dice/dice.pdf
+    // section 3.3 "Futile Wakeup Throttling" for details.
+    //
+    // Note that spinners in Enter() also set _succ non-null.
+    // In the current implementation spinners opportunistically set
+    // _succ so that exiting threads might avoid waking a successor.
+    // Another less appealing alternative would be for the exiting thread
+    // to drop the lock and then spin briefly to see if a spinner managed
+    // to acquire the lock.  If so, the exiting thread could exit
+    // immediately without waking a successor, otherwise the exiting
+    // thread would need to dequeue and wake a successor.
+    // (Note that we'd need to make the post-drop spin short, but no
+    // shorter than the worst-case round-trip cache-line migration time.
+    // The dropped lock needs to become visible to the spinner, and then
+    // the acquisition of the lock by the spinner must become visible to
+    // the exiting thread).
 
-      // It appears that an heir-presumptive (successor) must be made ready.
-      // Only the current lock owner can manipulate the EntryList or
-      // drain _cxq, so we need to reacquire the lock.  If we fail
-      // to reacquire the lock the responsibility for ensuring succession
-      // falls to the new owner.
-      //
-      if (!Atomic::replace_if_null(THREAD, &_owner)) {
-        return;
-      }
-    } else {
-      if ((intptr_t(_EntryList)|intptr_t(_cxq)) == 0 || _succ != NULL) {
-        OrderAccess::release_store(&_owner, (void*)NULL);   // drop the lock
-        OrderAccess::storeload();
-        // Ratify the previously observed values.
-        if (_cxq == NULL || _succ != NULL) {
-          return;
-        }
-
-        // inopportune interleaving -- the exiting thread (this thread)
-        // in the fast-exit path raced an entering thread in the slow-enter
-        // path.
-        // We have two choices:
-        // A.  Try to reacquire the lock.
-        //     If the CAS() fails return immediately, otherwise
-        //     we either restart/rerun the exit operation, or simply
-        //     fall-through into the code below which wakes a successor.
-        // B.  If the elements forming the EntryList|cxq are TSM
-        //     we could simply unpark() the lead thread and return
-        //     without having set _succ.
-        if (!Atomic::replace_if_null(THREAD, &_owner)) {
-          return;
-        }
-      }
+    // It appears that an heir-presumptive (successor) must be made ready.
+    // Only the current lock owner can manipulate the EntryList or
+    // drain _cxq, so we need to reacquire the lock.  If we fail
+    // to reacquire the lock the responsibility for ensuring succession
+    // falls to the new owner.
+    //
+    if (!Atomic::replace_if_null(THREAD, &_owner)) {
+      return;
     }
 
     guarantee(_owner == THREAD, "invariant");
 
     ObjectWaiter * w = NULL;
-    int QMode = Knob_QMode;
-
-    if (QMode == 2 && _cxq != NULL) {
-      // QMode == 2 : cxq has precedence over EntryList.
-      // Try to directly wake a successor from the cxq.
-      // If successful, the successor will need to unlink itself from cxq.
-      w = _cxq;
-      assert(w != NULL, "invariant");
-      assert(w->TState == ObjectWaiter::TS_CXQ, "Invariant");
-      ExitEpilog(Self, w);
-      return;
-    }
-
-    if (QMode == 3 && _cxq != NULL) {
-      // Aggressively drain cxq into EntryList at the first opportunity.
-      // This policy ensure that recently-run threads live at the head of EntryList.
-      // Drain _cxq into EntryList - bulk transfer.
-      // First, detach _cxq.
-      // The following loop is tantamount to: w = swap(&cxq, NULL)
-      w = _cxq;
-      for (;;) {
-        assert(w != NULL, "Invariant");
-        ObjectWaiter * u = Atomic::cmpxchg((ObjectWaiter*)NULL, &_cxq, w);
-        if (u == w) break;
-        w = u;
-      }
-      assert(w != NULL, "invariant");
-
-      ObjectWaiter * q = NULL;
-      ObjectWaiter * p;
-      for (p = w; p != NULL; p = p->_next) {
-        guarantee(p->TState == ObjectWaiter::TS_CXQ, "Invariant");
-        p->TState = ObjectWaiter::TS_ENTER;
-        p->_prev = q;
-        q = p;
-      }
-
-      // Append the RATs to the EntryList
-      // TODO: organize EntryList as a CDLL so we can locate the tail in constant-time.
-      ObjectWaiter * Tail;
-      for (Tail = _EntryList; Tail != NULL && Tail->_next != NULL;
-           Tail = Tail->_next)
-        /* empty */;
-      if (Tail == NULL) {
-        _EntryList = w;
-      } else {
-        Tail->_next = w;
-        w->_prev = Tail;
-      }
-
-      // Fall thru into code that tries to wake a successor from EntryList
-    }
-
-    if (QMode == 4 && _cxq != NULL) {
-      // Aggressively drain cxq into EntryList at the first opportunity.
-      // This policy ensure that recently-run threads live at the head of EntryList.
-
-      // Drain _cxq into EntryList - bulk transfer.
-      // First, detach _cxq.
-      // The following loop is tantamount to: w = swap(&cxq, NULL)
-      w = _cxq;
-      for (;;) {
-        assert(w != NULL, "Invariant");
-        ObjectWaiter * u = Atomic::cmpxchg((ObjectWaiter*)NULL, &_cxq, w);
-        if (u == w) break;
-        w = u;
-      }
-      assert(w != NULL, "invariant");
-
-      ObjectWaiter * q = NULL;
-      ObjectWaiter * p;
-      for (p = w; p != NULL; p = p->_next) {
-        guarantee(p->TState == ObjectWaiter::TS_CXQ, "Invariant");
-        p->TState = ObjectWaiter::TS_ENTER;
-        p->_prev = q;
-        q = p;
-      }
-
-      // Prepend the RATs to the EntryList
-      if (_EntryList != NULL) {
-        q->_next = _EntryList;
-        _EntryList->_prev = q;
-      }
-      _EntryList = w;
-
-      // Fall thru into code that tries to wake a successor from EntryList
-    }
 
     w = _EntryList;
     if (w != NULL) {
@@ -1150,34 +997,14 @@
     // TODO-FIXME: consider changing EntryList from a DLL to a CDLL so
     // we have faster access to the tail.
 
-    if (QMode == 1) {
-      // QMode == 1 : drain cxq to EntryList, reversing order
-      // We also reverse the order of the list.
-      ObjectWaiter * s = NULL;
-      ObjectWaiter * t = w;
-      ObjectWaiter * u = NULL;
-      while (t != NULL) {
-        guarantee(t->TState == ObjectWaiter::TS_CXQ, "invariant");
-        t->TState = ObjectWaiter::TS_ENTER;
-        u = t->_next;
-        t->_prev = u;
-        t->_next = s;
-        s = t;
-        t = u;
-      }
-      _EntryList  = s;
-      assert(s != NULL, "invariant");
-    } else {
-      // QMode == 0 or QMode == 2
-      _EntryList = w;
-      ObjectWaiter * q = NULL;
-      ObjectWaiter * p;
-      for (p = w; p != NULL; p = p->_next) {
-        guarantee(p->TState == ObjectWaiter::TS_CXQ, "Invariant");
-        p->TState = ObjectWaiter::TS_ENTER;
-        p->_prev = q;
-        q = p;
-      }
+    _EntryList = w;
+    ObjectWaiter * q = NULL;
+    ObjectWaiter * p;
+    for (p = w; p != NULL; p = p->_next) {
+      guarantee(p->TState == ObjectWaiter::TS_CXQ, "Invariant");
+      p->TState = ObjectWaiter::TS_ENTER;
+      p->_prev = q;
+      q = p;
     }
 
     // In 1-0 mode we need: ST EntryList; MEMBAR #storestore; ST _owner = NULL
@@ -1226,22 +1053,8 @@
 //       ST Self->_suspend_equivalent = false
 //       MEMBAR
 //       LD Self_>_suspend_flags
-//
-// UPDATE 2007-10-6: since I've replaced the native Mutex/Monitor subsystem
-// with a more efficient implementation, the need to use "FastHSSEC" has
-// decreased. - Dave
-
 
 bool ObjectMonitor::ExitSuspendEquivalent(JavaThread * jSelf) {
-  const int Mode = Knob_FastHSSEC;
-  if (Mode && !jSelf->is_external_suspend()) {
-    assert(jSelf->is_suspend_equivalent(), "invariant");
-    jSelf->clear_suspend_equivalent();
-    if (2 == Mode) OrderAccess::storeload();
-    if (!jSelf->is_external_suspend()) return false;
-    // We raced a suspension -- fall thru into the slow path
-    jSelf->set_suspend_equivalent();
-  }
   return jSelf->handle_special_suspend_equivalent_condition();
 }
 
@@ -1255,7 +1068,7 @@
   // 2. ST _owner = NULL
   // 3. unpark(wakee)
 
-  _succ = Knob_SuccEnabled ? Wakee->_thread : NULL;
+  _succ = Wakee->_thread;
   ParkEvent * Trigger = Wakee->_event;
 
   // Hygiene -- once we've set _owner = NULL we can't safely dereference Wakee again.
@@ -1348,12 +1161,6 @@
   THROW_MSG(vmSymbols::java_lang_IllegalMonitorStateException(), "current thread not owner");
 }
 
-static int Adjust(volatile int * adr, int dx) {
-  int v;
-  for (v = *adr; Atomic::cmpxchg(v + dx, adr, v) != v; v = *adr) /* empty */;
-  return v;
-}
-
 static void post_monitor_wait_event(EventJavaMonitorWait* event,
                                     ObjectMonitor* monitor,
                                     jlong notifier_tid,
@@ -1599,8 +1406,6 @@
 // we might just dequeue a thread from the WaitSet and directly unpark() it.
 
 void ObjectMonitor::INotify(Thread * Self) {
-  const int policy = Knob_MoveNotifyee;
-
   Thread::SpinAcquire(&_WaitSetLock, "WaitSet - notify");
   ObjectWaiter * iterator = DequeueWaiter();
   if (iterator != NULL) {
@@ -1611,9 +1416,9 @@
     //     or head (policy == 0).
     // b.  push it onto the front of the _cxq (policy == 2).
     // For now we use (b).
-    if (policy != 4) {
-      iterator->TState = ObjectWaiter::TS_ENTER;
-    }
+
+    iterator->TState = ObjectWaiter::TS_ENTER;
+
     iterator->_notified = 1;
     iterator->_notifier_tid = JFR_THREAD_ID(Self);
 
@@ -1624,67 +1429,19 @@
       assert(list != iterator, "invariant");
     }
 
-    if (policy == 0) {       // prepend to EntryList
-      if (list == NULL) {
-        iterator->_next = iterator->_prev = NULL;
-        _EntryList = iterator;
-      } else {
-        list->_prev = iterator;
-        iterator->_next = list;
-        iterator->_prev = NULL;
-        _EntryList = iterator;
-      }
-    } else if (policy == 1) {      // append to EntryList
-      if (list == NULL) {
-        iterator->_next = iterator->_prev = NULL;
-        _EntryList = iterator;
-      } else {
-        // CONSIDER:  finding the tail currently requires a linear-time walk of
-        // the EntryList.  We can make tail access constant-time by converting to
-        // a CDLL instead of using our current DLL.
-        ObjectWaiter * tail;
-        for (tail = list; tail->_next != NULL; tail = tail->_next) {}
-        assert(tail != NULL && tail->_next == NULL, "invariant");
-        tail->_next = iterator;
-        iterator->_prev = tail;
-        iterator->_next = NULL;
-      }
-    } else if (policy == 2) {      // prepend to cxq
-      if (list == NULL) {
-        iterator->_next = iterator->_prev = NULL;
-        _EntryList = iterator;
-      } else {
-        iterator->TState = ObjectWaiter::TS_CXQ;
-        for (;;) {
-          ObjectWaiter * front = _cxq;
-          iterator->_next = front;
-          if (Atomic::cmpxchg(iterator, &_cxq, front) == front) {
-            break;
-          }
-        }
-      }
-    } else if (policy == 3) {      // append to cxq
+    // prepend to cxq
+    if (list == NULL) {
+      iterator->_next = iterator->_prev = NULL;
+      _EntryList = iterator;
+    } else {
       iterator->TState = ObjectWaiter::TS_CXQ;
       for (;;) {
-        ObjectWaiter * tail = _cxq;
-        if (tail == NULL) {
-          iterator->_next = NULL;
-          if (Atomic::replace_if_null(iterator, &_cxq)) {
-            break;
-          }
-        } else {
-          while (tail->_next != NULL) tail = tail->_next;
-          tail->_next = iterator;
-          iterator->_prev = tail;
-          iterator->_next = NULL;
+        ObjectWaiter * front = _cxq;
+        iterator->_next = front;
+        if (Atomic::cmpxchg(iterator, &_cxq, front) == front) {
           break;
         }
       }
-    } else {
-      ParkEvent * ev = iterator->_event;
-      iterator->TState = ObjectWaiter::TS_RUN;
-      OrderAccess::fence();
-      ev->unpark();
     }
 
     // _WaitSetLock protects the wait queue, not the EntryList.  We could
@@ -1695,9 +1452,7 @@
     // on _WaitSetLock so it's not profitable to reduce the length of the
     // critical section.
 
-    if (policy < 4) {
-      iterator->wait_reenter_begin(this);
-    }
+    iterator->wait_reenter_begin(this);
   }
   Thread::SpinRelease(&_WaitSetLock);
 }
@@ -1854,33 +1609,19 @@
   // hold the duration constant but vary the frequency.
 
   ctr = _SpinDuration;
-  if (ctr < Knob_SpinBase) ctr = Knob_SpinBase;
   if (ctr <= 0) return 0;
 
-  if (Knob_SuccRestrict && _succ != NULL) return 0;
-  if (Knob_OState && NotRunnable (Self, (Thread *) _owner)) {
+  if (NotRunnable(Self, (Thread *) _owner)) {
     return 0;
   }
 
-  int MaxSpin = Knob_MaxSpinners;
-  if (MaxSpin >= 0) {
-    if (_Spinner > MaxSpin) {
-      return 0;
-    }
-    // Slightly racy, but benign ...
-    Adjust(&_Spinner, 1);
-  }
-
   // We're good to spin ... spin ingress.
   // CONSIDER: use Prefetch::write() to avoid RTS->RTO upgrades
   // when preparing to LD...CAS _owner, etc and the CAS is likely
   // to succeed.
-  int hits    = 0;
-  int msk     = 0;
-  int caspty  = Knob_CASPenalty;
-  int oxpty   = Knob_OXPenalty;
-  int sss     = Knob_SpinSetSucc;
-  if (sss && _succ == NULL) _succ = Self;
+  if (_succ == NULL) {
+    _succ = Self;
+  }
   Thread * prv = NULL;
 
   // There are three ways to exit the following loop:
@@ -1903,32 +1644,7 @@
       if (SafepointMechanism::poll(Self)) {
         goto Abort;           // abrupt spin egress
       }
-      if (Knob_UsePause & 1) SpinPause();
-    }
-
-    if (Knob_UsePause & 2) SpinPause();
-
-    // Exponential back-off ...  Stay off the bus to reduce coherency traffic.
-    // This is useful on classic SMP systems, but is of less utility on
-    // N1-style CMT platforms.
-    //
-    // Trade-off: lock acquisition latency vs coherency bandwidth.
-    // Lock hold times are typically short.  A histogram
-    // of successful spin attempts shows that we usually acquire
-    // the lock early in the spin.  That suggests we want to
-    // sample _owner frequently in the early phase of the spin,
-    // but then back-off and sample less frequently as the spin
-    // progresses.  The back-off makes a good citizen on SMP big
-    // SMP systems.  Oversampling _owner can consume excessive
-    // coherency bandwidth.  Relatedly, if we _oversample _owner we
-    // can inadvertently interfere with the the ST m->owner=null.
-    // executed by the lock owner.
-    if (ctr & msk) continue;
-    ++hits;
-    if ((hits & 0xF) == 0) {
-      // The 0xF, above, corresponds to the exponent.
-      // Consider: (msk+1)|msk
-      msk = ((msk << 2)|3) & BackOffMask;
+      SpinPause();
     }
 
     // Probe _owner with TATAS
@@ -1947,10 +1663,9 @@
       if (ox == NULL) {
         // The CAS succeeded -- this thread acquired ownership
         // Take care of some bookkeeping to exit spin state.
-        if (sss && _succ == Self) {
+        if (_succ == Self) {
           _succ = NULL;
         }
-        if (MaxSpin > 0) Adjust(&_Spinner, -1);
 
         // Increase _SpinDuration :
         // The spin was successful (profitable) so we tend toward
@@ -1968,22 +1683,17 @@
       }
 
       // The CAS failed ... we can take any of the following actions:
-      // * penalize: ctr -= Knob_CASPenalty
+      // * penalize: ctr -= CASPenalty
       // * exit spin with prejudice -- goto Abort;
       // * exit spin without prejudice.
       // * Since CAS is high-latency, retry again immediately.
       prv = ox;
-      if (caspty == -2) break;
-      if (caspty == -1) goto Abort;
-      ctr -= caspty;
-      continue;
+      goto Abort;
     }
 
     // Did lock ownership change hands ?
     if (ox != prv && prv != NULL) {
-      if (oxpty == -2) break;
-      if (oxpty == -1) goto Abort;
-      ctr -= oxpty;
+      goto Abort;
     }
     prv = ox;
 
@@ -1991,10 +1701,12 @@
     // The owner must be executing in order to drop the lock.
     // Spinning while the owner is OFFPROC is idiocy.
     // Consider: ctr -= RunnablePenalty ;
-    if (Knob_OState && NotRunnable (Self, ox)) {
+    if (NotRunnable(Self, ox)) {
       goto Abort;
     }
-    if (sss && _succ == NULL) _succ = Self;
+    if (_succ == NULL) {
+      _succ = Self;
+    }
   }
 
   // Spin failed with prejudice -- reduce _SpinDuration.
@@ -2012,8 +1724,7 @@
   }
 
  Abort:
-  if (MaxSpin >= 0) Adjust(&_Spinner, -1);
-  if (sss && _succ == Self) {
+  if (_succ == Self) {
     _succ = NULL;
     // Invariant: after setting succ=null a contending thread
     // must recheck-retry _owner before parking.  This usually happens
@@ -2204,29 +1915,6 @@
   }
 }
 
-static char * kvGet(char * kvList, const char * Key) {
-  if (kvList == NULL) return NULL;
-  size_t n = strlen(Key);
-  char * Search;
-  for (Search = kvList; *Search; Search += strlen(Search) + 1) {
-    if (strncmp (Search, Key, n) == 0) {
-      if (Search[n] == '=') return Search + n + 1;
-      if (Search[n] == 0)   return(char *) "1";
-    }
-  }
-  return NULL;
-}
-
-static int kvGetInt(char * kvList, const char * Key, int Default) {
-  char * v = kvGet(kvList, Key);
-  int rslt = v ? ::strtol(v, NULL, 0) : Default;
-  if (Knob_ReportSettings && v != NULL) {
-    tty->print_cr("INFO: SyncKnob: %s %d(%d)", Key, rslt, Default) ;
-    tty->flush();
-  }
-  return rslt;
-}
-
 void ObjectMonitor::DeferredInitialize() {
   if (InitDone > 0) return;
   if (Atomic::cmpxchg (-1, &InitDone, 0) != 0) {
@@ -2237,70 +1925,13 @@
   // One-shot global initialization ...
   // The initialization is idempotent, so we don't need locks.
   // In the future consider doing this via os::init_2().
-  // SyncKnobs consist of <Key>=<Value> pairs in the style
-  // of environment variables.  Start by converting ':' to NUL.
 
-  if (SyncKnobs == NULL) SyncKnobs = "";
-
-  size_t sz = strlen(SyncKnobs);
-  char * knobs = (char *) os::malloc(sz + 2, mtInternal);
-  if (knobs == NULL) {
-    vm_exit_out_of_memory(sz + 2, OOM_MALLOC_ERROR, "Parse SyncKnobs");
-    guarantee(0, "invariant");
-  }
-  strcpy(knobs, SyncKnobs);
-  knobs[sz+1] = 0;
-  for (char * p = knobs; *p; p++) {
-    if (*p == ':') *p = 0;
-  }
-
-  #define SETKNOB(x) { Knob_##x = kvGetInt(knobs, #x, Knob_##x); }
-  SETKNOB(ReportSettings);
-  SETKNOB(ExitRelease);
-  SETKNOB(InlineNotify);
-  SETKNOB(Verbose);
-  SETKNOB(VerifyInUse);
-  SETKNOB(VerifyMatch);
-  SETKNOB(FixedSpin);
-  SETKNOB(SpinLimit);
-  SETKNOB(SpinBase);
-  SETKNOB(SpinBackOff);
-  SETKNOB(CASPenalty);
-  SETKNOB(OXPenalty);
-  SETKNOB(SpinSetSucc);
-  SETKNOB(SuccEnabled);
-  SETKNOB(SuccRestrict);
-  SETKNOB(Penalty);
-  SETKNOB(Bonus);
-  SETKNOB(BonusB);
-  SETKNOB(Poverty);
-  SETKNOB(SpinAfterFutile);
-  SETKNOB(UsePause);
-  SETKNOB(SpinEarly);
-  SETKNOB(OState);
-  SETKNOB(MaxSpinners);
-  SETKNOB(PreSpin);
-  SETKNOB(ExitPolicy);
-  SETKNOB(QMode);
-  SETKNOB(ResetEvent);
-  SETKNOB(MoveNotifyee);
-  SETKNOB(FastHSSEC);
-  #undef SETKNOB
-
-  if (os::is_MP()) {
-    BackOffMask = (1 << Knob_SpinBackOff) - 1;
-    if (Knob_ReportSettings) {
-      tty->print_cr("INFO: BackOffMask=0x%X", BackOffMask);
-    }
-    // CONSIDER: BackOffMask = ROUNDUP_NEXT_POWER2 (ncpus-1)
-  } else {
+  if (!os::is_MP()) {
     Knob_SpinLimit = 0;
-    Knob_SpinBase  = 0;
     Knob_PreSpin   = 0;
     Knob_FixedSpin = -1;
   }
 
-  os::free(knobs);
   OrderAccess::fence();
   InitDone = 1;
 }