8222295: more baseline cleanups from Async Monitor Deflation project
authordcubed
Wed, 24 Apr 2019 10:20:25 -0400
changeset 54609 04857e2cd509
parent 54608 c604234be658
child 54610 a9ab154b1384
8222295: more baseline cleanups from Async Monitor Deflation project Reviewed-by: coleenp, acorn, dholmes
src/hotspot/share/oops/markOop.cpp
src/hotspot/share/runtime/objectMonitor.cpp
src/hotspot/share/runtime/objectMonitor.hpp
src/hotspot/share/runtime/objectMonitor.inline.hpp
src/hotspot/share/runtime/synchronizer.cpp
src/hotspot/share/runtime/vmStructs.cpp
src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ObjectMonitor.java
src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/ui/MonitorCacheDumpPanel.java
--- a/src/hotspot/share/oops/markOop.cpp	Wed Apr 24 15:37:55 2019 +0200
+++ b/src/hotspot/share/oops/markOop.cpp	Wed Apr 24 10:20:25 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,9 +37,9 @@
     if (mon == NULL) {
       st->print("NULL (this should never be seen!)");
     } else {
-      st->print("{count=0x%08x,waiters=0x%08x"
+      st->print("{contentions=0x%08x,waiters=0x%08x"
                 ",recursions=" INTPTR_FORMAT ",owner=" INTPTR_FORMAT "}",
-                mon->count(), mon->waiters(), mon->recursions(),
+                mon->contentions(), mon->waiters(), mon->recursions(),
                 p2i(mon->owner()));
     }
   } else if (is_locked()) {
--- a/src/hotspot/share/runtime/objectMonitor.cpp	Wed Apr 24 15:37:55 2019 +0200
+++ b/src/hotspot/share/runtime/objectMonitor.cpp	Wed Apr 24 10:20:25 2019 -0400
@@ -276,9 +276,13 @@
   // Note that if we acquire the monitor from an initial spin
   // we forgo posting JVMTI events and firing DTRACE probes.
   if (TrySpin(Self) > 0) {
-    assert(_owner == Self, "invariant");
-    assert(_recursions == 0, "invariant");
-    assert(((oop)(object()))->mark() == markOopDesc::encode(this), "invariant");
+    assert(_owner == Self, "must be Self: owner=" INTPTR_FORMAT, p2i(_owner));
+    assert(_recursions == 0, "must be 0: recursions=" INTPTR_FORMAT,
+           _recursions);
+    assert(((oop)object())->mark() == markOopDesc::encode(this),
+           "object mark must match encoded this: mark=" INTPTR_FORMAT
+           ", encoded this=" INTPTR_FORMAT, p2i(((oop)object())->mark()),
+           p2i(markOopDesc::encode(this)));
     Self->_Stalled = 0;
     return;
   }
@@ -290,11 +294,11 @@
   assert(!SafepointSynchronize::is_at_safepoint(), "invariant");
   assert(jt->thread_state() != _thread_blocked, "invariant");
   assert(this->object() != NULL, "invariant");
-  assert(_count >= 0, "invariant");
+  assert(_contentions >= 0, "invariant");
 
   // Prevent deflation at STW-time.  See deflate_idle_monitors() and is_busy().
   // Ensure the object-monitor relationship remains stable while there's contention.
-  Atomic::inc(&_count);
+  Atomic::inc(&_contentions);
 
   JFR_ONLY(JfrConditionalFlushWithStacktrace<EventJavaMonitorEnter> flush(jt);)
   EventJavaMonitorEnter event;
@@ -355,8 +359,8 @@
     // acquire it.
   }
 
-  Atomic::dec(&_count);
-  assert(_count >= 0, "invariant");
+  Atomic::dec(&_contentions);
+  assert(_contentions >= 0, "invariant");
   Self->_Stalled = 0;
 
   // Must either set _recursions = 0 or ASSERT _recursions == 0.
@@ -809,7 +813,7 @@
 // There's one exception to the claim above, however.  EnterI() can call
 // exit() to drop a lock if the acquirer has been externally suspended.
 // In that case exit() is called with _thread_state as _thread_blocked,
-// but the monitor's _count field is > 0, which inhibits reclamation.
+// but the monitor's _contentions field is > 0, which inhibits reclamation.
 //
 // 1-0 exit
 // ~~~~~~~~
