< prev index next >

src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/Services.java

Print this page

        

@@ -20,169 +20,66 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
 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.
  */
 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.
-     */
-    public static final int JAVA_SPECIFICATION_VERSION = getJavaSpecificationVersion();
+    // This class must be compilable and executable on JDK 8 since it's used in annotation
+    // processors while building JDK 9 so use of API added in JDK 9 is made via reflection.
 
-    // 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;
-        }
+    private Services() {
     }
 
     @SuppressWarnings("unchecked")
-    static <T> T invoke(Method method, Object receiver, Object... args) {
+    private static Map<String, String> initSavedProperties() throws InternalError {
         try {
-            return (T) method.invoke(receiver, args);
-        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+            Class<?> vmClass = Class.forName("jdk.internal.misc.VM");
+            Method m = vmClass.getMethod("getSavedProperties");
+            return (Map<String, String>) m.invoke(null);
+        } catch (Exception e) {
             throw new InternalError(e);
         }
     }
 
+    static final Map<String, String> SAVED_PROPERTIES = initSavedProperties();
+    static final boolean JVMCI_ENABLED = Boolean.parseBoolean(SAVED_PROPERTIES.get("jdk.internal.vm.ci.enabled"));
+
     /**
-     * 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}
+     * Checks that JVMCI is enabled in the VM and throws an error if it isn't.
      */
-    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<String> 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);
-                    }
-                }
-            }
+    static void checkJVMCIEnabled() {
+        if (!JVMCI_ENABLED) {
+            throw new Error("The EnableJVMCI VM option must be true (i.e., -XX:+EnableJVMCI) to use JVMCI");
         }
     }
 
     /**
-     * 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}
+     * Gets an unmodifiable copy of the system properties saved when {@link System} is initialized.
      */
-    public static <S> Iterable<S> load(Class<S> service) {
+    public static Map<String, String> getSavedProperties() {
+        checkJVMCIEnabled();
         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
-        return ServiceLoader.load(service, ClassLoader.getSystemClassLoader());
+        return SAVED_PROPERTIES;
     }
 
     /**
-     * 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> S loadSingle(Class<S> 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<S> providers = ServiceLoader.load(service, ClassLoader.getSystemClassLoader());
-        S singleProvider = null;
+    public static void initializeJVMCI() {
+        checkJVMCIEnabled();
         try {
-            for (Iterator<S> 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;
     }
 }
< prev index next >