--- old/src/share/vm/runtime/mutexLocker.hpp 2016-02-05 16:13:48.508134391 +0100 +++ new/src/share/vm/runtime/mutexLocker.hpp 2016-02-05 16:13:48.388134386 +0100 @@ -94,6 +94,7 @@ extern Mutex* CompileTaskAlloc_lock; // a lock held when CompileTasks are allocated extern Mutex* CompileStatistics_lock; // a lock held when updating compilation statistics extern Mutex* DirectivesStack_lock; // a lock held when mutating the dirstack and ref counting directives +extern Mutex* LoadDisassembler_lock; // a lock held when lazy loading the disassembler extern Mutex* MultiArray_lock; // a lock used to guard allocation of multi-dim arrays extern Monitor* Terminator_lock; // a lock used to guard termination of the vm extern Monitor* BeforeExit_lock; // a lock used to guard cleanups and shutdown hooks --- old/src/share/vm/compiler/disassembler.cpp 2016-02-05 16:13:48.512134391 +0100 +++ new/src/share/vm/compiler/disassembler.cpp 2016-02-05 16:13:48.388134386 +0100 @@ -80,6 +80,7 @@ // To force retry in debugger: assign _tried_to_load_library=0 return false; } + // Try to load it. char ebuf[1024]; char buf[JVM_MAXPATHLEN]; @@ -165,6 +166,22 @@ return true; } +bool Disassembler::can_decode() { + if (_decode_instructions_virtual != NULL || _decode_instructions != NULL) { + // Already succeeded. + return true; + } + if (_tried_to_load_library) { + // Do not try twice. + // To force retry in debugger: assign _tried_to_load_library=0 + return false; + } + + // If it was not loaded - lock and load. (double checked) + MutexLockerEx locker(DirectivesStack_lock, Mutex::_no_safepoint_check_flag); + return Disassembler::load_library(); +} + class decode_env { private: @@ -513,8 +530,8 @@ void Disassembler::decode(CodeBlob* cb, outputStream* st) { + if (!can_decode()) return; ttyLocker ttyl; - if (!load_library()) return; if (cb->is_nmethod()) { decode((nmethod*)cb, st); return; @@ -527,15 +544,15 @@ } void Disassembler::decode(address start, address end, outputStream* st, CodeStrings c) { + if (!can_decode()) return; ttyLocker ttyl; - if (!load_library()) return; decode_env env(CodeCache::find_blob_unsafe(start), st, c); env.decode_instructions(start, end); } void Disassembler::decode(nmethod* nm, outputStream* st) { + if (!can_decode()) return; ttyLocker ttyl; - if (!load_library()) return; decode_env env(nm, st); env.output()->print_cr("----------------------------------------------------------------------"); --- old/src/share/vm/compiler/disassembler.hpp 2016-02-05 16:13:48.512134391 +0100 +++ new/src/share/vm/compiler/disassembler.hpp 2016-02-05 16:13:48.392134386 +0100 @@ -59,7 +59,7 @@ // points to the decode function. static decode_func_virtual _decode_instructions_virtual; static decode_func _decode_instructions; - // tries to load library and return whether it succedded. + // tries to load library and return whether it succeeded. static bool load_library(); // Machine dependent stuff @@ -84,11 +84,7 @@ public: - static bool can_decode() { - return (_decode_instructions_virtual != NULL) || - (_decode_instructions != NULL) || - load_library(); - } + static bool can_decode(); static void decode(CodeBlob *cb, outputStream* st = NULL); static void decode(nmethod* nm, outputStream* st = NULL); static void decode(address begin, address end, outputStream* st = NULL, CodeStrings c = CodeStrings()); --- old/src/share/vm/runtime/mutexLocker.cpp 2016-02-05 16:13:48.516134392 +0100 +++ new/src/share/vm/runtime/mutexLocker.cpp 2016-02-05 16:13:48.388134386 +0100 @@ -90,6 +90,7 @@ Mutex* CompileTaskAlloc_lock = NULL; Mutex* CompileStatistics_lock = NULL; Mutex* DirectivesStack_lock = NULL; +Mutex* LoadDisassembler_lock = NULL; Mutex* MultiArray_lock = NULL; Monitor* Terminator_lock = NULL; Monitor* BeforeExit_lock = NULL; @@ -264,6 +265,7 @@ def(CompileTaskAlloc_lock , Mutex , nonleaf+2, true, Monitor::_safepoint_check_always); def(CompileStatistics_lock , Mutex , nonleaf+2, false, Monitor::_safepoint_check_always); def(DirectivesStack_lock , Mutex , special, true, Monitor::_safepoint_check_never); + def(LoadDisassembler_lock , Mutex , special, true, Monitor::_safepoint_check_never); def(MultiArray_lock , Mutex , nonleaf+2, false, Monitor::_safepoint_check_always); // locks SymbolTable_lock def(JvmtiThreadState_lock , Mutex , nonleaf+2, false, Monitor::_safepoint_check_always); // Used by JvmtiThreadState/JvmtiEventController