--- a/src/hotspot/share/runtime/objectMonitor.hpp	Wed Apr 24 15:37:55 2019 +0200
+++ b/src/hotspot/share/runtime/objectMonitor.hpp	Wed Apr 24 10:20:25 2019 -0400
@@ -163,9 +163,9 @@
   volatile int _Spinner;            // for exit->spinner handoff optimization
   volatile int _SpinDuration;
 
-  volatile jint  _count;            // reference count to prevent reclamation/deflation
-                                    // at stop-the-world time. See ObjectSynchronizer::deflate_monitor().
-                                    // _count is approximately |_WaitSet| + |_EntryList|
+  volatile jint  _contentions;      // Number of active contentions in enter(). It is used by is_busy()
+                                    // along with other fields to determine if an ObjectMonitor can be
+                                    // deflated. See ObjectSynchronizer::deflate_monitor().
  protected:
   ObjectWaiter * volatile _WaitSet; // LL of threads wait()ing on the monitor
   volatile jint  _waiters;          // number of waiting threads
@@ -207,7 +207,6 @@
   static int header_offset_in_bytes()      { return offset_of(ObjectMonitor, _header); }
   static int object_offset_in_bytes()      { return offset_of(ObjectMonitor, _object); }
   static int owner_offset_in_bytes()       { return offset_of(ObjectMonitor, _owner); }
-  static int count_offset_in_bytes()       { return offset_of(ObjectMonitor, _count); }
   static int recursions_offset_in_bytes()  { return offset_of(ObjectMonitor, _recursions); }
   static int cxq_offset_in_bytes()         { return offset_of(ObjectMonitor, _cxq); }
   static int succ_offset_in_bytes()        { return offset_of(ObjectMonitor, _succ); }
@@ -232,10 +231,8 @@
   void      set_header(markOop hdr);
 
   intptr_t is_busy() const {
-    // TODO-FIXME: merge _count and _waiters.
     // TODO-FIXME: assert _owner == null implies _recursions = 0
-    // TODO-FIXME: assert _WaitSet != null implies _count > 0
-    return _count|_waiters|intptr_t(_owner)|intptr_t(_cxq)|intptr_t(_EntryList);
+    return _contentions|_waiters|intptr_t(_owner)|intptr_t(_cxq)|intptr_t(_EntryList);
   }
 
   intptr_t  is_entered(Thread* current) const;
@@ -245,8 +242,6 @@
 
   jint      waiters() const;
 
-  jint      count() const;
-  void      set_count(jint count);
   jint      contentions() const;
   intptr_t  recursions() const                                         { return _recursions; }
 
@@ -263,14 +258,14 @@
   ~ObjectMonitor() {
     // TODO: Add asserts ...
     // _cxq == 0 _succ == NULL _owner == NULL _waiters == 0
-    // _count == 0 _EntryList  == NULL etc
+    // _contentions == 0 _EntryList  == NULL etc
   }
 
  private:
   void Recycle() {
     // TODO: add stronger asserts ...
     // _cxq == 0 _succ == NULL _owner == NULL _waiters == 0
-    // _count == 0 EntryList  == NULL
+    // _contentions == 0 EntryList  == NULL
     // _recursions == 0 _WaitSet == NULL
     assert(((is_busy()|_recursions) == 0), "freeing inuse monitor");
     _succ          = NULL;
--- a/src/hotspot/share/runtime/objectMonitor.inline.hpp	Wed Apr 24 15:37:55 2019 +0200
+++ b/src/hotspot/share/runtime/objectMonitor.inline.hpp	Wed Apr 24 10:20:25 2019 -0400
@@ -45,10 +45,6 @@
   _header = hdr;
 }
 
-inline jint ObjectMonitor::count() const {
-  return _count;
-}
-
 inline jint ObjectMonitor::waiters() const {
   return _waiters;
 }
