diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java index 02ed11cae2a..1f2276757c5 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java @@ -49,6 +49,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.ServiceLoader; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Predicate; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -509,18 +510,7 @@ public final class HotSpotJVMCIRuntime implements JVMCIRuntime { private final Map, JVMCIBackend> backends = new HashMap<>(); - private volatile List vmEventListeners; - - private Iterable getVmEventListeners() { - if (vmEventListeners == null) { - synchronized (this) { - if (vmEventListeners == null) { - vmEventListeners = JVMCIServiceLocator.getProviders(HotSpotVMEventListener.class); - } - } - } - return vmEventListeners; - } + private final List vmEventListeners; @SuppressWarnings("try") private HotSpotJVMCIRuntime() { @@ -580,6 +570,8 @@ public final class HotSpotJVMCIRuntime implements JVMCIRuntime { if (Option.PrintConfig.getBoolean()) { configStore.printConfig(this); } + + vmEventListeners = JVMCIServiceLocator.getProviders(HotSpotVMEventListener.class); } /** @@ -938,22 +930,21 @@ public final class HotSpotJVMCIRuntime implements JVMCIRuntime { } /** - * Guard to ensure shut down actions are performed at most once. + * Guard to ensure shut down actions are performed by at most one thread. */ - private boolean isShutdown; + private final AtomicBoolean isShutdown = new AtomicBoolean(); /** * Shuts down the runtime. */ @VMEntryPoint - private synchronized void shutdown() throws Exception { - if (!isShutdown) { - isShutdown = true; + private void shutdown() throws Exception { + if (isShutdown.compareAndSet(false, true)) { // Cleaners are normally only processed when a new Cleaner is // instantiated so process all remaining cleaners now. Cleaner.clean(); - for (HotSpotVMEventListener vmEventListener : getVmEventListeners()) { + for (HotSpotVMEventListener vmEventListener : vmEventListeners) { vmEventListener.notifyShutdown(); } } @@ -964,7 +955,7 @@ public final class HotSpotJVMCIRuntime implements JVMCIRuntime { */ @VMEntryPoint private void bootstrapFinished() throws Exception { - for (HotSpotVMEventListener vmEventListener : getVmEventListeners()) { + for (HotSpotVMEventListener vmEventListener : vmEventListeners) { vmEventListener.notifyBootstrapFinished(); } } @@ -977,7 +968,7 @@ public final class HotSpotJVMCIRuntime implements JVMCIRuntime { * @param compiledCode */ void notifyInstall(HotSpotCodeCacheProvider hotSpotCodeCacheProvider, InstalledCode installedCode, CompiledCode compiledCode) { - for (HotSpotVMEventListener vmEventListener : getVmEventListeners()) { + for (HotSpotVMEventListener vmEventListener : vmEventListeners) { vmEventListener.notifyInstall(hotSpotCodeCacheProvider, installedCode, compiledCode); } }