--- old/src/hotspot/share/gc/shared/concurrentGCThread.cpp 2019-03-25 09:37:49.629481010 +0100 +++ new/src/hotspot/share/gc/shared/concurrentGCThread.cpp 2019-03-25 09:37:49.415474095 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, 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 @@ -54,13 +54,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 @@ -74,7 +67,7 @@ void ConcurrentGCThread::run() { initialize_in_thread(); - wait_for_universe_init(); + wait_init_completed(); run_service(); --- old/src/hotspot/share/runtime/init.cpp 2019-03-25 09:37:49.961491738 +0100 +++ new/src/hotspot/share/runtime/init.cpp 2019-03-25 09:37:49.741484629 +0100 @@ -36,6 +36,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" @@ -186,11 +187,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-03-25 09:37:50.291502401 +0100 +++ new/src/hotspot/share/runtime/init.hpp 2019-03-25 09:37:50.069495227 +0100 @@ -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_RUNTIME_INIT_HPP --- old/src/hotspot/share/runtime/mutexLocker.cpp 2019-03-25 09:37:50.624513161 +0100 +++ new/src/hotspot/share/runtime/mutexLocker.cpp 2019-03-25 09:37:50.404506052 +0100 @@ -97,6 +97,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; @@ -283,6 +284,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_never); def(Notify_lock , PaddedMonitor, nonleaf, true, Monitor::_safepoint_check_always); def(JNIGlobalAlloc_lock , PaddedMutex , nonleaf, true, Monitor::_safepoint_check_never); --- old/src/hotspot/share/runtime/mutexLocker.hpp 2019-03-25 09:37:50.966524212 +0100 +++ new/src/hotspot/share/runtime/mutexLocker.hpp 2019-03-25 09:37:50.743517006 +0100 @@ -96,6 +96,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