@@ -58,12 +54,12 @@
 }
 
 inline void ObjectMonitor::clear() {
-  assert(_header != NULL, "Fatal logic error in ObjectMonitor header!");
-  assert(_count == 0, "Fatal logic error in ObjectMonitor count!");
-  assert(_waiters == 0, "Fatal logic error in ObjectMonitor waiters!");
-  assert(_recursions == 0, "Fatal logic error in ObjectMonitor recursions!");
-  assert(_object != NULL, "Fatal logic error in ObjectMonitor object!");
-  assert(_owner == NULL, "Fatal logic error in ObjectMonitor owner!");
+  assert(_header != NULL, "must be non-NULL");
+  assert(_contentions == 0, "must be 0: contentions=%d", _contentions);
+  assert(_waiters == 0, "must be 0: waiters=%d", _waiters);
+  assert(_recursions == 0, "must be 0: recursions=" INTPTR_FORMAT, _recursions);
+  assert(_object != NULL, "must be non-NULL");
+  assert(_owner == NULL, "must be NULL: owner=" INTPTR_FORMAT, p2i(_owner));
 
   _header = NULL;
   _object = NULL;
@@ -96,10 +92,10 @@
 
 // return number of threads contending for this monitor
 inline jint ObjectMonitor::contentions() const {
-  return _count;
+  return _contentions;
 }
 
-// Do NOT set _count = 0. There is a race such that _count could
+// Do NOT set _contentions = 0. There is a race such that _contentions could
 // be set while inflating prior to setting _owner
 // Just use Atomic::inc/dec and assert 0 when monitor put on free list
 inline void ObjectMonitor::set_owner(void* owner) {
--- a/src/hotspot/share/runtime/synchronizer.cpp	Wed Apr 24 15:37:55 2019 +0200
+++ b/src/hotspot/share/runtime/synchronizer.cpp	Wed Apr 24 10:20:25 2019 -0400
@@ -735,7 +735,7 @@
   } else if (mark->has_monitor()) {
     monitor = mark->monitor();
     temp = monitor->header();
-    assert(temp->is_neutral(), "invariant: header=" INTPTR_FORMAT, p2i((address)temp));
+    assert(temp->is_neutral(), "invariant: header=" INTPTR_FORMAT, p2i(temp));
     hash = temp->hash();
     if (hash != 0) {
       return hash;
@@ -743,39 +743,38 @@
     // Skip to the following code to reduce code size
   } else if (Self->is_lock_owned((address)mark->locker())) {
     temp = mark->displaced_mark_helper(); // this is a lightweight monitor owned
-    assert(temp->is_neutral(), "invariant: header=" INTPTR_FORMAT, p2i((address)temp));
+    assert(temp->is_neutral(), "invariant: header=" INTPTR_FORMAT, p2i(temp));
     hash = temp->hash();              // by current thread, check if the displaced
     if (hash != 0) {                  // header contains hash code
       return hash;
     }
     // WARNING:
-    //   The displaced header is strictly immutable.
-    // It can NOT be changed in ANY cases. So we have
-    // to inflate the header into heavyweight monitor
-    // even the current thread owns the lock. The reason
-    // is the BasicLock (stack slot) will be asynchronously
-    // read by other threads during the inflate() function.
-    // Any change to stack may not propagate to other threads
-    // correctly.
+    // The displaced header in the BasicLock on a thread's stack
+    // is strictly immutable. It CANNOT be changed in ANY cases.
+    // So we have to inflate the stack lock into an ObjectMonitor
+    // even if the current thread owns the lock. The BasicLock on
+    // a thread's stack can be asynchronously read by other threads
+    // during an inflate() call so any change to that stack memory
+    // may not propagate to other threads correctly.
   }
 
   // Inflate the monitor to set hash code
   monitor = inflate(Self, obj, inflate_cause_hash_code);
   // Load displaced header and check it has hash code
   mark = monitor->header();
-  assert(mark->is_neutral(), "invariant: header=" INTPTR_FORMAT, p2i((address)mark));
+  assert(mark->is_neutral(), "invariant: header=" INTPTR_FORMAT, p2i(mark));
   hash = mark->hash();
   if (hash == 0) {
     hash = get_next_hash(Self, obj);
     temp = mark->copy_set_hash(hash); // merge hash code into header
-    assert(temp->is_neutral(), "invariant: header=" INTPTR_FORMAT, p2i((address)temp));
+    assert(temp->is_neutral(), "invariant: header=" INTPTR_FORMAT, p2i(temp));
     test = Atomic::cmpxchg(temp, monitor->header_addr(), mark);
     if (test != mark) {
-      // The only update to the header in the monitor (outside GC)
-      // is install the hash code. If someone add new usage of
-      // displaced header, please update this code
+      // The only update to the ObjectMonitor's header/dmw field
+      // is to merge in the hash code. If someone adds a new usage
+      // of the header/dmw field, please update this code.
       hash = test->hash();
-      assert(test->is_neutral(), "invariant: header=" INTPTR_FORMAT, p2i((address)test));
+      assert(test->is_neutral(), "invariant: header=" INTPTR_FORMAT, p2i(test));
       assert(hash != 0, "Trivial unexpected object/monitor header usage.");
     }
   }
@@ -1334,7 +1333,7 @@
     if (mark->has_monitor()) {
       ObjectMonitor * inf = mark->monitor();
       markOop dmw = inf->header();
-      assert(dmw->is_neutral(), "invariant: header=" INTPTR_FORMAT, p2i((address)dmw));
+      assert(dmw->is_neutral(), "invariant: header=" INTPTR_FORMAT, p2i(dmw));
       assert(oopDesc::equals((oop) inf->object(), object), "invariant");
       assert(ObjectSynchronizer::verify_objmon_isinpool(inf), "monitor is invalid");
       return inf;
@@ -1398,7 +1397,7 @@
       // Consider what happens when a thread unlocks a stack-locked object.
       // It attempts to use CAS to swing the displaced header value from the
       // on-stack basiclock back into the object header.  Recall also that the
-      // header value (hashcode, etc) can reside in (a) the object header, or
+      // header value (hash code, etc) can reside in (a) the object header, or
       // (b) a displaced header associated with the stack-lock, or (c) a displaced
       // header in an objectMonitor.  The inflate() routine must copy the header
       // value from the basiclock on the owner's stack to the objectMonitor, all
@@ -1419,7 +1418,9 @@
       // object is in the mark.  Furthermore the owner can't complete
       // an unlock on the object, either.
       markOop dmw = mark->displaced_mark_helper();
-      assert(dmw->is_neutral(), "invariant");
+      // Catch if the object's header is not neutral (not locked and
+      // not marked is what we care about here).
+      assert(dmw->is_neutral(), "invariant: header=" INTPTR_FORMAT, p2i(dmw));
 
       // Setup monitor fields to proper values -- prepare the monitor
       m->set_header(dmw);
@@ -1463,7 +1464,9 @@
     // An inflateTry() method that we could call from fast_enter() and slow_enter()
     // would be useful.
 
-    assert(mark->is_neutral(), "invariant");
+    // Catch if the object's header is not neutral (not locked and
+    // not marked is what we care about here).
+    assert(mark->is_neutral(), "invariant: header=" INTPTR_FORMAT, p2i(mark));
     ObjectMonitor * m = omAlloc(Self);
     // prepare m for installation - set monitor to initial state
     m->Recycle();
@@ -1503,7 +1506,7 @@
 }
 
 
-// We create a list of in-use monitors for each thread.
+// We maintain a list of in-use monitors for each thread.
 //
 // deflate_thread_local_monitors() scans a single thread's in-use list, while
 // deflate_idle_monitors() scans only a global list of in-use monitors which
@@ -1512,7 +1515,7 @@
 // These operations are called at all safepoints, immediately after mutators
 // are stopped, but before any objects have moved. Collectively they traverse
 // the population of in-use monitors, deflating where possible. The scavenged
-// monitors are returned to the monitor free list.
+// monitors are returned to the global monitor free list.
 //
 // Beware that we scavenge at *every* stop-the-world point. Having a large
 // number of monitors in-use could negatively impact performance. We also want
@@ -1521,7 +1524,7 @@
 //
 // Perversely, the heap size -- and thus the STW safepoint rate --
 // typically drives the scavenge rate.  Large heaps can mean infrequent GC,
-// which in turn can mean large(r) numbers of objectmonitors in circulation.
+// which in turn can mean large(r) numbers of ObjectMonitors in circulation.
 // This is an unfortunate aspect of this design.
 
 // Deflate a single monitor if not in-use
@@ -1531,9 +1534,15 @@
                                          ObjectMonitor** freeTailp) {
   bool deflated;
   // Normal case ... The monitor is associated with obj.
-  guarantee(obj->mark() == markOopDesc::encode(mid), "invariant");
-  guarantee(mid == obj->mark()->monitor(), "invariant");
-  guarantee(mid->header()->is_neutral(), "invariant");
+  const markOop mark = obj->mark();
+  guarantee(mark == markOopDesc::encode(mid), "should match: mark="
+            INTPTR_FORMAT ", encoded mid=" INTPTR_FORMAT, p2i(mark),
+            p2i(markOopDesc::encode(mid)));
+  // Make sure that mark->monitor() and markOopDesc::encode() agree:
+  guarantee(mark->monitor() == mid, "should match: monitor()=" INTPTR_FORMAT
+            ", mid=" INTPTR_FORMAT, p2i(mark->monitor()), p2i(mid));
+  const markOop dmw = mid->header();
+  guarantee(dmw->is_neutral(), "invariant: header=" INTPTR_FORMAT, p2i(dmw));
 
   if (mid->is_busy()) {
     deflated = false;
@@ -1544,16 +1553,17 @@
     if (log_is_enabled(Trace, monitorinflation)) {
       ResourceMark rm;
       log_trace(monitorinflation)("deflate_monitor: "
-                                  "object=" INTPTR_FORMAT ", mark=" INTPTR_FORMAT ", type='%s'",
-                                  p2i(obj), p2i(obj->mark()),
-                                  obj->klass()->external_name());
+                                  "object=" INTPTR_FORMAT ", mark="
+                                  INTPTR_FORMAT ", type='%s'", p2i(obj),
+                                  p2i(mark), obj->klass()->external_name());
     }
 
     // Restore the header back to obj
-    obj->release_set_mark(mid->header());
+    obj->release_set_mark(dmw);
     mid->clear();
 
-    assert(mid->object() == NULL, "invariant");
+    assert(mid->object() == NULL, "invariant: object=" INTPTR_FORMAT,
+           p2i(mid->object()));
 
     // Move the object to the working free list defined by freeHeadp, freeTailp
     if (*freeHeadp == NULL) *freeHeadp = mid;
@@ -2022,13 +2032,12 @@
       out->print_cr("ERROR: jt=" INTPTR_FORMAT ", monitor=" INTPTR_FORMAT
                     ": in-use per-thread monitor's object does not think "
                     "it has a monitor: obj=" INTPTR_FORMAT ", mark="
-                    INTPTR_FORMAT,  p2i(jt), p2i(n), p2i((address)obj),
-                    p2i((address)mark));
+                    INTPTR_FORMAT,  p2i(jt), p2i(n), p2i(obj), p2i(mark));
     } else {
       out->print_cr("ERROR: monitor=" INTPTR_FORMAT ": in-use global "
                     "monitor's object does not think it has a monitor: obj="
                     INTPTR_FORMAT ", mark=" INTPTR_FORMAT, p2i(n),
-                    p2i((address)obj), p2i((address)mark));
+                    p2i(obj), p2i(mark));
     }
     *error_cnt_p = *error_cnt_p + 1;
   }
