--- old/src/hotspot/share/runtime/globals.hpp 2020-01-31 16:35:14.103723047 -0500 +++ new/src/hotspot/share/runtime/globals.hpp 2020-01-31 16:35:13.747714373 -0500 @@ -698,6 +698,10 @@ product(intx, MonitorBound, 0, "(Deprecated) Bound Monitor population") \ range(0, max_jint) \ \ + develop(intx, StressMonitorInterferenceCount, 10, \ + "Stress Monitor code paths") \ + range(0, 100) \ + \ experimental(intx, MonitorUsedDeflationThreshold, 90, \ "Percentage of used monitors before triggering cleanup " \ "safepoint which deflates monitors (0 is off). " \ --- old/src/hotspot/share/runtime/synchronizer.cpp 2020-01-31 16:35:14.599735132 -0500 +++ new/src/hotspot/share/runtime/synchronizer.cpp 2020-01-31 16:35:14.255726750 -0500 @@ -1293,7 +1293,7 @@ m = take_from_start_of_om_free_list(self); if (m != NULL) { guarantee(m->object() == NULL, "invariant"); - prepend_to_om_in_use_list(self, m); + // prepend_to_om_in_use_list(self, m); return m; } @@ -1394,7 +1394,7 @@ m->_recursions); // _next_om is used for both per-thread in-use and free lists so // we have to remove 'm' from the in-use list first (as needed). - if (from_per_thread_alloc) { + if (false && from_per_thread_alloc) { // Need to remove 'm' from om_in_use_list. ObjectMonitor* mid = NULL; ObjectMonitor* next = NULL; @@ -1620,6 +1620,7 @@ !SafepointSynchronize::is_at_safepoint(), "invariant"); EventJavaMonitorInflate event; + int interference_count = 0; for (;;) { const markWord mark = object->mark(); @@ -1683,11 +1684,13 @@ m->_Responsible = NULL; m->_SpinDuration = ObjectMonitor::Knob_SpinLimit; // Consider: maintain by type/class - markWord cmp = object->cas_set_mark(markWord::INFLATING(), mark); - if (cmp != mark) { + interference_count++; + if (StressMonitorInterferenceCount > interference_count + || object->cas_set_mark(markWord::INFLATING(), mark) != mark) { om_release(self, m, true); continue; // Interference -- just retry } + prepend_to_om_in_use_list(self, m); // We've successfully installed INFLATING (0) into the mark-word. // This is the only case where 0 will appear in a mark-word. @@ -1776,7 +1779,8 @@ m->_Responsible = NULL; m->_SpinDuration = ObjectMonitor::Knob_SpinLimit; // consider: keep metastats by type/class - if (object->cas_set_mark(markWord::encode(m), mark) != mark) { + interference_count++; + if (StressMonitorInterferenceCount > interference_count || object->cas_set_mark(markWord::encode(m), mark) != mark) { m->set_header(markWord::zero()); m->set_object(NULL); m->Recycle(); @@ -1787,6 +1791,7 @@ // The state-transitions are one-way, so there's no chance of // live-lock -- "Inflated" is an absorbing state. } + prepend_to_om_in_use_list(self, m); // Hopefully the performance counters are allocated on distinct // cache lines to avoid false sharing on MP systems ...