8213723: More Monitor/mutex initialization management
8213893: StringTable_lock is unused
Reviewed-by: tschatzl, dcubed, coleenp
--- 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) {