src/hotspot/share/runtime/objectMonitor.hpp
branchdatagramsocketimpl-branch
changeset 58678 9cf78a70fa4f
parent 54807 33fe50b6d707
child 58679 9c3209ff7550
--- a/src/hotspot/share/runtime/objectMonitor.hpp	Thu Oct 17 20:27:44 2019 +0100
+++ b/src/hotspot/share/runtime/objectMonitor.hpp	Thu Oct 17 20:53:35 2019 +0100
@@ -27,6 +27,7 @@
 
 #include "memory/allocation.hpp"
 #include "memory/padded.hpp"
+#include "oops/markWord.hpp"
 #include "runtime/os.hpp"
 #include "runtime/park.hpp"
 #include "runtime/perfData.hpp"
@@ -42,15 +43,13 @@
 class ObjectWaiter : public StackObj {
  public:
   enum TStates { TS_UNDEF, TS_READY, TS_RUN, TS_WAIT, TS_ENTER, TS_CXQ };
-  enum Sorted  { PREPEND, APPEND, SORTED };
-  ObjectWaiter * volatile _next;
-  ObjectWaiter * volatile _prev;
+  ObjectWaiter* volatile _next;
+  ObjectWaiter* volatile _prev;
   Thread*       _thread;
   jlong         _notifier_tid;
   ParkEvent *   _event;
   volatile int  _notified;
   volatile TStates TState;
-  Sorted        _Sorted;           // List placement disposition
   bool          _active;           // Contention monitoring is enabled
  public:
   ObjectWaiter(Thread* thread);
@@ -67,14 +66,10 @@
 // WARNING: This is a very sensitive and fragile class. DO NOT make any
 // changes unless you are fully aware of the underlying semantics.
 //
-// Class JvmtiRawMonitor currently inherits from ObjectMonitor so
-// changes in this class must be careful to not break JvmtiRawMonitor.
-// These two subsystems should be separated.
-//
 // ObjectMonitor Layout Overview/Highlights/Restrictions:
 //
 // - The _header field must be at offset 0 because the displaced header
-//   from markOop is stored there. We do not want markOop.hpp to include
+//   from markWord is stored there. We do not want markWord.hpp to include
 //   ObjectMonitor.hpp to avoid exposing ObjectMonitor everywhere. This
 //   means that ObjectMonitor cannot inherit from any other class nor can
 //   it use any virtual member functions. This restriction is critical to
@@ -126,40 +121,37 @@
 //     in a 64-bit JVM.
 
 class ObjectMonitor {
- public:
-  enum {
-    OM_OK,                    // no error
-    OM_SYSTEM_ERROR,          // operating system error
-    OM_ILLEGAL_MONITOR_STATE, // IllegalMonitorStateException
-    OM_INTERRUPTED,           // Thread.interrupt()
-    OM_TIMED_OUT              // Object.wait() timed out
-  };
-
- private:
   friend class ObjectSynchronizer;
   friend class ObjectWaiter;
   friend class VMStructs;
   JVMCI_ONLY(friend class JVMCIVMStructs;)
 
-  volatile markOop   _header;       // displaced object header word - mark
-  void*     volatile _object;       // backward object pointer - strong root
+  // The sync code expects the header field to be at offset zero (0).
+  // Enforced by the assert() in header_addr().
+  volatile markWord _header;        // displaced object header word - mark
+  void* volatile _object;           // backward object pointer - strong root
  public:
-  ObjectMonitor*     FreeNext;      // Free list linkage
+  ObjectMonitor* _next_om;          // Next ObjectMonitor* linkage
  private:
+  // Separate _header and _owner on different cache lines since both can
+  // have busy multi-threaded access. _header and _object are set at
+  // initial inflation and _object doesn't change until deflation so
+  // _object is a good choice to share the cache line with _header.
+  // _next_om shares _header's cache line for pre-monitor list historical
+  // reasons. _next_om only changes if the next ObjectMonitor is deflated.
   DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE,
-                        sizeof(volatile markOop) + sizeof(void * volatile) +
+                        sizeof(volatile markWord) + sizeof(void* volatile) +
                         sizeof(ObjectMonitor *));
- protected:                         // protected for JvmtiRawMonitor
-  void *  volatile _owner;          // pointer to owning thread OR BasicLock
+  void* volatile _owner;            // pointer to owning thread OR BasicLock
   volatile jlong _previous_owner_tid;  // thread id of the previous owner of the monitor
-  volatile intptr_t  _recursions;   // recursion count, 0 for first entry
-  ObjectWaiter * volatile _EntryList; // Threads blocked on entry or reentry.
+  volatile intptr_t _recursions;    // recursion count, 0 for first entry
+  ObjectWaiter* volatile _EntryList;  // Threads blocked on entry or reentry.
                                       // The list is actually composed of WaitNodes,
                                       // acting as proxies for Threads.
- private:
-  ObjectWaiter * volatile _cxq;     // LL of recently-arrived threads blocked on entry.
-  Thread * volatile _succ;          // Heir presumptive thread - used for futile wakeup throttling
-  Thread * volatile _Responsible;
+
+  ObjectWaiter* volatile _cxq;      // LL of recently-arrived threads blocked on entry.
+  Thread* volatile _succ;           // Heir presumptive thread - used for futile wakeup throttling
+  Thread* volatile _Responsible;
 
   volatile int _Spinner;            // for exit->spinner handoff optimization
   volatile int _SpinDuration;
@@ -168,7 +160,7 @@
                                     // 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
+  ObjectWaiter* volatile _WaitSet;  // LL of threads wait()ing on the monitor
   volatile jint  _waiters;          // number of waiting threads
  private:
   volatile int _WaitSetLock;        // protects Wait Queue - simple spinlock
@@ -201,7 +193,7 @@
   void* operator new (size_t size) throw();
   void* operator new[] (size_t size) throw();
   void operator delete(void* p);
-  void operator delete[] (void *p);
+  void operator delete[] (void* p);
 
   // TODO-FIXME: the "offset" routines should return a type of off_t instead of int ...
   // ByteSize would also be an appropriate type.
@@ -213,7 +205,7 @@
   static int succ_offset_in_bytes()        { return offset_of(ObjectMonitor, _succ); }
   static int EntryList_offset_in_bytes()   { return offset_of(ObjectMonitor, _EntryList); }
 
-  // ObjectMonitor references can be ORed with markOopDesc::monitor_value
+  // ObjectMonitor references can be ORed with markWord::monitor_value
   // as part of the ObjectMonitor tagging mechanism. When we combine an
   // ObjectMonitor reference with an offset, we need to remove the tag
   // value in order to generate the proper address.
@@ -225,16 +217,17 @@
   // to the ObjectMonitor reference manipulation code:
   //
   #define OM_OFFSET_NO_MONITOR_VALUE_TAG(f) \
-    ((ObjectMonitor::f ## _offset_in_bytes()) - markOopDesc::monitor_value)
+    ((ObjectMonitor::f ## _offset_in_bytes()) - markWord::monitor_value)
 
-  markOop   header() const;
-  volatile markOop* header_addr();
-  void      set_header(markOop hdr);
+  markWord           header() const;
+  volatile markWord* header_addr();
+  void               set_header(markWord hdr);
 
   intptr_t is_busy() const {
     // TODO-FIXME: assert _owner == null implies _recursions = 0
     return _contentions|_waiters|intptr_t(_owner)|intptr_t(_cxq)|intptr_t(_EntryList);
   }
+  const char* is_busy_to_string(stringStream* ss);
 
   intptr_t  is_entered(Thread* current) const;
 
@@ -254,7 +247,7 @@
  protected:
   // We don't typically expect or want the ctors or dtors to run.
   // normal ObjectMonitors are type-stable and immortal.
-  ObjectMonitor() { ::memset((void *)this, 0, sizeof(*this)); }
+  ObjectMonitor() { ::memset((void*)this, 0, sizeof(*this)); }
 
   ~ObjectMonitor() {
     // TODO: Add asserts ...
@@ -268,7 +261,9 @@
     // _cxq == 0 _succ == NULL _owner == NULL _waiters == 0
     // _contentions == 0 EntryList  == NULL
     // _recursions == 0 _WaitSet == NULL
-    assert(((is_busy()|_recursions) == 0), "freeing inuse monitor");
+    DEBUG_ONLY(stringStream ss;)
+    assert((is_busy() | _recursions) == 0, "freeing in-use monitor: %s, "
+           "recursions=" INTPTR_FORMAT, is_busy_to_string(&ss), _recursions);
     _succ          = NULL;
     _EntryList     = NULL;
     _cxq           = NULL;
@@ -282,8 +277,9 @@
   void*     object_addr();
   void      set_object(void* obj);
 
-  bool      check(TRAPS);       // true if the thread owns the monitor.
-  void      check_slow(TRAPS);
+  // Returns true if the specified thread owns the ObjectMonitor. Otherwise
+  // returns false and throws IllegalMonitorStateException (IMSE).
+  bool      check_owner(Thread* THREAD);
   void      clear();
 
   void      enter(TRAPS);
@@ -300,18 +296,18 @@
   void      reenter(intptr_t recursions, TRAPS);
 
  private:
-  void      AddWaiter(ObjectWaiter * waiter);
-  void      INotify(Thread * Self);
-  ObjectWaiter * DequeueWaiter();
-  void      DequeueSpecificWaiter(ObjectWaiter * waiter);
+  void      AddWaiter(ObjectWaiter* waiter);
+  void      INotify(Thread* self);
+  ObjectWaiter* DequeueWaiter();
+  void      DequeueSpecificWaiter(ObjectWaiter* waiter);
   void      EnterI(TRAPS);
-  void      ReenterI(Thread * Self, ObjectWaiter * SelfNode);
-  void      UnlinkAfterAcquire(Thread * Self, ObjectWaiter * SelfNode);
-  int       TryLock(Thread * Self);
-  int       NotRunnable(Thread * Self, Thread * Owner);
-  int       TrySpin(Thread * Self);
-  void      ExitEpilog(Thread * Self, ObjectWaiter * Wakee);
-  bool      ExitSuspendEquivalent(JavaThread * Self);
+  void      ReenterI(Thread* self, ObjectWaiter* self_node);
+  void      UnlinkAfterAcquire(Thread* self, ObjectWaiter* self_node);
+  int       TryLock(Thread* self);
+  int       NotRunnable(Thread* self, Thread * Owner);
+  int       TrySpin(Thread* self);
+  void      ExitEpilog(Thread* self, ObjectWaiter* Wakee);
+  bool      ExitSuspendEquivalent(JavaThread* self);
 };
 
 #endif // SHARE_RUNTIME_OBJECTMONITOR_HPP