JDK-8213137 : Remove static initialization of monitor/mutex instances
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 12
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2018-10-30
  • Updated: 2021-06-21
  • Resolved: 2018-11-08
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 11 JDK 12
11.0.13Fixed 12 b20Fixed
Related Reports
Relates :  
Relates :  
Description
There are a number of Monitor/Mutex instances that are initialized with C++ static initialization statements. This means they execute when the JVM library is loaded and before any JVM initialization of any sort has occurred. This is only viable for trivial initialization that is independent of all other initialization actions that might occur during VM startup.

Proposed changes to mutex/monitor code requires non-trivial initialization at the OS level, which means we need to remove the static initialization of these mutex/monitor instances. (it will likely also need a new very early os::init function after which mutex/monitor initialization can take place.

./share/utilities/decoder.cpp:Mutex*            Decoder::_shared_decoder_lock = new Mutex(Mutex::native, ...
./share/services/diagnosticFramework.cpp:Mutex* DCmdFactory::_dcmdFactory_lock = new Mutex(Mutex::leaf, ...
./share/jfr/periodic/sampling/jfrThreadSampler.cpp:Monitor* JfrThreadSampler::_transition_block_lock = new Monitor(Mutex::leaf, ...
./share/runtime/sweeper.cpp:Monitor* NMethodSweeper::_stat_lock = new Monitor(Mutex::special, ...
./share/gc/shared/parallelCleaning.cpp:Monitor* CodeCacheUnloadingTask::_lock = new Monitor(Mutex::leaf, ...
./share/runtime/threadSMR.cpp:Monitor*              ThreadsSMRSupport::_delete_lock = 
                                                                                 new Monitor(Monitor::special, "Thread_SMR_delete_lock",
Comments
Fix Request (11u) I would like to backport this patch to 11u. It will improve the stability of JVM by eliminating global static initialization non-determinism. It is also needed in order to have JDK-8210832 "Remove sneaky locking in class Monitor" in 11u. The patch does not apply cleanly to 11u. The conflicts are because patched files parallelCleaning.hpp and parallelCleaning.cpp have different paths in 11u and git struggles to position some changes. Also the changes to parallelCleaning.hpp and parallelCleaning.cpp remove a lock object, assuming it is not used, but the object is used in 11u (see review discussion for details). The original changes are not changed after resolution of the conflicts. As a result of review CodeCacheUnloadingTask::_lock/G1CodeCacheUnloadingTask::_lock global static initializations were found. They will be addressed in the backport of JDK-8213723. The patch to 11u has been reviewed.
17-06-2021

Most Monitor/mutex instances are declared as global objects in mutexLocker.cpp and initialized in mutex_init(), called by vm_init_globals() during the create_vm process. We can relocate static monitors/mutexes to the global list if the initialization is early enough. - NMethodSweeper::_stat_lock becomes NMethodSweeper_stat_lock Only used by the sweeper thread which is only created by Compilation_init_phase1() which happens after vm_init_globals. - JfrThreadSampler::transition_blokc_lock becomes JfrThreadSampler_lock Used by the JFRThreadSampler threads which are only started from Java code so initialization must happen before we start executing java code - which it is. - CodeCacheUnloadingTask::_lock becomes CodeCacheUnloadingTask_lock Used by GC worker threads so needs t be initialized before the heap, which happens in universe_init, which is called from init_globals, which happen after vm_init_globals. - ThreadsSMRSupport::_delete_lock becomes ThreadsSMRSupport_delete_lock Needs to be initialized before the first thread can call ThreadSMR::delete, which is after the main thread is attached, which is after vm_init_globals. - Decoder::_shared_decoder_lock becomes Decoder_shared_decoder_lock It's used during normal execution (not error reporting) so must be initialized before other threads are created, which it is. - DCmdFactory::_dcmdFactory_lock becomes DCmdFactory_lock It used to serialize DCmdFacory management, after the VM has been initialized and can respond to DCmds.
04-11-2018

It appears that after JDK-8209189 the CodeCacheUnloadingTask::_lock is unused and so can be removed rather than relocated.
04-11-2018