@@ -2039,14 +2048,12 @@
                     ": in-use per-thread monitor's object does not refer "
                     "to the same monitor: obj=" INTPTR_FORMAT ", mark="
                     INTPTR_FORMAT ", obj_mon=" INTPTR_FORMAT, p2i(jt),
-                    p2i(n), p2i((address)obj), p2i((address)mark),
-                    p2i((address)obj_mon));
+                    p2i(n), p2i(obj), p2i(mark), p2i(obj_mon));
     } else {
       out->print_cr("ERROR: monitor=" INTPTR_FORMAT ": in-use global "
                     "monitor's object does not refer to the same monitor: obj="
                     INTPTR_FORMAT ", mark=" INTPTR_FORMAT ", obj_mon="
-                    INTPTR_FORMAT, p2i(n), p2i((address)obj),
-                    p2i((address)mark), p2i((address)obj_mon));
+                    INTPTR_FORMAT, p2i(n), p2i(obj), p2i(mark), p2i(obj_mon));
     }
     *error_cnt_p = *error_cnt_p + 1;
   }
@@ -2105,7 +2112,7 @@
 
   if (gOmInUseCount > 0) {
     out->print_cr("In-use global monitor info:");
-    out->print_cr("(B -> is_busy, H -> has hashcode, L -> lock status)");
+    out->print_cr("(B -> is_busy, H -> has hash code, L -> lock status)");
     out->print_cr("%18s  %s  %18s  %18s",
                   "monitor", "BHL", "object", "object type");
     out->print_cr("==================  ===  ==================  ==================");
@@ -2124,7 +2131,7 @@
   }
 
   out->print_cr("In-use per-thread monitor info:");
