-
Notifications
You must be signed in to change notification settings - Fork 5.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
8346781: [JVMCI] Limit ServiceLoader to class initializers #22869
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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")); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This field is no longer used in JVMCI and I will remove its usages in Graal. |
||
|
||
/** | ||
* 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<Class<?>, List<?>> servicesCache = IS_BUILDING_NATIVE_IMAGE ? new HashMap<>() : null; | ||
|
||
@SuppressWarnings("unchecked") | ||
private static <S> Iterable<S> load0(Class<S> service) { | ||
if (IS_IN_NATIVE_IMAGE || IS_BUILDING_NATIVE_IMAGE) { | ||
List<?> list = servicesCache.get(service); | ||
if (list != null) { | ||
return (Iterable<S>) list; | ||
} | ||
if (IS_IN_NATIVE_IMAGE) { | ||
throw new InternalError(String.format("No %s providers found when building native image", service.getName())); | ||
} | ||
} | ||
|
||
Iterable<S> providers = ServiceLoader.load(service, ClassLoader.getSystemClassLoader()); | ||
if (IS_BUILDING_NATIVE_IMAGE) { | ||
synchronized (servicesCache) { | ||
ArrayList<S> 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 <tt> | ||
* {@link RuntimePermission}("jvmci")</tt> | ||
*/ | ||
public static <S> Iterable<S> load(Class<S> service) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are no usages of this method in JVMCI or Graal. |
||
@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 <tt> | ||
* {@link RuntimePermission}("jvmci")</tt> | ||
*/ | ||
public static <S> S loadSingle(Class<S> service, boolean required) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are no usages of this method in JVMCI or Graal. |
||
@SuppressWarnings("removal") | ||
SecurityManager sm = System.getSecurityManager(); | ||
if (sm != null) { | ||
sm.checkPermission(new JVMCIPermission()); | ||
} | ||
Iterable<S> 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 | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Making this public avoids the need for a method substitution.