8213723: More Monitor/mutex initialization management
authordholmes
Thu, 15 Nov 2018 17:55:41 -0500
changeset 52581 d402a406bbc3
parent 52580 73f6a850a62f
child 52582 6df094be7f58
8213723: More Monitor/mutex initialization management 8213893: StringTable_lock is unused Reviewed-by: tschatzl, dcubed, coleenp
src/hotspot/os/aix/os_aix.cpp
src/hotspot/os/bsd/os_bsd.cpp
src/hotspot/os/linux/os_linux.cpp
src/hotspot/os/solaris/os_solaris.cpp
src/hotspot/os/windows/os_windows.cpp
src/hotspot/share/runtime/mutex.cpp
src/hotspot/share/runtime/mutexLocker.cpp
src/hotspot/share/runtime/mutexLocker.hpp
src/hotspot/share/runtime/os.cpp
src/hotspot/share/runtime/os.hpp
src/hotspot/share/services/memTracker.cpp
src/hotspot/share/services/memTracker.hpp
--- a/src/hotspot/os/aix/os_aix.cpp	Thu Nov 15 14:01:10 2018 -0800
+++ b/src/hotspot/os/aix/os_aix.cpp	Thu Nov 15 17:55:41 2018 -0500
@@ -3532,6 +3532,10 @@
 // This is called _after_ the global arguments have been parsed.
 jint os::init_2(void) {
 
+  // This could be set after os::Posix::init() but all platforms
+  // have to set it the same so we have to mirror Solaris.
+  DEBUG_ONLY(os::set_mutex_init_done();)
+
   os::Posix::init_2();
 
   if (os::Aix::on_pase()) {
--- a/src/hotspot/os/bsd/os_bsd.cpp	Thu Nov 15 14:01:10 2018 -0800
+++ b/src/hotspot/os/bsd/os_bsd.cpp	Thu Nov 15 17:55:41 2018 -0500
@@ -3167,6 +3167,10 @@
 // this is called _after_ the global arguments have been parsed
 jint os::init_2(void) {
 
+  // This could be set after os::Posix::init() but all platforms
+  // have to set it the same so we have to mirror Solaris.
+  DEBUG_ONLY(os::set_mutex_init_done();)
+
   os::Posix::init_2();
 
   // initialize suspend/resume support - must do this before signal_sets_init()
--- a/src/hotspot/os/linux/os_linux.cpp	Thu Nov 15 14:01:10 2018 -0800
+++ b/src/hotspot/os/linux/os_linux.cpp	Thu Nov 15 17:55:41 2018 -0500
@@ -4957,6 +4957,10 @@
 // this is called _after_ the global arguments have been parsed
 jint os::init_2(void) {
 
+  // This could be set after os::Posix::init() but all platforms
+  // have to set it the same so we have to mirror Solaris.
+  DEBUG_ONLY(os::set_mutex_init_done();)
+
   os::Posix::init_2();
 
   Linux::fast_thread_clock_init();
--- a/src/hotspot/os/solaris/os_solaris.cpp	Thu Nov 15 14:01:10 2018 -0800
+++ b/src/hotspot/os/solaris/os_solaris.cpp	Thu Nov 15 17:55:41 2018 -0500
@@ -4199,6 +4199,7 @@
   // initialize synchronization primitives to use either thread or
   // lwp synchronization (controlled by UseLWPSynchronization)
   Solaris::synchronization_init();
+  DEBUG_ONLY(os::set_mutex_init_done();)
 
   if (MaxFDLimit) {
     // set the number of file descriptors to max. print out error
--- a/src/hotspot/os/windows/os_windows.cpp	Thu Nov 15 14:01:10 2018 -0800
+++ b/src/hotspot/os/windows/os_windows.cpp	Thu Nov 15 17:55:41 2018 -0500
@@ -4036,6 +4036,11 @@
 
 // this is called _after_ the global arguments have been parsed
 jint os::init_2(void) {
+
+  // This could be set any time but all platforms
+  // have to set it the same so we have to mirror Solaris.
+  DEBUG_ONLY(os::set_mutex_init_done();)
+
   // Setup Windows Exceptions
 
   // for debugging float code generation bugs
--- a/src/hotspot/share/runtime/mutex.cpp	Thu Nov 15 14:01:10 2018 -0800
+++ b/src/hotspot/share/runtime/mutex.cpp	Thu Nov 15 17:55:41 2018 -0500
@@ -1159,10 +1159,14 @@
   m->_WaitLock[0]       = 0;
 }
 
-Monitor::Monitor() { ClearMonitor(this); }
+Monitor::Monitor() {
+  assert(os::mutex_init_done(), "Too early!");
+  ClearMonitor(this);
+}
 
 Monitor::Monitor(int Rank, const char * name, bool allow_vm_block,
                  SafepointCheckRequired safepoint_check_required) {
+  assert(os::mutex_init_done(), "Too early!");
   ClearMonitor(this, name);
 #ifdef ASSERT
   _allow_vm_block  = allow_vm_block;
--- a/src/hotspot/share/runtime/mutexLocker.cpp	Thu Nov 15 14:01:10 2018 -0800
+++ b/src/hotspot/share/runtime/mutexLocker.cpp	Thu Nov 15 17:55:41 2018 -0500
@@ -64,7 +64,6 @@
 Mutex*   SignatureHandlerLibrary_lock = NULL;
 Mutex*   VtableStubs_lock             = NULL;
 Mutex*   SymbolArena_lock             = NULL;
-Mutex*   StringTable_lock             = NULL;
 Monitor* StringDedupQueue_lock        = NULL;
 Mutex*   StringDedupTable_lock        = NULL;
 Monitor* CodeCache_lock               = NULL;
@@ -148,9 +147,12 @@
 
 Mutex*   MetaspaceExpand_lock         = NULL;
 Mutex*   ClassLoaderDataGraph_lock    = NULL;
-Monitor* ThreadsSMRDelete_lock       = NULL;
+Monitor* ThreadsSMRDelete_lock        = NULL;
 Mutex*   SharedDecoder_lock           = NULL;
 Mutex*   DCmdFactory_lock             = NULL;
+#if INCLUDE_NMT
+Mutex*   NMTQuery_lock                = NULL;
+#endif
 
 #define MAX_NUM_MUTEX 128
 static Monitor * _mutex_array[MAX_NUM_MUTEX];
@@ -255,7 +257,6 @@
   def(JNIHandleBlockFreeList_lock  , PaddedMutex  , leaf-1,      true,  Monitor::_safepoint_check_never);      // handles are used by VM thread
   def(SignatureHandlerLibrary_lock , PaddedMutex  , leaf,        false, Monitor::_safepoint_check_always);
   def(SymbolArena_lock             , PaddedMutex  , leaf+2,      true,  Monitor::_safepoint_check_never);
-  def(StringTable_lock             , PaddedMutex  , leaf,        true,  Monitor::_safepoint_check_always);
   def(ProfilePrint_lock            , PaddedMutex  , leaf,        false, Monitor::_safepoint_check_always);     // serial profile printing
   def(ExceptionCache_lock          , PaddedMutex  , leaf,        false, Monitor::_safepoint_check_always);     // serial profile printing
   def(OsrList_lock                 , PaddedMutex  , leaf,        true,  Monitor::_safepoint_check_never);
@@ -335,6 +336,9 @@
   def(ThreadsSMRDelete_lock        , PaddedMonitor, special,     false, Monitor::_safepoint_check_never);
   def(SharedDecoder_lock           , PaddedMutex  , native,      false, Monitor::_safepoint_check_never);
   def(DCmdFactory_lock             , PaddedMutex  , leaf,        true,  Monitor::_safepoint_check_never);
+#if INCLUDE_NMT
+  def(NMTQuery_lock                , PaddedMutex  , max_nonleaf, false, Monitor::_safepoint_check_always);
+#endif
 }
 
 GCMutexLocker::GCMutexLocker(Monitor * mutex) {
--- a/src/hotspot/share/runtime/mutexLocker.hpp	Thu Nov 15 14:01:10 2018 -0800
+++ b/src/hotspot/share/runtime/mutexLocker.hpp	Thu Nov 15 17:55:41 2018 -0500
@@ -58,7 +58,6 @@
 extern Mutex*   SignatureHandlerLibrary_lock;    // a lock on the SignatureHandlerLibrary
 extern Mutex*   VtableStubs_lock;                // a lock on the VtableStubs
 extern Mutex*   SymbolArena_lock;                // a lock on the symbol table arena
-extern Mutex*   StringTable_lock;                // a lock on the interned string table
 extern Monitor* StringDedupQueue_lock;           // a lock on the string deduplication queue
 extern Mutex*   StringDedupTable_lock;           // a lock on the string deduplication table
 extern Monitor* CodeCache_lock;                  // a lock on the CodeCache, rank is special, use MutexLockerEx
@@ -136,6 +135,9 @@
 extern Monitor* ThreadsSMRDelete_lock;           // Used by ThreadsSMRSupport to take pressure off the Threads_lock
 extern Mutex*   SharedDecoder_lock;              // serializes access to the decoder during normal (not error reporting) use
 extern Mutex*   DCmdFactory_lock;                // serialize access to DCmdFactory information
+#if INCLUDE_NMT
+extern Mutex*   NMTQuery_lock;                   // serialize NMT Dcmd queries
+#endif
 #if INCLUDE_JFR
 extern Mutex*   JfrStacktrace_lock;              // used to guard access to the JFR stacktrace table
 extern Monitor* JfrMsg_lock;                     // protects JFR messaging
--- a/src/hotspot/share/runtime/os.cpp	Thu Nov 15 14:01:10 2018 -0800
+++ b/src/hotspot/share/runtime/os.cpp	Thu Nov 15 17:55:41 2018 -0500
@@ -85,6 +85,8 @@
 
 static size_t cur_malloc_words = 0;  // current size for MallocMaxTestWords
 
+DEBUG_ONLY(bool os::_mutex_init_done = false;)
+
 void os_init_globals() {
   // Called from init_globals().
   // See Threads::create_vm() in thread.cpp, and init.cpp.
--- a/src/hotspot/share/runtime/os.hpp	Thu Nov 15 14:01:10 2018 -0800
+++ b/src/hotspot/share/runtime/os.hpp	Thu Nov 15 17:55:41 2018 -0500
@@ -94,6 +94,15 @@
   friend class VMStructs;
   friend class JVMCIVMStructs;
   friend class MallocTracker;
+
+#ifdef ASSERT
+ private:
+  static bool _mutex_init_done;
+ public:
+  static void set_mutex_init_done() { _mutex_init_done = true; }
+  static bool mutex_init_done() { return _mutex_init_done; }
+#endif
+
  public:
   enum { page_sizes_max = 9 }; // Size of _page_sizes array (8 plus a sentinel)
 
--- a/src/hotspot/share/services/memTracker.cpp	Thu Nov 15 14:01:10 2018 -0800
+++ b/src/hotspot/share/services/memTracker.cpp	Thu Nov 15 17:55:41 2018 -0500
@@ -24,7 +24,6 @@
 #include "precompiled.hpp"
 #include "jvm.h"
 
-#include "runtime/mutex.hpp"
 #include "runtime/orderAccess.hpp"
 #include "runtime/vmThread.hpp"
 #include "runtime/vm_operations.hpp"
@@ -50,7 +49,6 @@
 NMT_TrackingLevel MemTracker::_cmdline_tracking_level = NMT_unknown;
 
 MemBaseline MemTracker::_baseline;
-Mutex*      MemTracker::_query_lock = NULL;
 bool MemTracker::_is_nmt_env_valid = true;
 
 static const size_t buffer_size = 64;
@@ -98,11 +96,6 @@
       shutdown();
       return;
     }
-    _query_lock = new (std::nothrow) Mutex(Monitor::max_nonleaf, "NMT_queryLock");
-    // Already OOM. It is unlikely, but still have to handle it.
-    if (_query_lock == NULL) {
-      shutdown();
-    }
   }
 }
 
--- a/src/hotspot/share/services/memTracker.hpp	Thu Nov 15 14:01:10 2018 -0800
+++ b/src/hotspot/share/services/memTracker.hpp	Thu Nov 15 17:55:41 2018 -0500
@@ -79,6 +79,7 @@
 
 #else
 
+#include "runtime/mutexLocker.hpp"
 #include "runtime/threadCritical.hpp"
 #include "services/mallocTracker.hpp"
 #include "services/virtualMemoryTracker.hpp"
@@ -91,7 +92,6 @@
                     NativeCallStack(1, true) : NativeCallStack::empty_stack())
 
 class MemBaseline;
-class Mutex;
 
 // Tracker is used for guarding 'release' semantics of virtual memory operation, to avoid
 // the other thread obtains and records the same region that is just 'released' by current
@@ -270,7 +270,10 @@
   // Query lock is used to synchronize the access to tracking data.
   // So far, it is only used by JCmd query, but it may be used by
   // other tools.
-  static inline Mutex* query_lock() { return _query_lock; }
+  static inline Mutex* query_lock() {
+    assert(NMTQuery_lock != NULL, "not initialized!");
+    return NMTQuery_lock;
+  }
 
   // Make a final report or report for hs_err file.
   static void error_report(outputStream* output) {