--- old/src/hotspot/share/gc/shared/concurrentGCThread.cpp 2019-06-25 21:47:12.317239681 +0200 +++ new/src/hotspot/share/gc/shared/concurrentGCThread.cpp 2019-06-25 21:47:12.169240214 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -55,13 +55,6 @@ assert(this == Thread::current(), "just checking"); } -void ConcurrentGCThread::wait_for_universe_init() { - MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag); - while (!is_init_completed() && !_should_terminate) { - CGC_lock->wait(Mutex::_no_safepoint_check_flag, 1); - } -} - void ConcurrentGCThread::terminate() { assert(_should_terminate, "Should only be called on terminate request."); // Signal that it is terminated @@ -75,7 +68,7 @@ void ConcurrentGCThread::run() { initialize_in_thread(); - wait_for_universe_init(); + wait_init_completed(); run_service(); --- old/src/hotspot/share/runtime/init.cpp 2019-06-25 21:47:12.917237522 +0200 +++ new/src/hotspot/share/runtime/init.cpp 2019-06-25 21:47:12.769238054 +0200 @@ -34,6 +34,7 @@ #include "runtime/handles.inline.hpp" #include "runtime/icache.hpp" #include "runtime/init.hpp" +#include "runtime/orderAccess.hpp" #include "runtime/safepoint.hpp" #include "runtime/sharedRuntime.hpp" #include "services/memTracker.hpp" @@ -180,11 +181,19 @@ static volatile bool _init_completed = false; bool is_init_completed() { - return _init_completed; + return OrderAccess::load_acquire(&_init_completed); } +void wait_init_completed() { + MonitorLockerEx ml(InitCompleted_lock, Monitor::_no_safepoint_check_flag); + while (!_init_completed) { + ml.wait(Monitor::_no_safepoint_check_flag); + } +} void set_init_completed() { assert(Universe::is_fully_initialized(), "Should have completed initialization"); - _init_completed = true; + MonitorLockerEx ml(InitCompleted_lock, Monitor::_no_safepoint_check_flag); + OrderAccess::release_store(&_init_completed, true); + ml.notify_all(); } --- old/src/hotspot/share/runtime/init.hpp 2019-06-25 21:47:13.521235351 +0200 +++ new/src/hotspot/share/runtime/init.hpp 2019-06-25 21:47:13.373235883 +0200 @@ -40,6 +40,7 @@ void exit_globals(); // call destructors before exit bool is_init_completed(); // returns true when bootstrapping has completed +void wait_init_completed(); // wait until set_init_completed() has been called void set_init_completed(); // set basic init to completed #endif // SHARE_VM_RUNTIME_INIT_HPP --- old/src/hotspot/share/runtime/mutexLocker.cpp 2019-06-25 21:47:14.109233240 +0200 +++ new/src/hotspot/share/runtime/mutexLocker.cpp 2019-06-25 21:47:13.965233756 +0200 @@ -99,6 +99,7 @@ Mutex* DirectivesStack_lock = NULL; Mutex* MultiArray_lock = NULL; Monitor* Terminator_lock = NULL; +Monitor* InitCompleted_lock = NULL; Monitor* BeforeExit_lock = NULL; Monitor* Notify_lock = NULL; Mutex* ProfilePrint_lock = NULL; @@ -261,6 +262,7 @@ def(VMOperationRequest_lock , PaddedMonitor, nonleaf, true, Monitor::_safepoint_check_sometimes); def(RetData_lock , PaddedMutex , nonleaf, false, Monitor::_safepoint_check_always); def(Terminator_lock , PaddedMonitor, nonleaf, true, Monitor::_safepoint_check_sometimes); + def(InitCompleted_lock , PaddedMonitor, leaf, true, Monitor::_safepoint_check_never); def(VtableStubs_lock , PaddedMutex , nonleaf, true, Monitor::_safepoint_check_always); def(Notify_lock , PaddedMonitor, nonleaf, true, Monitor::_safepoint_check_always); // OopStorage-based JNI may lock the alloc_locks while releasing a handle, --- old/src/hotspot/share/runtime/mutexLocker.hpp 2019-06-25 21:47:14.713231074 +0200 +++ new/src/hotspot/share/runtime/mutexLocker.hpp 2019-06-25 21:47:14.569231591 +0200 @@ -103,6 +103,7 @@ extern Mutex* DirectivesStack_lock; // a lock held when mutating the dirstack and ref counting directives 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* InitCompleted_lock; // a lock used to signal threads waiting on init completed extern Monitor* BeforeExit_lock; // a lock used to guard cleanups and shutdown hooks extern Monitor* Notify_lock; // a lock used to synchronize the start-up of the vm extern Mutex* ProfilePrint_lock; // a lock used to serialize the printing of profiles