-  out->print_cr("(B -> is_busy, H -> has hashcode, L -> lock status)");
+  out->print_cr("(B -> is_busy, H -> has hash code, L -> lock status)");
   out->print_cr("%18s  %18s  %s  %18s  %18s",
                 "jt", "monitor", "BHL", "object", "object type");
   out->print_cr("==================  ==================  ===  ==================  ==================");
--- a/src/hotspot/share/runtime/vmStructs.cpp	Wed Apr 24 15:37:55 2019 +0200
+++ b/src/hotspot/share/runtime/vmStructs.cpp	Wed Apr 24 10:20:25 2019 -0400
@@ -896,7 +896,7 @@
   volatile_nonstatic_field(ObjectMonitor,      _header,                                       markOop)                               \
   unchecked_nonstatic_field(ObjectMonitor,     _object,                                       sizeof(void *)) /* NOTE: no type */    \
   unchecked_nonstatic_field(ObjectMonitor,     _owner,                                        sizeof(void *)) /* NOTE: no type */    \
-  volatile_nonstatic_field(ObjectMonitor,      _count,                                        jint)                                  \
+  volatile_nonstatic_field(ObjectMonitor,      _contentions,                                  jint)                                  \
   volatile_nonstatic_field(ObjectMonitor,      _waiters,                                      jint)                                  \
   volatile_nonstatic_field(ObjectMonitor,      _recursions,                                   intptr_t)                              \
   nonstatic_field(ObjectMonitor,               FreeNext,                                      ObjectMonitor*)                        \
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ObjectMonitor.java	Wed Apr 24 15:37:55 2019 +0200
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ObjectMonitor.java	Wed Apr 24 10:20:25 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -50,7 +50,7 @@
     ownerFieldOffset = f.getOffset();
     f = type.getField("FreeNext");
     FreeNextFieldOffset = f.getOffset();
