--- old/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/Services.java 2017-04-21 12:14:49.000000000 +0200 +++ new/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/Services.java 2017-04-21 12:14:49.000000000 +0200 @@ -22,167 +22,45 @@ */ package jdk.vm.ci.services; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.util.Formatter; -import java.util.Iterator; -import java.util.ServiceConfigurationError; -import java.util.ServiceLoader; -import java.util.Set; +import java.util.Map; /** - * A mechanism for accessing service providers via JVMCI. + * Provides utilities needed by JVMCI clients. + * + * This class must be compilable on JDK 8 and so use of API added in JDK 9 is made via reflection. */ public final class Services { private Services() { } - private static int getJavaSpecificationVersion() { - String value = System.getProperty("java.specification.version"); - if (value.startsWith("1.")) { - value = value.substring(2); - } - return Integer.parseInt(value); - } - /** - * The integer value corresponding to the value of the {@code java.specification.version} system - * property after any leading {@code "1."} has been stripped. + * Gets an unmodifiable copy of the system properties saved when {@link System} is initialized. */ - public static final int JAVA_SPECIFICATION_VERSION = getJavaSpecificationVersion(); - - // Use reflection so that this compiles on Java 8 - private static final Method getModule; - private static final Method getPackages; - private static final Method addUses; - private static final Method isExported; - private static final Method addExports; - - static { - if (JAVA_SPECIFICATION_VERSION >= 9) { - try { - getModule = Class.class.getMethod("getModule"); - Class moduleClass = getModule.getReturnType(); - getPackages = moduleClass.getMethod("getPackages"); - addUses = moduleClass.getMethod("addUses", Class.class); - isExported = moduleClass.getMethod("isExported", String.class, moduleClass); - addExports = moduleClass.getMethod("addExports", String.class, moduleClass); - } catch (NoSuchMethodException | SecurityException e) { - throw new InternalError(e); - } - } else { - getModule = null; - getPackages = null; - addUses = null; - isExported = null; - addExports = null; - } - } - @SuppressWarnings("unchecked") - static T invoke(Method method, Object receiver, Object... args) { - try { - return (T) method.invoke(receiver, args); - } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { - throw new InternalError(e); - } - } - - /** - * Performs any required security checks and dynamic reconfiguration to allow the module of a - * given class to access the classes in the JVMCI module. - * - * Note: This API uses {@link Class} instead of {@code Module} to provide backwards - * compatibility for JVMCI clients compiled against a JDK release earlier than 9. - * - * @param requestor a class requesting access to the JVMCI module for its module - * @throws SecurityException if a security manager is present and it denies - * {@link JVMCIPermission} - */ - public static void exportJVMCITo(Class requestor) { - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new JVMCIPermission()); - } - if (JAVA_SPECIFICATION_VERSION >= 9) { - Object jvmci = invoke(getModule, Services.class); - Object requestorModule = invoke(getModule, requestor); - if (jvmci != requestorModule) { - Set packages = invoke(getPackages, jvmci); - for (String pkg : packages) { - // Export all JVMCI packages dynamically instead - // of requiring a long list of --add-exports - // options on the JVM command line. - boolean exported = invoke(isExported, jvmci, pkg, requestorModule); - if (!exported) { - invoke(addExports, jvmci, pkg, requestorModule); - } - } - } - } - } - - /** - * 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 JVMCIPermission} - */ - public static Iterable load(Class service) { + public static Map getSavedProperties() { SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission(new JVMCIPermission()); } - if (JAVA_SPECIFICATION_VERSION >= 9) { - Object jvmci = invoke(getModule, Services.class); - invoke(addUses, jvmci, service); + try { + Class vmClass = Class.forName("jdk.internal.misc.VM"); + Method m = vmClass.getMethod("getSavedProperties"); + return (Map) m.invoke(null); + } catch (Exception e) { + throw new InternalError(e); } - - // Restrict JVMCI clients to be on the class path or module path - return ServiceLoader.load(service, ClassLoader.getSystemClassLoader()); } /** - * 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 JVMCIPermission} + * Causes the JVMCI subsystem to be initialized if it isn't already initialized. */ - public static S loadSingle(Class service, boolean required) { - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new JVMCIPermission()); - } - if (JAVA_SPECIFICATION_VERSION >= 9) { - Object jvmci = invoke(getModule, Services.class); - invoke(addUses, jvmci, service); - } - // Restrict JVMCI clients to be on the class path or module path - Iterable providers = ServiceLoader.load(service, ClassLoader.getSystemClassLoader()); - S singleProvider = null; + public static void initializeJVMCI() { try { - for (Iterator it = providers.iterator(); it.hasNext();) { - singleProvider = it.next(); - if (it.hasNext()) { - throw new InternalError(String.format("Multiple %s providers found", service.getName())); - } - } - } catch (ServiceConfigurationError e) { - // If the service is required we will bail out below. - } - if (singleProvider == null && required) { - String javaHome = System.getProperty("java.home"); - String vmName = System.getProperty("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()); + Class.forName("jdk.vm.ci.runtime.JVMCI"); + } catch (ClassNotFoundException e) { + throw new InternalError(e); } - return singleProvider; } }