From 519757a5d7f6c2833c46f27d8dc9aa8812b330dc Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Mon, 23 Dec 2024 18:45:56 +0100 Subject: [PATCH 1/2] make Cleaner.clean public --- .../share/classes/jdk/vm/ci/hotspot/Cleaner.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/Cleaner.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/Cleaner.java index b6f4395f055e4..87760efb8a0e8 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/Cleaner.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/Cleaner.java @@ -36,7 +36,7 @@ * referenced by this might be referenced by {@link ResolvedJavaType} which is kept alive by a * {@link WeakReference} so we need equivalent reference strength. */ -abstract class Cleaner extends WeakReference { +public abstract class Cleaner extends WeakReference { /** * Head of linked list of cleaners. @@ -107,7 +107,7 @@ private static synchronized void remove(Cleaner cl) { /** * Remove the cleaners whose referents have become weakly reachable. */ - static void clean() { + public static void clean() { Cleaner c = (Cleaner) queue.poll(); boolean oopHandleCleared = false; while (c != null) { From 24bb39be0234c8b2dba2815247c89d70283fe45c Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Mon, 23 Dec 2024 18:00:00 +0100 Subject: [PATCH 2/2] remove non-native-image build time use of ServiceLoader --- .../vm/ci/hotspot/HotSpotJVMCIRuntime.java | 53 ++++------- .../jdk/vm/ci/hotspot/HotSpotVMConfig.java | 2 +- .../vm/ci/services/JVMCIServiceLocator.java | 28 ++---- .../classes/jdk/vm/ci/services/Services.java | 89 ------------------- .../events/JvmciShutdownEventListener.java | 12 +-- .../jvmci/events/JvmciShutdownEventTest.java | 8 +- 6 files changed, 38 insertions(+), 154 deletions(-) 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 bc221c46717fa..0943b0f816230 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 @@ -23,7 +23,6 @@ package jdk.vm.ci.hotspot; import static jdk.vm.ci.common.InitTimer.timer; -import static jdk.vm.ci.services.Services.IS_BUILDING_NATIVE_IMAGE; import static jdk.vm.ci.services.Services.IS_IN_NATIVE_IMAGE; import java.io.IOException; @@ -453,33 +452,26 @@ static void parse(HotSpotJVMCIRuntime runtime) { } } - private static HotSpotJVMCIBackendFactory findFactory(String architecture) { - Iterable factories = getHotSpotJVMCIBackendFactories(); - assert factories != null : "sanity"; - for (HotSpotJVMCIBackendFactory factory : factories) { - if (factory.getArchitecture().equalsIgnoreCase(architecture)) { - return factory; + /** + * The backend factory for the JVMCI shared library. + */ + private static final HotSpotJVMCIBackendFactory backendFactory; + static { + String arch = HotSpotVMConfig.getHostArchitectureName(); + HotSpotJVMCIBackendFactory selected = null; + for (HotSpotJVMCIBackendFactory factory : ServiceLoader.load(HotSpotJVMCIBackendFactory.class)) { + if (factory.getArchitecture().equalsIgnoreCase(arch)) { + if (selected != null) { + throw new JVMCIError("Multiple factories available for %s: %s and %s", + arch, selected, factory); + } + selected = factory; } } - - throw new JVMCIError("No JVMCI runtime available for the %s architecture", architecture); - } - - private static volatile List cachedHotSpotJVMCIBackendFactories; - - @SuppressFBWarnings(value = "LI_LAZY_INIT_UPDATE_STATIC", justification = "not sure about this") - private static Iterable getHotSpotJVMCIBackendFactories() { - if (IS_IN_NATIVE_IMAGE || cachedHotSpotJVMCIBackendFactories != null) { - return cachedHotSpotJVMCIBackendFactories; + if (selected == null) { + throw new JVMCIError("No JVMCI runtime available for the %s architecture", arch); } - Iterable result = ServiceLoader.load(HotSpotJVMCIBackendFactory.class, ClassLoader.getSystemClassLoader()); - if (IS_BUILDING_NATIVE_IMAGE) { - cachedHotSpotJVMCIBackendFactories = new ArrayList<>(); - for (HotSpotJVMCIBackendFactory factory : result) { - cachedHotSpotJVMCIBackendFactories.add(factory); - } - } - return result; + backendFactory = selected; } /** @@ -587,15 +579,8 @@ private HotSpotJVMCIRuntime() { // Initialize the Option values. Option.parse(this); - String hostArchitecture = config.getHostArchitectureName(); - - HotSpotJVMCIBackendFactory factory; - try (InitTimer t = timer("find factory:", hostArchitecture)) { - factory = findFactory(hostArchitecture); - } - - try (InitTimer t = timer("create JVMCI backend:", hostArchitecture)) { - hostBackend = registerBackend(factory.createJVMCIBackend(this, null)); + try (InitTimer t = timer("create JVMCI backend:", backendFactory.getArchitecture())) { + hostBackend = registerBackend(backendFactory.createJVMCIBackend(this, null)); } compilerFactory = HotSpotJVMCICompilerConfig.getCompilerFactory(this); diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfig.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfig.java index 5d5956a667cc1..e93b98042b62a 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfig.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfig.java @@ -55,7 +55,7 @@ static HotSpotVMConfig config() { * Gets the host architecture name for the purpose of finding the corresponding * {@linkplain HotSpotJVMCIBackendFactory backend}. */ - String getHostArchitectureName() { + static String getHostArchitectureName() { Architecture arch = Architecture.current(); switch (arch) { case X64: return "amd64"; diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/services/JVMCIServiceLocator.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/services/JVMCIServiceLocator.java index c155c9c861393..265b8c24f3e23 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/services/JVMCIServiceLocator.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/services/JVMCIServiceLocator.java @@ -22,8 +22,6 @@ */ package jdk.vm.ci.services; -import static jdk.vm.ci.services.Services.IS_BUILDING_NATIVE_IMAGE; - import java.util.ArrayList; import java.util.List; import java.util.ServiceLoader; @@ -71,24 +69,12 @@ protected JVMCIServiceLocator() { */ protected abstract S getProvider(Class service); - private static volatile List cachedLocators; - - private static Iterable getJVMCIServiceLocators() { - Iterable result = cachedLocators; - if (result != null) { - return result; - } - result = ServiceLoader.load(JVMCIServiceLocator.class, ClassLoader.getSystemClassLoader()); - if (IS_BUILDING_NATIVE_IMAGE) { - ArrayList l = new ArrayList<>(); - for (JVMCIServiceLocator locator : result) { - l.add(locator); - } - l.trimToSize(); - cachedLocators = l; - return l; - } - return result; + /** + * The available set of locators. + */ + private static final List locators = new ArrayList<>(); + static { + ServiceLoader.load(JVMCIServiceLocator.class).forEach(locators::add); } /** @@ -106,7 +92,7 @@ public static List getProviders(Class service) { sm.checkPermission(new JVMCIPermission()); } List providers = new ArrayList<>(); - for (JVMCIServiceLocator access : getJVMCIServiceLocators()) { + for (JVMCIServiceLocator access : locators) { S provider = access.getProvider(service); if (provider != null) { providers.add(provider); diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/services/Services.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/services/Services.java index d417100224771..d16a788eb1476 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/services/Services.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/services/Services.java @@ -22,13 +22,10 @@ */ package jdk.vm.ci.services; -import java.util.ArrayList; -import java.util.Formatter; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.ServiceLoader; import java.util.Set; import java.util.function.Consumer; import java.util.function.Supplier; @@ -44,13 +41,6 @@ */ public final class Services { - /** - * Guards code that should be run when building an JVMCI shared library but should be excluded - * from (being compiled into) the library. Such code must be directly guarded by an {@code if} - * statement on this field - the guard cannot be behind a method call. - */ - public static final boolean IS_BUILDING_NATIVE_IMAGE = Boolean.parseBoolean(VM.getSavedProperty("jdk.vm.ci.services.aot")); - /** * Guards code that should only be run in a JVMCI shared library. Such code must be directly * guarded by an {@code if} statement on this field - the guard cannot be behind a method call. @@ -131,34 +121,6 @@ public static void initializeJVMCI() { } } - private static final Map, List> servicesCache = IS_BUILDING_NATIVE_IMAGE ? new HashMap<>() : null; - - @SuppressWarnings("unchecked") - private static Iterable load0(Class service) { - if (IS_IN_NATIVE_IMAGE || IS_BUILDING_NATIVE_IMAGE) { - List list = servicesCache.get(service); - if (list != null) { - return (Iterable) list; - } - if (IS_IN_NATIVE_IMAGE) { - throw new InternalError(String.format("No %s providers found when building native image", service.getName())); - } - } - - Iterable providers = ServiceLoader.load(service, ClassLoader.getSystemClassLoader()); - if (IS_BUILDING_NATIVE_IMAGE) { - synchronized (servicesCache) { - ArrayList providersList = new ArrayList<>(); - for (S provider : providers) { - providersList.add(provider); - } - servicesCache.put(service, providersList); - providers = providersList; - } - } - return providers; - } - /** * Opens all JVMCI packages to {@code otherModule}. */ @@ -175,57 +137,6 @@ static void openJVMCITo(Module otherModule) { } } - /** - * Gets an {@link Iterable} of the JVMCI providers available for a given service. - * - * @throws SecurityException if a security manager is present and it denies - * {@link RuntimePermission}("jvmci") - */ - public static Iterable load(Class service) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new JVMCIPermission()); - } - return load0(service); - } - - /** - * Gets the JVMCI provider for a given service for which at most one provider must be available. - * - * @param service the service whose provider is being requested - * @param required specifies if an {@link InternalError} should be thrown if no provider of - * {@code service} is available - * @throws SecurityException if a security manager is present and it denies - * {@link RuntimePermission}("jvmci") - */ - public static S loadSingle(Class service, boolean required) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new JVMCIPermission()); - } - Iterable providers = load0(service); - - S singleProvider = null; - for (S provider : providers) { - if (singleProvider != null) { - throw new InternalError(String.format("Multiple %s providers found: %s, %s", service.getName(), singleProvider.getClass().getName(), provider.getClass().getName())); - } - singleProvider = provider; - } - if (singleProvider == null && required) { - String javaHome = Services.getSavedProperty("java.home"); - String vmName = Services.getSavedProperty("java.vm.name"); - Formatter errorMessage = new Formatter(); - errorMessage.format("The VM does not expose required service %s.%n", service.getName()); - errorMessage.format("Currently used Java home directory is %s.%n", javaHome); - errorMessage.format("Currently used VM configuration is: %s", vmName); - throw new UnsupportedOperationException(errorMessage.toString()); - } - return singleProvider; - } - /** * Creates a thread-local variable that notifies {@code onThreadTermination} when a thread * terminates and it has been initialized in the terminating thread (even if it was initialized diff --git a/test/hotspot/jtreg/compiler/jvmci/events/JvmciShutdownEventListener.java b/test/hotspot/jtreg/compiler/jvmci/events/JvmciShutdownEventListener.java index 1d855aeb4e5ab..59066126d87ef 100644 --- a/test/hotspot/jtreg/compiler/jvmci/events/JvmciShutdownEventListener.java +++ b/test/hotspot/jtreg/compiler/jvmci/events/JvmciShutdownEventListener.java @@ -31,11 +31,13 @@ public class JvmciShutdownEventListener extends JVMCIServiceLocator implements H public static final String MESSAGE = "Shutdown notified"; public static final String GOT_INTERNAL_ERROR = "Got internal error"; - public static void main(String args[]) { - try { - HotSpotJVMCIRuntime.runtime(); // let's trigger that lazy jvmci init - } catch (Error e) { - System.out.println(GOT_INTERNAL_ERROR); + public static class Main { + public static void main(String args[]) { + try { + HotSpotJVMCIRuntime.runtime(); // let's trigger that lazy jvmci init + } catch (Error e) { + System.out.println(GOT_INTERNAL_ERROR); + } } } diff --git a/test/hotspot/jtreg/compiler/jvmci/events/JvmciShutdownEventTest.java b/test/hotspot/jtreg/compiler/jvmci/events/JvmciShutdownEventTest.java index 0242f548cca58..0f0d34bf2d877 100644 --- a/test/hotspot/jtreg/compiler/jvmci/events/JvmciShutdownEventTest.java +++ b/test/hotspot/jtreg/compiler/jvmci/events/JvmciShutdownEventTest.java @@ -53,11 +53,11 @@ import jdk.test.lib.cli.CommandLineOptionTest; public class JvmciShutdownEventTest { - private final static String[] MESSAGE = new String[]{ + private final static String[] MESSAGE = { JvmciShutdownEventListener.MESSAGE }; - private final static String[] ERROR_MESSAGE = new String[]{ + private final static String[] ERROR_MESSAGE = { JvmciShutdownEventListener.GOT_INTERNAL_ERROR }; @@ -68,7 +68,7 @@ public static void main(String args[]) throws Throwable { "Unexpected output with +EnableJVMCI", ExitCode.OK, addTestVMOptions, "-XX:+UnlockExperimentalVMOptions", "-XX:+EnableJVMCI", "-XX:-UseJVMCICompiler", "-Xbootclasspath/a:.", - JvmciShutdownEventListener.class.getName() + JvmciShutdownEventListener.Main.class.getName() ); CommandLineOptionTest.verifyJVMStartup(ERROR_MESSAGE, MESSAGE, @@ -76,7 +76,7 @@ public static void main(String args[]) throws Throwable { "Unexpected output with -EnableJVMCI", ExitCode.OK, addTestVMOptions, "-XX:+UnlockExperimentalVMOptions", "-XX:-EnableJVMCI", "-XX:-UseJVMCICompiler", "-Xbootclasspath/a:.", - JvmciShutdownEventListener.class.getName() + JvmciShutdownEventListener.Main.class.getName() ); } }