-    countField  = type.getJIntField("_count");
+    contentionsField  = type.getJIntField("_contentions");
     waitersField = type.getJIntField("_waiters");
     recursionsField = type.getCIntegerField("_recursions");
   }
@@ -87,19 +87,14 @@
   // FIXME
   //  void      set_queue(void* owner);
 
-  public int count() { return countField.getValue(addr); }
-  // FIXME
-  //  void      set_count(int count);
-
   public long recursions() { return recursionsField.getValue(addr); }
 
   public OopHandle object() {
     return addr.getOopHandleAt(objectFieldOffset);
   }
 
-  // contentions is always equal to count
   public int contentions() {
-      return count();
+      return contentionsField.getValue(addr);
   }
 
   // FIXME
@@ -114,7 +109,7 @@
   private static long          objectFieldOffset;
   private static long          ownerFieldOffset;
   private static long          FreeNextFieldOffset;
-  private static JIntField     countField;
+  private static JIntField     contentionsField;
   private static JIntField     waitersField;
   private static CIntegerField recursionsField;
   // FIXME: expose platform-dependent stuff
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/ui/MonitorCacheDumpPanel.java	Wed Apr 24 15:37:55 2019 +0200
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/ui/MonitorCacheDumpPanel.java	Wed Apr 24 10:20:25 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -83,7 +83,7 @@
         }
       }
     }
-    tty.println("  _count: " + mon.count());
+    tty.println("  _contentions: " + mon.contentions());
     tty.println("  _waiters: " + mon.waiters());
     tty.println("  _recursions: " + mon.recursions());
   }
@@ -98,7 +98,7 @@
     ObjectMonitor mon;
     while (i.hasNext()) {
       mon = (ObjectMonitor)i.next();
-      if (mon.count() != 0 || mon.waiters() != 0 || mon.owner() != null) {
+      if (mon.contentions() != 0 || mon.waiters() != 0 || mon.owner() != null) {
         OopHandle object = mon.object();
         if (object == null) {
           dumpMonitor(tty, mon, true);