--- old/.mx.jvmci/.pydevproject 2017-04-28 11:48:36.000000000 +0200 +++ new/.mx.jvmci/.pydevproject 2017-04-28 11:48:36.000000000 +0200 @@ -3,7 +3,7 @@ Default python 2.7 -/.mx.jvmci +/mx.jvmci /mx --- old/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/EventProvider.java 2017-04-28 11:48:37.000000000 +0200 +++ new/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/EventProvider.java 2017-04-28 11:48:36.000000000 +0200 @@ -24,7 +24,6 @@ import jdk.vm.ci.hotspot.EmptyEventProvider.EmptyCompilationEvent; import jdk.vm.ci.hotspot.EmptyEventProvider.EmptyCompilerFailureEvent; -import jdk.vm.ci.services.JVMCIPermission; /** * Service-provider class for logging compiler related events. --- old/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCICompilerConfig.java 2017-04-28 11:48:37.000000000 +0200 +++ new/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCICompilerConfig.java 2017-04-28 11:48:37.000000000 +0200 @@ -28,9 +28,9 @@ import jdk.vm.ci.runtime.JVMCICompiler; import jdk.vm.ci.runtime.JVMCICompilerFactory; import jdk.vm.ci.runtime.JVMCIRuntime; -import jdk.vm.ci.services.JVMCIServiceLocator; import jdk.vm.ci.services.JVMCIPermission; -import jdk.vm.ci.services.Services; +import jdk.vm.ci.services.JVMCIServiceLocator; +import jdk.vm.ci.services.internal.ReflectionAccessJDK; final class HotSpotJVMCICompilerConfig { @@ -47,7 +47,7 @@ @Override public String getCompilerName() { - return ""; + return "null"; } @Override @@ -73,19 +73,23 @@ JVMCICompilerFactory factory = null; String compilerName = Option.Compiler.getString(); if (compilerName != null) { - for (JVMCICompilerFactory f : JVMCIServiceLocator.getProviders(JVMCICompilerFactory.class)) { - if (f.getCompilerName().equals(compilerName)) { - factory = f; + if (compilerName.isEmpty() || compilerName.equals("null")) { + factory = new DummyCompilerFactory(); + } else { + for (JVMCICompilerFactory f : JVMCIServiceLocator.getProviders(JVMCICompilerFactory.class)) { + if (f.getCompilerName().equals(compilerName)) { + factory = f; + } + } + if (factory == null) { + throw new JVMCIError("JVMCI compiler '%s' not found", compilerName); } - } - if (factory == null) { - throw new JVMCIError("JVMCI compiler '%s' not found", compilerName); } } else { // Auto select a single available compiler for (JVMCICompilerFactory f : JVMCIServiceLocator.getProviders(JVMCICompilerFactory.class)) { if (factory == null) { - Services.exportJVMCITo(f.getClass()); + ReflectionAccessJDK.openJVMCITo(f.getClass()); factory = f; } else { // Multiple factories seen - cancel auto selection --- old/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java 2017-04-28 11:48:38.000000000 +0200 +++ new/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java 2017-04-28 11:48:38.000000000 +0200 @@ -32,6 +32,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.ServiceLoader; import java.util.TreeMap; import jdk.internal.misc.VM; @@ -50,7 +51,6 @@ import jdk.vm.ci.runtime.JVMCICompiler; import jdk.vm.ci.runtime.JVMCICompilerFactory; import jdk.vm.ci.services.JVMCIServiceLocator; -import jdk.vm.ci.services.Services; /** * HotSpot implementation of a JVMCI runtime. @@ -88,7 +88,10 @@ */ public enum Option { // @formatter:off - Compiler(String.class, null, "Selects the system compiler."), + Compiler(String.class, null, "Selects the system compiler. This must match the getCompilerName() value returned " + + "by a jdk.vm.ci.runtime.JVMCICompilerFactory provider. " + + "An empty string or the value \"null\" selects a compiler " + + "that will raise an exception upon receiving a compilation request."), // Note: The following one is not used (see InitTimer.ENABLED). It is added here // so that -XX:+JVMCIPrintProperties shows the option. InitTimer(Boolean.class, false, "Specifies if initialization timing is enabled."), @@ -208,7 +211,7 @@ } public static HotSpotJVMCIBackendFactory findFactory(String architecture) { - for (HotSpotJVMCIBackendFactory factory : Services.load(HotSpotJVMCIBackendFactory.class)) { + for (HotSpotJVMCIBackendFactory factory : ServiceLoader.load(HotSpotJVMCIBackendFactory.class, ClassLoader.getSystemClassLoader())) { if (factory.getArchitecture().equalsIgnoreCase(architecture)) { return factory; } --- old/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMemoryAccessProviderImpl.java 2017-04-28 11:48:39.000000000 +0200 +++ new/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMemoryAccessProviderImpl.java 2017-04-28 11:48:38.000000000 +0200 @@ -98,7 +98,7 @@ boolean aligned = ((displacement - headerSize) % sizeOfElement) == 0; if (displacement < 0 || displacement > (arrayEnd - sizeOfElement) || (kind == JavaKind.Object && !aligned)) { int index = (int) ((displacement - headerSize) / sizeOfElement); - throw new AssertionError("Unsafe array access: reading element of kind " + kind + + throw new IllegalArgumentException("Unsafe array access: reading element of kind " + kind + " at offset " + displacement + " (index ~ " + index + ") in " + type.toJavaName() + " object of length " + length); } --- old/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java 2017-04-28 11:48:39.000000000 +0200 +++ new/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java 2017-04-28 11:48:39.000000000 +0200 @@ -801,8 +801,7 @@ } if (elementType.getName().startsWith("Ljava/")) { // Classes in a java.* package can only be defined by the - // boot class loader. This is enforced by ClassLoader.preDefineClass() - assert mirror().getClassLoader() == null; + // boot or platform class loader. return true; } ClassLoader thisCl = mirror().getClassLoader(); --- old/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/JVMCIServiceLocator.java 2017-04-28 11:48:40.000000000 +0200 +++ new/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/JVMCIServiceLocator.java 2017-04-28 11:48:40.000000000 +0200 @@ -24,12 +24,15 @@ import java.util.ArrayList; import java.util.List; +import java.util.ServiceLoader; + +import jdk.vm.ci.services.internal.ReflectionAccessJDK; /** * Service-provider class for the runtime to locate providers of JVMCI services where the latter are - * not in packages exported by the JVMCI module. As part of instantiating - * {@link JVMCIServiceLocator}, all JVMCI packages will be {@linkplain Services#exportJVMCITo(Class) - * exported} to the module defining the class of the instantiated object. + * not in packages exported by the JVMCI module. As part of instantiating a + * {@link JVMCIServiceLocator}, all JVMCI packages will be opened to the module defining the class + * of the instantiated object. * * While the {@link #getProvider(Class)} method can be used directly, it's usually easier to use * {@link #getProviders(Class)}. @@ -49,30 +52,39 @@ } /** - * Creates a capability for accessing JVMCI. Once successfully instantiated, JVMCI exports all - * its packages to the module defining the type of this object. + * Creates a capability for accessing JVMCI. Once successfully instantiated, JVMCI opens all its + * packages to the module defining the type of this object. * * @throws SecurityException if a security manager has been installed and it denies * {@link JVMCIPermission} */ protected JVMCIServiceLocator() { this(checkPermission()); - Services.exportJVMCITo(getClass()); + Services.checkJVMCIEnabled(); + ReflectionAccessJDK.openJVMCITo(getClass()); } /** * Gets the provider of the service defined by {@code service} or {@code null} if this object * does not have a provider for {@code service}. */ - public abstract S getProvider(Class service); + protected abstract S getProvider(Class service); /** - * Gets the providers of the service defined by {@code service} by querying the - * {@link JVMCIServiceLocator} providers obtained by {@link Services#load(Class)}. + * Gets the providers of the service defined by {@code service} by querying the available + * {@link JVMCIServiceLocator} providers. + * + * @throws SecurityException if a security manager is present and it denies + * {@link JVMCIPermission} */ public static List getProviders(Class service) { + Services.checkJVMCIEnabled(); + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkPermission(new JVMCIPermission()); + } List providers = new ArrayList<>(); - for (JVMCIServiceLocator access : Services.load(JVMCIServiceLocator.class)) { + for (JVMCIServiceLocator access : ServiceLoader.load(JVMCIServiceLocator.class, ClassLoader.getSystemClassLoader())) { S provider = access.getProvider(service); if (provider != null) { providers.add(provider); --- old/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/Services.java 2017-04-28 11:48:41.000000000 +0200 +++ new/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/Services.java 2017-04-28 11:48:40.000000000 +0200 @@ -22,167 +22,64 @@ */ 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 invoke(Method method, Object receiver, Object... args) { + private static Map 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) m.invoke(null); + } catch (Exception e) { throw new InternalError(e); } } + static final Map 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 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 Iterable load(Class service) { + public static Map 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 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() { + checkJVMCIEnabled(); 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; } } --- old/src/jdk.internal.vm.ci/share/classes/module-info.java 2017-04-28 11:48:41.000000000 +0200 +++ new/src/jdk.internal.vm.ci/share/classes/module-info.java 2017-04-28 11:48:41.000000000 +0200 @@ -33,37 +33,4 @@ jdk.vm.ci.hotspot.aarch64.AArch64HotSpotJVMCIBackendFactory, jdk.vm.ci.hotspot.amd64.AMD64HotSpotJVMCIBackendFactory, jdk.vm.ci.hotspot.sparc.SPARCHotSpotJVMCIBackendFactory; - - exports jdk.vm.ci.aarch64 to - jdk.internal.vm.compiler; - exports jdk.vm.ci.amd64 to - jdk.aot, - jdk.internal.vm.compiler; - exports jdk.vm.ci.code to - jdk.aot, - jdk.internal.vm.compiler; - exports jdk.vm.ci.code.site to - jdk.aot, - jdk.internal.vm.compiler; - exports jdk.vm.ci.code.stack to - jdk.internal.vm.compiler; - exports jdk.vm.ci.common to - jdk.internal.vm.compiler; - exports jdk.vm.ci.hotspot to - jdk.aot, - jdk.internal.vm.compiler; - exports jdk.vm.ci.hotspot.aarch64 to - jdk.internal.vm.compiler; - exports jdk.vm.ci.hotspot.amd64 to - jdk.internal.vm.compiler; - exports jdk.vm.ci.hotspot.sparc to - jdk.internal.vm.compiler; - exports jdk.vm.ci.meta to - jdk.aot, - jdk.internal.vm.compiler; - exports jdk.vm.ci.runtime to - jdk.aot, - jdk.internal.vm.compiler; - exports jdk.vm.ci.sparc to - jdk.internal.vm.compiler; } --- old/src/jdk.internal.vm.compiler/.mx.graal/.pydevproject 2017-04-28 11:48:42.000000000 +0200 +++ new/src/jdk.internal.vm.compiler/.mx.graal/.pydevproject 2017-04-28 11:48:42.000000000 +0200 @@ -3,9 +3,9 @@ Default python 2.7 -/mx.graal -/mx.graal -/mx.graal +/.mx.graal +/.mx.graal +/.mx.graal --- old/src/jdk.internal.vm.compiler/.mx.graal/suite.py 2017-04-28 11:48:43.000000000 +0200 +++ new/src/jdk.internal.vm.compiler/.mx.graal/suite.py 2017-04-28 11:48:43.000000000 +0200 @@ -8,6 +8,36 @@ # (e.g., macosx-x86_64-normal-server-release). "outputRoot" : "../../../build/mx/hotspot", + "jdklibraries" : { + "JVMCI_SERVICES" : { + "path" : "lib/jvmci-services.jar", + "sourcePath" : "lib/jvmci-services.src.zip", + "optional" : False, + "jdkStandardizedSince" : "9", + "module" : "jdk.internal.vm.ci" + }, + "JVMCI_API" : { + "path" : "lib/jvmci/jvmci-api.jar", + "sourcePath" : "lib/jvmci/jvmci-api.src.zip", + "dependencies" : [ + "JVMCI_SERVICES", + ], + "optional" : False, + "jdkStandardizedSince" : "9", + "module" : "jdk.internal.vm.ci" + }, + "JVMCI_HOTSPOT" : { + "path" : "lib/jvmci/jvmci-hotspot.jar", + "sourcePath" : "lib/jvmci/jvmci-hotspot.src.zip", + "dependencies" : [ + "JVMCI_API", + ], + "optional" : False, + "jdkStandardizedSince" : "9", + "module" : "jdk.internal.vm.ci" + }, + }, + "libraries" : { # ------------- Libraries ------------- @@ -17,6 +47,16 @@ "sha1" : "476d9a44cd19d6b55f81571077dfa972a4f8a083", "bootClassPathAgent" : "true", }, + "ASM5" : { + "sha1" : "0da08b8cce7bbf903602a25a3a163ae252435795", + "urls" : ["https://lafo.ssw.uni-linz.ac.at/pub/graal-external-deps/asm-5.0.4.jar"], + }, + + "ASM_TREE5" : { + "sha1" : "396ce0c07ba2b481f25a70195c7c94922f0d1b0b", + "urls" : ["https://lafo.ssw.uni-linz.ac.at/pub/graal-external-deps/asm-tree-5.0.4.jar"], + "dependencies" : ["ASM5"], + }, }, "projects" : { @@ -32,6 +72,7 @@ "org.graalvm.compiler.serviceprovider" : { "subDir" : "share/classes", + "dependencies" : ["JVMCI_SERVICES"], "sourceDirs" : ["src"], "checkstyle" : "org.graalvm.compiler.graph", "javaCompliance" : "1.8", @@ -49,6 +90,7 @@ "org.graalvm.compiler.options" : { "subDir" : "share/classes", + "dependencies" : ["JVMCI_SERVICES", "JVMCI_API"], "sourceDirs" : ["src"], "checkstyle" : "org.graalvm.compiler.graph", "javaCompliance" : "1.8", @@ -83,6 +125,7 @@ "sourceDirs" : ["src"], "checkstyle" : "org.graalvm.compiler.graph", "dependencies" : [ + "JVMCI_API", "org.graalvm.compiler.serviceprovider", "org.graalvm.compiler.options" ], @@ -137,6 +180,7 @@ "sourceDirs" : ["src"], "checkstyle" : "org.graalvm.compiler.graph", "dependencies" : [ + "JVMCI_HOTSPOT", "org.graalvm.compiler.core.test", ], "javaCompliance" : "1.8", @@ -146,6 +190,9 @@ "org.graalvm.compiler.api.runtime" : { "subDir" : "share/classes", "sourceDirs" : ["src"], + "dependencies" : [ + "JVMCI_API", + ], "checkstyle" : "org.graalvm.compiler.graph", "javaCompliance" : "1.8", "workingSets" : "API,Graal", @@ -156,6 +203,7 @@ "sourceDirs" : ["src"], "dependencies" : [ "mx:JUNIT", + "JVMCI_SERVICES", "org.graalvm.compiler.api.runtime", ], "checkstyle" : "org.graalvm.compiler.graph", @@ -166,6 +214,7 @@ "org.graalvm.compiler.api.replacements" : { "subDir" : "share/classes", "sourceDirs" : ["src"], + "dependencies" : ["JVMCI_API"], "checkstyle" : "org.graalvm.compiler.graph", "javaCompliance" : "1.8", "workingSets" : "API,Graal,Replacements", @@ -175,6 +224,7 @@ "subDir" : "share/classes", "sourceDirs" : ["src"], "dependencies" : [ + "JVMCI_HOTSPOT", "org.graalvm.compiler.api.runtime", "org.graalvm.compiler.replacements", "org.graalvm.compiler.runtime", @@ -261,6 +311,8 @@ "org.graalvm.compiler.hotspot", "org.graalvm.compiler.lir.jtt", "org.graalvm.compiler.lir.test", + "JVMCI_API", + "JVMCI_HOTSPOT", ], "checkstyle" : "org.graalvm.compiler.graph", "javaCompliance" : "1.8", @@ -347,6 +399,9 @@ "org.graalvm.compiler.asm" : { "subDir" : "share/classes", "sourceDirs" : ["src"], + "dependencies" : [ + "JVMCI_API", + ], "checkstyle" : "org.graalvm.compiler.graph", "javaCompliance" : "1.8", "workingSets" : "Graal,Assembler", @@ -403,6 +458,7 @@ "org.graalvm.compiler.bytecode" : { "subDir" : "share/classes", "sourceDirs" : ["src"], + "dependencies" : ["JVMCI_API"], "checkstyle" : "org.graalvm.compiler.graph", "javaCompliance" : "1.8", "workingSets" : "Graal,Java", @@ -774,6 +830,7 @@ "dependencies" : [ "org.graalvm.compiler.lir.jtt", "org.graalvm.compiler.lir.aarch64", + "JVMCI_HOTSPOT" ], "checkstyle" : "org.graalvm.compiler.graph", "javaCompliance" : "1.8", @@ -803,6 +860,7 @@ "dependencies" : [ "org.graalvm.compiler.lir.jtt", "org.graalvm.compiler.lir.amd64", + "JVMCI_HOTSPOT" ], "checkstyle" : "org.graalvm.compiler.graph", "javaCompliance" : "1.8", @@ -831,6 +889,7 @@ "sourceDirs" : ["src"], "dependencies" : [ "org.graalvm.compiler.lir.jtt", + "JVMCI_HOTSPOT" ], "checkstyle" : "org.graalvm.compiler.graph", "javaCompliance" : "1.8", @@ -908,6 +967,7 @@ "org.graalvm.compiler.graph.test", "org.graalvm.compiler.printer", "JAVA_ALLOCATION_INSTRUMENTER", + "ASM_TREE5", ], "annotationProcessors" : ["GRAAL_NODEINFO_PROCESSOR"], "checkstyle" : "org.graalvm.compiler.graph", --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.test/src/org/graalvm/compiler/api/test/Graal.java 2017-04-28 11:48:44.000000000 +0200 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.test/src/org/graalvm/compiler/api/test/Graal.java 2017-04-28 11:48:44.000000000 +0200 @@ -40,7 +40,7 @@ private static final GraalRuntime runtime = initializeRuntime(); private static GraalRuntime initializeRuntime() { - Services.exportJVMCITo(Graal.class); + Services.initializeJVMCI(); JVMCICompiler compiler = JVMCI.getRuntime().getCompiler(); if (compiler instanceof GraalJVMCICompiler) { GraalJVMCICompiler graal = (GraalJVMCICompiler) compiler; --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/util/ModuleAPI.java 2017-04-28 11:48:45.000000000 +0200 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/util/ModuleAPI.java 2017-04-28 11:48:45.000000000 +0200 @@ -53,11 +53,6 @@ public static final ModuleAPI getModule; /** - * {@code jdk.internal.module.Modules.addExports(Module, String, Module)}. - */ - public static final ModuleAPI addExports; - - /** * {@code java.lang.Module.getResourceAsStream(String)}. */ public static final ModuleAPI getResourceAsStream; @@ -116,13 +111,11 @@ try { getModule = new ModuleAPI(Class.class.getMethod("getModule")); Class moduleClass = getModule.method.getReturnType(); - Class modulesClass = Class.forName("jdk.internal.module.Modules"); getResourceAsStream = new ModuleAPI(moduleClass.getMethod("getResourceAsStream", String.class)); canRead = new ModuleAPI(moduleClass.getMethod("canRead", moduleClass)); isExported = new ModuleAPI(moduleClass.getMethod("isExported", String.class)); isExportedTo = new ModuleAPI(moduleClass.getMethod("isExported", String.class, moduleClass)); - addExports = new ModuleAPI(modulesClass.getDeclaredMethod("addExports", moduleClass, String.class, moduleClass)); - } catch (NoSuchMethodException | SecurityException | ClassNotFoundException e) { + } catch (NoSuchMethodException | SecurityException e) { throw new InternalError(e); } } else { @@ -132,8 +125,6 @@ canRead = unavailable; isExported = unavailable; isExportedTo = unavailable; - addExports = unavailable; } - } } --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CheckGraalInvariants.java 2017-04-28 11:48:46.000000000 +0200 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CheckGraalInvariants.java 2017-04-28 11:48:45.000000000 +0200 @@ -127,7 +127,7 @@ MetaAccessProvider metaAccess = providers.getMetaAccess(); PhaseSuite graphBuilderSuite = new PhaseSuite<>(); - Plugins plugins = new Plugins(new InvocationPlugins(metaAccess)); + Plugins plugins = new Plugins(new InvocationPlugins()); GraphBuilderConfiguration config = GraphBuilderConfiguration.getDefault(plugins).withEagerResolving(true); graphBuilderSuite.appendPhase(new GraphBuilderPhase(config)); HighTierContext context = new HighTierContext(providers, graphBuilderSuite, OptimisticOptimizations.NONE); --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/InterfaceMethodHandleTest.java 2017-04-28 11:48:46.000000000 +0200 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/InterfaceMethodHandleTest.java 2017-04-28 11:48:46.000000000 +0200 @@ -26,15 +26,14 @@ import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; -import org.junit.Test; - import org.graalvm.compiler.code.CompilationResult; import org.graalvm.compiler.test.ExportingClassLoader; +import org.junit.Test; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.Label; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; -import jdk.internal.org.objectweb.asm.ClassWriter; -import jdk.internal.org.objectweb.asm.Label; -import jdk.internal.org.objectweb.asm.MethodVisitor; -import jdk.internal.org.objectweb.asm.Opcodes; import jdk.vm.ci.code.InstalledCode; import jdk.vm.ci.meta.ResolvedJavaMethod; --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/OptionsVerifierTest.java 2017-04-28 11:48:47.000000000 +0200 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/OptionsVerifierTest.java 2017-04-28 11:48:47.000000000 +0200 @@ -44,19 +44,17 @@ import java.util.ServiceLoader; import java.util.Set; -import org.junit.Test; - import org.graalvm.compiler.options.OptionDescriptor; import org.graalvm.compiler.options.OptionDescriptors; import org.graalvm.compiler.options.OptionValue; import org.graalvm.compiler.test.GraalTest; - -import jdk.internal.org.objectweb.asm.ClassReader; -import jdk.internal.org.objectweb.asm.ClassVisitor; -import jdk.internal.org.objectweb.asm.Label; -import jdk.internal.org.objectweb.asm.MethodVisitor; -import jdk.internal.org.objectweb.asm.Opcodes; -import jdk.internal.org.objectweb.asm.Type; +import org.junit.Test; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.Label; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.Type; /** * Verifies a class declaring one or more {@linkplain OptionValue options} has a class initializer --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/StaticInterfaceFieldTest.java 2017-04-28 11:48:48.000000000 +0200 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/StaticInterfaceFieldTest.java 2017-04-28 11:48:48.000000000 +0200 @@ -83,7 +83,7 @@ MetaAccessProvider metaAccess = providers.getMetaAccess(); PhaseSuite graphBuilderSuite = new PhaseSuite<>(); - Plugins plugins = new Plugins(new InvocationPlugins(metaAccess)); + Plugins plugins = new Plugins(new InvocationPlugins()); GraphBuilderConfiguration config = GraphBuilderConfiguration.getDefault(plugins).withEagerResolving(true); graphBuilderSuite.appendPhase(new GraphBuilderPhase(config)); HighTierContext context = new HighTierContext(providers, graphBuilderSuite, OptimisticOptimizations.NONE); --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnbalancedMonitorsTest.java 2017-04-28 11:48:49.000000000 +0200 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnbalancedMonitorsTest.java 2017-04-28 11:48:48.000000000 +0200 @@ -24,10 +24,10 @@ import jdk.vm.ci.code.BailoutException; import jdk.vm.ci.meta.ResolvedJavaMethod; -import jdk.internal.org.objectweb.asm.ClassWriter; -import jdk.internal.org.objectweb.asm.Label; -import jdk.internal.org.objectweb.asm.MethodVisitor; -import jdk.internal.org.objectweb.asm.Opcodes; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.Label; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; import static org.graalvm.compiler.core.common.CompilationIdentifier.INVALID_COMPILATION_ID; @@ -86,7 +86,7 @@ ResolvedJavaMethod method = getResolvedJavaMethod(LOADER.findClass(INNER_CLASS_NAME), name); try { StructuredGraph graph = new StructuredGraph(method, AllowAssumptions.NO, INVALID_COMPILATION_ID); - Plugins plugins = new Plugins(new InvocationPlugins(getMetaAccess())); + Plugins plugins = new Plugins(new InvocationPlugins()); GraphBuilderConfiguration graphBuilderConfig = GraphBuilderConfiguration.getDefault(plugins).withEagerResolving(true); OptimisticOptimizations optimisticOpts = OptimisticOptimizations.NONE; --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyBailoutUsageTest.java 2017-04-28 11:48:50.000000000 +0200 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyBailoutUsageTest.java 2017-04-28 11:48:49.000000000 +0200 @@ -122,7 +122,7 @@ Providers providers = rt.getHostBackend().getProviders(); MetaAccessProvider metaAccess = providers.getMetaAccess(); PhaseSuite graphBuilderSuite = new PhaseSuite<>(); - Plugins plugins = new Plugins(new InvocationPlugins(metaAccess)); + Plugins plugins = new Plugins(new InvocationPlugins()); GraphBuilderConfiguration config = GraphBuilderConfiguration.getDefault(plugins).withEagerResolving(true); graphBuilderSuite.appendPhase(new GraphBuilderPhase(config)); HighTierContext context = new HighTierContext(providers, graphBuilderSuite, OptimisticOptimizations.NONE); --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyDebugUsageTest.java 2017-04-28 11:48:50.000000000 +0200 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyDebugUsageTest.java 2017-04-28 11:48:50.000000000 +0200 @@ -300,7 +300,7 @@ Providers providers = rt.getHostBackend().getProviders(); MetaAccessProvider metaAccess = providers.getMetaAccess(); PhaseSuite graphBuilderSuite = new PhaseSuite<>(); - Plugins plugins = new Plugins(new InvocationPlugins(metaAccess)); + Plugins plugins = new Plugins(new InvocationPlugins()); GraphBuilderConfiguration config = GraphBuilderConfiguration.getDefault(plugins).withEagerResolving(true); graphBuilderSuite.appendPhase(new GraphBuilderPhase(config)); HighTierContext context = new HighTierContext(providers, graphBuilderSuite, OptimisticOptimizations.NONE); --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyVirtualizableTest.java 2017-04-28 11:48:51.000000000 +0200 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyVirtualizableTest.java 2017-04-28 11:48:51.000000000 +0200 @@ -267,7 +267,7 @@ Providers providers = rt.getHostBackend().getProviders(); MetaAccessProvider metaAccess = providers.getMetaAccess(); PhaseSuite graphBuilderSuite = new PhaseSuite<>(); - Plugins plugins = new Plugins(new InvocationPlugins(metaAccess)); + Plugins plugins = new Plugins(new InvocationPlugins()); GraphBuilderConfiguration config = GraphBuilderConfiguration.getDefault(plugins).withEagerResolving(true); graphBuilderSuite.appendPhase(new GraphBuilderPhase(config)); HighTierContext context = new HighTierContext(providers, graphBuilderSuite, OptimisticOptimizations.NONE); --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/debug/VerifyMethodMetricsTest.java 2017-04-28 11:48:52.000000000 +0200 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/debug/VerifyMethodMetricsTest.java 2017-04-28 11:48:51.000000000 +0200 @@ -249,7 +249,7 @@ Providers providers = rt.getHostBackend().getProviders(); MetaAccessProvider metaAccess = providers.getMetaAccess(); PhaseSuite graphBuilderSuite = new PhaseSuite<>(); - Plugins plugins = new Plugins(new InvocationPlugins(metaAccess)); + Plugins plugins = new Plugins(new InvocationPlugins()); GraphBuilderConfiguration config = GraphBuilderConfiguration.getDefault(plugins).withEagerResolving(true); graphBuilderSuite.appendPhase(new GraphBuilderPhase(config)); HighTierContext context = new HighTierContext(providers, graphBuilderSuite, OptimisticOptimizations.NONE); --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/tutorial/StaticAnalysis.java 2017-04-28 11:48:52.000000000 +0200 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/tutorial/StaticAnalysis.java 2017-04-28 11:48:52.000000000 +0200 @@ -253,7 +253,7 @@ * the code before static analysis, the classes would otherwise be not loaded * yet and the bytecode parser would only create a graph. */ - Plugins plugins = new Plugins(new InvocationPlugins(metaAccess)); + Plugins plugins = new Plugins(new InvocationPlugins()); GraphBuilderConfiguration graphBuilderConfig = GraphBuilderConfiguration.getDefault(plugins).withEagerResolving(true); /* * For simplicity, we ignore all exception handling during the static analysis. --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java 2017-04-28 11:48:53.000000000 +0200 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java 2017-04-28 11:48:53.000000000 +0200 @@ -29,15 +29,12 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeSet; import java.util.stream.Collectors; -import org.junit.Test; - import org.graalvm.compiler.api.test.Graal; import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider; @@ -45,12 +42,15 @@ import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins; import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin; import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins; +import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Binding; import org.graalvm.compiler.runtime.RuntimeProvider; import org.graalvm.compiler.test.GraalTest; +import org.junit.Test; import jdk.vm.ci.hotspot.HotSpotVMConfigStore; import jdk.vm.ci.hotspot.VMIntrinsicMethod; import jdk.vm.ci.meta.MetaAccessProvider; +import jdk.vm.ci.meta.MetaUtil; import jdk.vm.ci.meta.MethodHandleAccessProvider.IntrinsicMethod; import jdk.vm.ci.meta.ResolvedJavaMethod; @@ -63,11 +63,10 @@ */ public class CheckGraalIntrinsics extends GraalTest { - public static boolean match(ResolvedJavaMethod method, VMIntrinsicMethod intrinsic) { - if (intrinsic.name.equals(method.getName())) { - if (intrinsic.descriptor.equals(method.getSignature().toMethodDescriptor())) { - String declaringClass = method.getDeclaringClass().toClassName().replace('.', '/'); - if (declaringClass.equals(intrinsic.declaringClass)) { + public static boolean match(String type, Binding binding, VMIntrinsicMethod intrinsic) { + if (intrinsic.name.equals(binding.name)) { + if (intrinsic.descriptor.startsWith(binding.argumentsDescriptor)) { + if (type.equals(intrinsic.declaringClass)) { return true; } } @@ -75,16 +74,20 @@ return false; } - private static ResolvedJavaMethod findMethod(Set methods, VMIntrinsicMethod intrinsic) { - for (ResolvedJavaMethod method : methods) { - if (match(method, intrinsic)) { - return method; + public static InvocationPlugin findPlugin(Map> bindings, VMIntrinsicMethod intrinsic) { + for (Map.Entry> e : bindings.entrySet()) { + // Match format of VMIntrinsicMethod.declaringClass + String type = MetaUtil.internalNameToJava(e.getKey(), true, false).replace('.', '/'); + for (Binding binding : e.getValue()) { + if (match(type, binding, intrinsic)) { + return binding.plugin; + } } } return null; } - private static ResolvedJavaMethod resolveIntrinsic(MetaAccessProvider metaAccess, VMIntrinsicMethod intrinsic) throws ClassNotFoundException { + public static ResolvedJavaMethod resolveIntrinsic(MetaAccessProvider metaAccess, VMIntrinsicMethod intrinsic) throws ClassNotFoundException { Class c = Class.forName(intrinsic.declaringClass.replace('/', '.'), false, CheckGraalIntrinsics.class.getClassLoader()); for (Method javaMethod : c.getDeclaredMethods()) { if (javaMethod.getName().equals(intrinsic.name)) { @@ -425,28 +428,20 @@ public void test() throws ClassNotFoundException { HotSpotGraalRuntimeProvider rt = (HotSpotGraalRuntimeProvider) Graal.getRequiredCapability(RuntimeProvider.class); HotSpotProviders providers = rt.getHostBackend().getProviders(); - Map impl = new HashMap<>(); Plugins graphBuilderPlugins = providers.getGraphBuilderPlugins(); InvocationPlugins invocationPlugins = graphBuilderPlugins.getInvocationPlugins(); - for (ResolvedJavaMethod method : invocationPlugins.getMethods()) { - InvocationPlugin plugin = invocationPlugins.lookupInvocation(method); - assert plugin != null; - impl.put(method, plugin); - } - Set methods = invocationPlugins.getMethods(); HotSpotVMConfigStore store = rt.getVMConfig().getStore(); List intrinsics = store.getIntrinsics(); List missing = new ArrayList<>(); + Map> bindings = invocationPlugins.getBindings(true); for (VMIntrinsicMethod intrinsic : intrinsics) { - ResolvedJavaMethod method = findMethod(methods, intrinsic); - if (method == null) { - method = resolveIntrinsic(providers.getMetaAccess(), intrinsic); - - IntrinsicMethod intrinsicMethod = null; + InvocationPlugin plugin = findPlugin(bindings, intrinsic); + if (plugin == null) { + ResolvedJavaMethod method = resolveIntrinsic(providers.getMetaAccess(), intrinsic); if (method != null) { - intrinsicMethod = providers.getConstantReflection().getMethodHandleAccess().lookupMethodHandleIntrinsic(method); + IntrinsicMethod intrinsicMethod = providers.getConstantReflection().getMethodHandleAccess().lookupMethodHandleIntrinsic(method); if (intrinsicMethod != null) { continue; } --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ConstantPoolSubstitutionsTests.java 2017-04-28 11:48:54.000000000 +0200 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ConstantPoolSubstitutionsTests.java 2017-04-28 11:48:54.000000000 +0200 @@ -39,9 +39,9 @@ import org.junit.BeforeClass; import org.junit.Test; -import jdk.internal.org.objectweb.asm.ClassWriter; -import jdk.internal.org.objectweb.asm.MethodVisitor; -import jdk.internal.org.objectweb.asm.Opcodes; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; import jdk.vm.ci.meta.ResolvedJavaMethod; public class ConstantPoolSubstitutionsTests extends GraalCompilerTest implements Opcodes { --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/TestIntrinsicCompiles.java 2017-04-28 11:48:54.000000000 +0200 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/TestIntrinsicCompiles.java 2017-04-28 11:48:54.000000000 +0200 @@ -22,13 +22,12 @@ */ package org.graalvm.compiler.hotspot.test; -import java.util.List; -import java.util.Set; +import static org.graalvm.compiler.core.common.CompilationIdentifier.INVALID_COMPILATION_ID; -import org.junit.Test; +import java.util.List; +import java.util.Map; import org.graalvm.compiler.api.test.Graal; -import org.graalvm.compiler.core.common.CompilationIdentifier; import org.graalvm.compiler.core.test.GraalCompilerTest; import org.graalvm.compiler.hotspot.HotSpotGraalCompiler; import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider; @@ -37,8 +36,10 @@ import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins; import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin; import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins; +import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Binding; import org.graalvm.compiler.nodes.graphbuilderconf.MethodSubstitutionPlugin; import org.graalvm.compiler.runtime.RuntimeProvider; +import org.junit.Test; import jdk.vm.ci.hotspot.HotSpotVMConfigStore; import jdk.vm.ci.hotspot.VMIntrinsicMethod; @@ -50,46 +51,27 @@ */ public class TestIntrinsicCompiles extends GraalCompilerTest { - private static boolean match(ResolvedJavaMethod method, VMIntrinsicMethod intrinsic) { - if (intrinsic.name.equals(method.getName())) { - if (intrinsic.descriptor.equals(method.getSignature().toMethodDescriptor())) { - String declaringClass = method.getDeclaringClass().toClassName().replace('.', '/'); - if (declaringClass.equals(intrinsic.declaringClass)) { - return true; - } - } - } - return false; - } - - private static ResolvedJavaMethod findMethod(Set methods, VMIntrinsicMethod intrinsic) { - for (ResolvedJavaMethod method : methods) { - if (match(method, intrinsic)) { - return method; - } - } - return null; - } - @Test @SuppressWarnings("try") - public void test() { + public void test() throws ClassNotFoundException { HotSpotGraalCompiler compiler = (HotSpotGraalCompiler) JVMCI.getRuntime().getCompiler(); HotSpotGraalRuntimeProvider rt = (HotSpotGraalRuntimeProvider) Graal.getRequiredCapability(RuntimeProvider.class); HotSpotProviders providers = rt.getHostBackend().getProviders(); Plugins graphBuilderPlugins = providers.getGraphBuilderPlugins(); InvocationPlugins invocationPlugins = graphBuilderPlugins.getInvocationPlugins(); - Set pluginMethods = invocationPlugins.getMethods(); + Map> bindings = invocationPlugins.getBindings(true); HotSpotVMConfigStore store = rt.getVMConfig().getStore(); List intrinsics = store.getIntrinsics(); for (VMIntrinsicMethod intrinsic : intrinsics) { - ResolvedJavaMethod method = findMethod(pluginMethods, intrinsic); - if (method != null) { - InvocationPlugin plugin = invocationPlugins.lookupInvocation(method); - if (plugin instanceof MethodSubstitutionPlugin && !method.isNative()) { - StructuredGraph graph = compiler.getIntrinsicGraph(method, providers, CompilationIdentifier.INVALID_COMPILATION_ID); - getCode(method, graph); + InvocationPlugin plugin = CheckGraalIntrinsics.findPlugin(bindings, intrinsic); + if (plugin != null) { + if (plugin instanceof MethodSubstitutionPlugin) { + ResolvedJavaMethod method = CheckGraalIntrinsics.resolveIntrinsic(getMetaAccess(), intrinsic); + if (!method.isNative()) { + StructuredGraph graph = compiler.getIntrinsicGraph(method, providers, INVALID_COMPILATION_ID); + getCode(method, graph); + } } } } --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompileTheWorld.java 2017-04-28 11:48:55.000000000 +0200 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompileTheWorld.java 2017-04-28 11:48:55.000000000 +0200 @@ -102,7 +102,6 @@ import jdk.vm.ci.meta.MetaAccessProvider; import jdk.vm.ci.runtime.JVMCI; import jdk.vm.ci.runtime.JVMCICompiler; -import jdk.vm.ci.services.Services; /** * This class implements compile-the-world functionality with JVMCI. @@ -785,7 +784,6 @@ } public static void main(String[] args) throws Throwable { - Services.exportJVMCITo(CompileTheWorld.class); HotSpotGraalCompiler compiler = (HotSpotGraalCompiler) HotSpotJVMCIRuntime.runtime().getCompiler(); compiler.compileTheWorld(); } --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompilerFactory.java 2017-04-28 11:48:56.000000000 +0200 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompilerFactory.java 2017-04-28 11:48:56.000000000 +0200 @@ -22,21 +22,19 @@ */ package org.graalvm.compiler.hotspot; -import static org.graalvm.compiler.core.common.util.Util.Java8OrEarlier; -import static org.graalvm.compiler.options.OptionValue.PROFILE_OPTIONVALUE_PROPERTY_NAME; import static jdk.vm.ci.common.InitTimer.timer; +import static org.graalvm.compiler.options.OptionValue.PROFILE_OPTIONVALUE_PROPERTY_NAME; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.PrintStream; -import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; +import java.util.Map.Entry; import java.util.Properties; import java.util.ServiceLoader; -import org.graalvm.compiler.debug.GraalError; import org.graalvm.compiler.debug.MethodFilter; import org.graalvm.compiler.options.Option; import org.graalvm.compiler.options.OptionDescriptors; @@ -46,10 +44,11 @@ import org.graalvm.compiler.phases.tiers.CompilerConfiguration; import jdk.vm.ci.common.InitTimer; +import jdk.vm.ci.hotspot.HotSpotJVMCICompilerFactory; import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; import jdk.vm.ci.hotspot.HotSpotSignature; -import jdk.vm.ci.hotspot.HotSpotJVMCICompilerFactory; import jdk.vm.ci.runtime.JVMCIRuntime; +import jdk.vm.ci.services.Services; public final class HotSpotGraalCompilerFactory extends HotSpotJVMCICompilerFactory { @@ -135,8 +134,8 @@ if (allOptionsSettings == null) { try (InitTimer t = timer("InitializeOptions")) { ServiceLoader loader = ServiceLoader.load(OptionDescriptors.class, OptionDescriptors.class.getClassLoader()); - Properties savedProps = getSavedProperties(Java8OrEarlier); - String optionsFile = savedProps.getProperty(GRAAL_OPTIONS_FILE_PROPERTY_NAME); + Map savedProps = Services.getSavedProperties(); + String optionsFile = savedProps.get(GRAAL_OPTIONS_FILE_PROPERTY_NAME); if (optionsFile != null) { File graalOptions = new File(optionsFile); @@ -165,15 +164,15 @@ } Map optionSettings = new HashMap<>(); - for (Map.Entry e : savedProps.entrySet()) { - String name = (String) e.getKey(); + for (Entry e : savedProps.entrySet()) { + String name = e.getKey(); if (name.startsWith(GRAAL_OPTION_PROPERTY_PREFIX)) { if (name.equals("graal.PrintFlags") || name.equals("graal.ShowFlags")) { System.err.println("The " + name + " option has been removed and will be ignored. Use -XX:+JVMCIPrintProperties instead."); } else if (name.equals(GRAAL_OPTIONS_FILE_PROPERTY_NAME) || name.equals(GRAAL_VERSION_PROPERTY_NAME) || name.equals(PROFILE_OPTIONVALUE_PROPERTY_NAME)) { // Ignore well known properties that do not denote an option } else { - String value = (String) e.getValue(); + String value = e.getValue(); optionSettings.put(name.substring(GRAAL_OPTION_PROPERTY_PREFIX.length()), value); } } @@ -206,18 +205,6 @@ } } - private static Properties getSavedProperties(boolean jdk8OrEarlier) { - try { - String vmClassName = jdk8OrEarlier ? "sun.misc.VM" : "jdk.internal.misc.VM"; - Class vmClass = Class.forName(vmClassName); - Field savedPropsField = vmClass.getDeclaredField("savedProps"); - savedPropsField.setAccessible(true); - return (Properties) savedPropsField.get(null); - } catch (Exception e) { - throw new GraalError(e); - } - } - @Override public HotSpotGraalCompiler createCompiler(JVMCIRuntime runtime) { HotSpotGraalCompiler compiler = createCompiler(runtime, CompilerConfigurationFactory.selectFactory(null)); --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalJVMCIServiceLocator.java 2017-04-28 11:48:57.000000000 +0200 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalJVMCIServiceLocator.java 2017-04-28 11:48:57.000000000 +0200 @@ -22,10 +22,6 @@ */ package org.graalvm.compiler.hotspot; -import static org.graalvm.compiler.core.common.util.ModuleAPI.addExports; -import static org.graalvm.compiler.core.common.util.ModuleAPI.getModule; -import static org.graalvm.compiler.core.common.util.Util.JAVA_SPECIFICATION_VERSION; - import org.graalvm.compiler.serviceprovider.ServiceProvider; import jdk.vm.ci.hotspot.HotSpotVMEventListener; @@ -35,43 +31,45 @@ @ServiceProvider(JVMCIServiceLocator.class) public final class HotSpotGraalJVMCIServiceLocator extends JVMCIServiceLocator { - private boolean exportsAdded; - /** - * Dynamically exports various internal JDK packages to the Graal module. This requires only - * {@code --add-exports=java.base/jdk.internal.module=org.graalvm.compiler.graal_core} on the VM - * command line instead of a {@code --add-exports} instance for each JDK internal package used - * by Graal. + * Holds the state shared between all {@link HotSpotGraalJVMCIServiceLocator} instances. This is + * necessary as a service provider instance is created each time the service is loaded. */ - private void addExports() { - if (JAVA_SPECIFICATION_VERSION >= 9 && !exportsAdded) { - Object javaBaseModule = getModule.invoke(String.class); - Object graalModule = getModule.invoke(getClass()); - addExports.invokeStatic(javaBaseModule, "jdk.internal.misc", graalModule); - addExports.invokeStatic(javaBaseModule, "jdk.internal.jimage", graalModule); - addExports.invokeStatic(javaBaseModule, "com.sun.crypto.provider", graalModule); - exportsAdded = true; + private static final class Shared { + static final Shared SINGLETON = new Shared(); + + T getProvider(Class service, HotSpotGraalJVMCIServiceLocator locator) { + if (service == JVMCICompilerFactory.class) { + return service.cast(new HotSpotGraalCompilerFactory(locator)); + } else if (service == HotSpotVMEventListener.class) { + if (graalRuntime != null) { + return service.cast(new HotSpotGraalVMEventListener(graalRuntime)); + } + } + return null; } - } - private HotSpotGraalRuntime graalRuntime; + private HotSpotGraalRuntime graalRuntime; + + /** + * Notifies this object of the compiler created via {@link HotSpotGraalJVMCIServiceLocator}. + */ + void onCompilerCreation(HotSpotGraalCompiler compiler) { + assert this.graalRuntime == null : "only expect a single JVMCICompiler to be created"; + this.graalRuntime = (HotSpotGraalRuntime) compiler.getGraalRuntime(); + } + } @Override public T getProvider(Class service) { - if (service == JVMCICompilerFactory.class) { - addExports(); - return service.cast(new HotSpotGraalCompilerFactory(this)); - } else if (service == HotSpotVMEventListener.class) { - if (graalRuntime != null) { - addExports(); - return service.cast(new HotSpotGraalVMEventListener(graalRuntime)); - } - } - return null; + return Shared.SINGLETON.getProvider(service, this); } - public void onCompilerCreation(HotSpotGraalCompiler compiler) { - assert this.graalRuntime == null : "only expect a single JVMCICompiler to be created"; - this.graalRuntime = (HotSpotGraalRuntime) compiler.getGraalRuntime(); + /** + * Notifies this object of the compiler created via {@link HotSpotGraalJVMCIServiceLocator}. + */ + @SuppressWarnings("static-method") + void onCompilerCreation(HotSpotGraalCompiler compiler) { + Shared.SINGLETON.onCompilerCreation(compiler); } } --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java 2017-04-28 11:48:58.000000000 +0200 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java 2017-04-28 11:48:58.000000000 +0200 @@ -128,7 +128,7 @@ */ public static Plugins create(GraalHotSpotVMConfig config, HotSpotWordTypes wordTypes, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, SnippetReflectionProvider snippetReflection, ForeignCallsProvider foreignCalls, StampProvider stampProvider, ReplacementsImpl replacements) { - InvocationPlugins invocationPlugins = new HotSpotInvocationPlugins(config, metaAccess); + InvocationPlugins invocationPlugins = new HotSpotInvocationPlugins(config); Plugins plugins = new Plugins(invocationPlugins); NodeIntrinsificationProvider nodeIntrinsificationProvider = new NodeIntrinsificationProvider(metaAccess, snippetReflection, foreignCalls, wordTypes); --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotInvocationPlugins.java 2017-04-28 11:48:59.000000000 +0200 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotInvocationPlugins.java 2017-04-28 11:48:58.000000000 +0200 @@ -38,7 +38,6 @@ import org.graalvm.compiler.replacements.nodes.MacroNode; import jdk.vm.ci.meta.JavaKind; -import jdk.vm.ci.meta.MetaAccessProvider; import jdk.vm.ci.meta.ResolvedJavaType; /** @@ -47,8 +46,7 @@ final class HotSpotInvocationPlugins extends InvocationPlugins { final GraalHotSpotVMConfig config; - HotSpotInvocationPlugins(GraalHotSpotVMConfig config, MetaAccessProvider metaAccess) { - super(metaAccess); + HotSpotInvocationPlugins(GraalHotSpotVMConfig config) { this.config = config; } --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/AESCryptSubstitutions.java 2017-04-28 11:48:59.000000000 +0200 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/AESCryptSubstitutions.java 2017-04-28 11:48:59.000000000 +0200 @@ -29,8 +29,6 @@ import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.probability; import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayBaseOffset; -import java.lang.reflect.Field; - import org.graalvm.compiler.api.replacements.ClassSubstitution; import org.graalvm.compiler.api.replacements.MethodSubstitution; import org.graalvm.compiler.core.common.LocationIdentity; @@ -61,7 +59,7 @@ static final long kOffset; static final long lastKeyOffset; static final Class AESCryptClass; - static final int AES_BLOCK_SIZE; + static final int AES_BLOCK_SIZE_IN_BYTES; static { try { @@ -72,9 +70,9 @@ AESCryptClass = Class.forName("com.sun.crypto.provider.AESCrypt", true, cl); kOffset = UnsafeAccess.UNSAFE.objectFieldOffset(AESCryptClass.getDeclaredField("K")); lastKeyOffset = UnsafeAccess.UNSAFE.objectFieldOffset(AESCryptClass.getDeclaredField("lastKey")); - Field aesBlockSizeField = Class.forName("com.sun.crypto.provider.AESConstants", true, cl).getDeclaredField("AES_BLOCK_SIZE"); - aesBlockSizeField.setAccessible(true); - AES_BLOCK_SIZE = aesBlockSizeField.getInt(null); + // Thankfully the AES block size is a constant (128 bits) and so we don't need to + // reflect on com.sun.crypto.provider.AESConstants.AES_BLOCK_SIZE. + AES_BLOCK_SIZE_IN_BYTES = 16; } catch (Exception ex) { throw new GraalError(ex); } @@ -141,7 +139,7 @@ * Perform null and array bounds checks for arguments to a cipher operation. */ static void checkArgs(byte[] in, int inOffset, byte[] out, int outOffset) { - if (probability(VERY_SLOW_PATH_PROBABILITY, inOffset < 0 || in.length - AES_BLOCK_SIZE < inOffset || outOffset < 0 || out.length - AES_BLOCK_SIZE < outOffset)) { + if (probability(VERY_SLOW_PATH_PROBABILITY, inOffset < 0 || in.length - AES_BLOCK_SIZE_IN_BYTES < inOffset || outOffset < 0 || out.length - AES_BLOCK_SIZE_IN_BYTES < outOffset)) { DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint); } } --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/CRC32Substitutions.java 2017-04-28 11:49:00.000000000 +0200 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/CRC32Substitutions.java 2017-04-28 11:49:00.000000000 +0200 @@ -57,7 +57,7 @@ return config.crcTableAddress; } - @MethodSubstitution + @MethodSubstitution(optional = true) static int update(int crc, int b) { final long crcTableRawAddress = GraalHotSpotVMConfigNode.crcTableAddress(); @@ -69,7 +69,7 @@ return ~result; } - @MethodSubstitution + @MethodSubstitution(optional = true) static int updateBytes(int crc, byte[] buf, int off, int len) { Word bufAddr = Word.unsigned(ComputeObjectAddressNode.get(buf, arrayBaseOffset(JavaKind.Byte) + off)); return updateBytesCRC32(UPDATE_BYTES_CRC32, crc, bufAddr, len); @@ -84,7 +84,7 @@ return updateBytesCRC32(UPDATE_BYTES_CRC32, crc, bufAddr, len); } - @MethodSubstitution + @MethodSubstitution(optional = true) static int updateByteBuffer(int crc, long addr, int off, int len) { Word bufAddr = Word.unsigned(addr).add(off); return updateBytesCRC32(UPDATE_BYTES_CRC32, crc, bufAddr, len); --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/ThreadSubstitutions.java 2017-04-28 11:49:01.000000000 +0200 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/ThreadSubstitutions.java 2017-04-28 11:49:00.000000000 +0200 @@ -45,7 +45,7 @@ @ClassSubstitution(Thread.class) public class ThreadSubstitutions { - @MethodSubstitution(isStatic = false) + @MethodSubstitution(isStatic = false, optional = true) public static boolean isInterrupted(final Thread thisObject, boolean clearInterrupted) { Word javaThread = CurrentJavaThreadNode.get(); Object thread = javaThread.readObject(threadObjectOffset(INJECTED_VMCONFIG), JAVA_THREAD_THREAD_OBJECT_LOCATION); --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/InvocationPlugin.java 2017-04-28 11:49:01.000000000 +0200 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/InvocationPlugin.java 2017-04-28 11:49:01.000000000 +0200 @@ -40,8 +40,7 @@ /** * The receiver in a non-static method. The class literal for this interface must be used with - * {@link InvocationPlugins#put(InvocationPlugin, boolean, boolean, boolean, Class, String, Class...)} - * to denote the receiver argument for such a non-static method. + * {@link InvocationPlugins#put} to denote the receiver argument for such a non-static method. */ public interface Receiver { /** --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/InvocationPlugins.java 2017-04-28 11:49:02.000000000 +0200 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/InvocationPlugins.java 2017-04-28 11:49:02.000000000 +0200 @@ -23,8 +23,9 @@ package org.graalvm.compiler.nodes.graphbuilderconf; import static java.lang.String.format; +import static org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.LateClassPlugins.CLOSED_LATE_CLASS_PLUGIN; -import java.lang.reflect.Executable; +import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Type; @@ -32,10 +33,8 @@ import java.util.Arrays; import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Set; import org.graalvm.compiler.api.replacements.MethodSubstitution; import org.graalvm.compiler.api.replacements.MethodSubstitutionRegistry; @@ -46,12 +45,24 @@ import org.graalvm.compiler.nodes.ValueNode; import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.Receiver; -import jdk.vm.ci.meta.MetaAccessProvider; import jdk.vm.ci.meta.MetaUtil; import jdk.vm.ci.meta.ResolvedJavaMethod; +import jdk.vm.ci.meta.ResolvedJavaType; +import jdk.vm.ci.meta.Signature; /** * Manages a set of {@link InvocationPlugin}s. + * + * Most plugins are registered during initialization (i.e., before + * {@link #lookupInvocation(ResolvedJavaMethod)} or {@link #getBindings} is called). These + * registrations can be made with {@link Registration}, + * {@link #register(InvocationPlugin, String, String, Type...)}, + * {@link #register(InvocationPlugin, Type, String, Type...)} or + * {@link #registerOptional(InvocationPlugin, Type, String, Type...)}. Initialization is not + * thread-safe and so must only be performed by a single thread. + * + * Plugins that are not guaranteed to be made during initialization must use + * {@link LateRegistration}. */ public class InvocationPlugins { @@ -260,6 +271,26 @@ } /** + * Registers a plugin for a method with 6 arguments. + * + * @param name the name of the method + * @param plugin the plugin to be registered + */ + public void register6(String name, Type arg1, Type arg2, Type arg3, Type arg4, Type arg5, Type arg6, InvocationPlugin plugin) { + plugins.register(plugin, false, allowOverwrite, declaringType, name, arg1, arg2, arg3, arg4, arg5, arg6); + } + + /** + * Registers a plugin for a method with 7 arguments. + * + * @param name the name of the method + * @param plugin the plugin to be registered + */ + public void register7(String name, Type arg1, Type arg2, Type arg3, Type arg4, Type arg5, Type arg6, Type arg7, InvocationPlugin plugin) { + plugins.register(plugin, false, allowOverwrite, declaringType, name, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + } + + /** * Registers a plugin for an optional method with no arguments. * * @param name the name of the method @@ -337,168 +368,151 @@ */ @Override public void registerMethodSubstitution(Class substituteDeclaringClass, String name, String substituteName, Type... argumentTypes) { + MethodSubstitutionPlugin plugin = createMethodSubstitution(substituteDeclaringClass, substituteName, argumentTypes); + plugins.register(plugin, false, allowOverwrite, declaringType, name, argumentTypes); + } + + public MethodSubstitutionPlugin createMethodSubstitution(Class substituteDeclaringClass, String substituteName, Type... argumentTypes) { assert methodSubstitutionBytecodeProvider != null : "Registration used for method substitutions requires a non-null methodSubstitutionBytecodeProvider"; MethodSubstitutionPlugin plugin = new MethodSubstitutionPlugin(methodSubstitutionBytecodeProvider, substituteDeclaringClass, substituteName, argumentTypes); - plugins.register(plugin, false, allowOverwrite, declaringType, name, argumentTypes); + return plugin; } + } /** - * Key for a {@linkplain ClassPlugins#entries resolved} plugin registration. Due to the - * possibility of class redefinition, we cannot directly use {@link ResolvedJavaMethod}s as - * keys. A {@link ResolvedJavaMethod} implementation might implement {@code equals()} and - * {@code hashCode()} based on internal representation subject to change by class redefinition. + * Utility for registering plugins after Graal may have been initialized. Registrations made via + * this class are not finalized until {@link #close} is called. */ - static final class ResolvedJavaMethodKey { - private final ResolvedJavaMethod method; + public static class LateRegistration implements AutoCloseable { + + private InvocationPlugins plugins; + private final List bindings = new ArrayList<>(); + private final Type declaringType; - ResolvedJavaMethodKey(ResolvedJavaMethod method) { - this.method = method; + /** + * Creates an object for registering {@link InvocationPlugin}s for methods declared by a + * given class. + * + * @param plugins where to register the plugins + * @param declaringType the class declaring the methods for which plugins will be registered + * via this object + */ + public LateRegistration(InvocationPlugins plugins, Type declaringType) { + this.plugins = plugins; + this.declaringType = declaringType; } - @Override - public boolean equals(Object obj) { - if (obj instanceof ResolvedJavaMethodKey) { - ResolvedJavaMethodKey that = (ResolvedJavaMethodKey) obj; - if (this.method.isStatic() == that.method.isStatic()) { - if (this.method.getDeclaringClass().equals(that.method.getDeclaringClass())) { - if (this.method.getName().equals(that.method.getName())) { - if (this.method.getSignature().equals(that.method.getSignature())) { - return true; - } - } - } - } + /** + * Registers an invocation plugin for a given method. There must be no plugin currently + * registered for {@code method}. + * + * @param argumentTypes the argument types of the method. Element 0 of this array must be + * the {@link Class} value for {@link InvocationPlugin.Receiver} iff the method + * is non-static. Upon returning, element 0 will have been rewritten to + * {@code declaringClass} + */ + public void register(InvocationPlugin plugin, String name, Type... argumentTypes) { + boolean isStatic = argumentTypes.length == 0 || argumentTypes[0] != InvocationPlugin.Receiver.class; + if (!isStatic) { + argumentTypes[0] = declaringType; } - return false; - } - @Override - public int hashCode() { - return this.method.getName().hashCode(); + assert isStatic || argumentTypes[0] == declaringType; + Binding binding = new Binding(plugin, isStatic, name, argumentTypes); + bindings.add(binding); + + assert Checks.check(this.plugins, declaringType, binding); + assert Checks.checkResolvable(false, declaringType, binding); } @Override - public String toString() { - return "ResolvedJavaMethodKey<" + method + ">"; + public void close() { + assert plugins != null : String.format("Late registrations of invocation plugins for %s is already closed", declaringType); + plugins.registerLate(declaringType, bindings); + plugins = null; } } /** - * Key for {@linkplain ClassPlugins#registrations registering} an {@link InvocationPlugin} for a - * specific method. + * Associates an {@link InvocationPlugin} with the details of a method it substitutes. */ - static class MethodKey { - final boolean isStatic; + public static class Binding { + /** + * The plugin this binding is for. + */ + public final InvocationPlugin plugin; /** - * This method is optional. This is used for new API methods not present in previous JDK - * versions. + * Specifies if the associated method is static. */ - final boolean isOptional; + public final boolean isStatic; - final String name; - final Type[] argumentTypes; - final InvocationPlugin value; + /** + * The name of the associated method. + */ + public final String name; /** - * Used to lazily initialize {@link #resolved}. + * A partial + * method + * descriptor for the associated method. The descriptor includes enclosing {@code '('} + * and {@code ')'} characters but omits the return type suffix. */ - private final MetaAccessProvider metaAccess; + public final String argumentsDescriptor; - private volatile ResolvedJavaMethod resolved; + /** + * Link in a list of bindings. + */ + private Binding next; - MethodKey(MetaAccessProvider metaAccess, InvocationPlugin data, boolean isStatic, boolean isOptional, String name, Type... argumentTypes) { - this.metaAccess = metaAccess; - this.value = data; + Binding(InvocationPlugin data, boolean isStatic, String name, Type... argumentTypes) { + this.plugin = data; this.isStatic = isStatic; - this.isOptional = isOptional; this.name = name; - this.argumentTypes = argumentTypes; - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof MethodKey) { - MethodKey that = (MethodKey) obj; - boolean res = this.name.equals(that.name) && areEqual(this.argumentTypes, that.argumentTypes); - assert !res || this.isStatic == that.isStatic; - return res; - } - return false; - } - - private static boolean areEqual(Type[] args1, Type[] args2) { - if (args1.length == args2.length) { - for (int i = 0; i < args1.length; i++) { - if (!args1[i].getTypeName().equals(args2[i].getTypeName())) { - return false; - } - } - return true; - } - return false; - } - - public int getDeclaredParameterCount() { - return isStatic ? argumentTypes.length : argumentTypes.length - 1; - } - - @Override - public int hashCode() { - return name.hashCode(); - } - - private ResolvedJavaMethod resolve(Class declaringClass) { - if (resolved == null) { - Executable method = resolveJava(declaringClass); - if (method == null) { - return null; - } - resolved = metaAccess.lookupJavaMethod(method); - } - return resolved; - } - - private Executable resolveJava(Class declaringClass) { - try { - Executable res; - Class[] parameterTypes = resolveTypes(argumentTypes, isStatic ? 0 : 1, argumentTypes.length); - if (name.equals("")) { - res = declaringClass.getDeclaredConstructor(parameterTypes); - } else { - res = declaringClass.getDeclaredMethod(name, parameterTypes); - } - assert Modifier.isStatic(res.getModifiers()) == isStatic : res; - return res; - } catch (NoSuchMethodException | SecurityException e) { - if (isOptional) { - return null; - } - throw new InternalError(e); - } + StringBuilder buf = new StringBuilder(); + buf.append('('); + for (int i = isStatic ? 0 : 1; i < argumentTypes.length; i++) { + buf.append(MetaUtil.toInternalName(argumentTypes[i].getTypeName())); + } + buf.append(')'); + this.argumentsDescriptor = buf.toString(); + assert !name.equals("") || !isStatic : this; + } + + Binding(ResolvedJavaMethod resolved, InvocationPlugin data) { + this.plugin = data; + this.isStatic = resolved.isStatic(); + this.name = resolved.getName(); + Signature sig = resolved.getSignature(); + String desc = sig.toMethodDescriptor(); + assert desc.indexOf(')') != -1 : desc; + this.argumentsDescriptor = desc.substring(0, desc.indexOf(')') + 1); + assert !name.equals("") || !isStatic : this; } @Override public String toString() { - StringBuilder sb = new StringBuilder(name).append('('); - for (Type p : argumentTypes) { - if (sb.charAt(sb.length() - 1) != '(') { - sb.append(", "); - } - sb.append(p.getTypeName()); - } - return sb.append(')').toString(); + return name + argumentsDescriptor; } } - private final MetaAccessProvider metaAccess; + /** + * Plugin registrations for already resolved methods. If non-null, then {@link #registrations} + * is null and no further registrations can be made. + */ + private final Map resolvedRegistrations; - private final Map registrations = new HashMap<>(); + /** + * Map from class names in {@linkplain MetaUtil#toInternalName(String) internal} form to the + * invocation plugin bindings for the class. Tf non-null, then {@link #resolvedRegistrations} + * will be null. + */ + private final Map registrations; /** - * Deferred registrations as well as guard for initialization. The guard uses double-checked - * locking which is why this field is {@code volatile}. + * Deferred registrations as well as the guard for delimiting the initial registration phase. + * The guard uses double-checked locking which is why this field is {@code volatile}. */ private volatile List deferredRegistrations = new ArrayList<>(); @@ -512,119 +526,159 @@ } /** - * Per-class invocation plugins. + * Support for registering plugins once this object may be accessed by multiple threads. */ - protected static class ClassPlugins { - private final Type declaringType; + private volatile LateClassPlugins lateRegistrations; - private final List registrations = new ArrayList<>(); + /** + * Per-class bindings. + */ + static class ClassPlugins { - public ClassPlugins(Type declaringClass) { - this.declaringType = declaringClass; - } + /** + * Maps method names to binding lists. + */ + private final Map bindings = new HashMap<>(); /** - * Entry map that is initialized upon first call to {@link #get(ResolvedJavaMethod)}. + * Gets the invocation plugin for a given method. * - * Note: this must be volatile as threads may race to initialize it. - */ - private volatile Map entries; - - void initializeMap() { - if (!isClosed()) { - if (registrations.isEmpty()) { - entries = Collections.emptyMap(); - } else { - Class declaringClass = resolveType(declaringType, true); - if (declaringClass == null) { - // An optional type that could not be resolved - entries = Collections.emptyMap(); - } else { - Map newEntries = new HashMap<>(); - for (MethodKey methodKey : registrations) { - ResolvedJavaMethod m = methodKey.resolve(declaringClass); - if (m != null) { - newEntries.put(new ResolvedJavaMethodKey(m), methodKey.value); - if (entries != null) { - // Another thread finished initializing entries first - return; - } - } - } - entries = newEntries; + * @return the invocation plugin for {@code method} or {@code null} + */ + InvocationPlugin get(ResolvedJavaMethod method) { + assert !method.isBridge(); + Binding binding = bindings.get(method.getName()); + while (binding != null) { + if (method.isStatic() == binding.isStatic) { + if (method.getSignature().toMethodDescriptor().startsWith(binding.argumentsDescriptor)) { + return binding.plugin; } } + binding = binding.next; } + return null; } - public InvocationPlugin get(ResolvedJavaMethod method) { - if (!isClosed()) { - initializeMap(); - } - return entries.get(new ResolvedJavaMethodKey(method)); - } - - public void register(MethodKey methodKey, boolean allowOverwrite) { - assert !isClosed() : "registration is closed: " + methodKey + " " + Arrays.toString(entries.keySet().toArray()); + public void register(Binding binding, boolean allowOverwrite) { if (allowOverwrite) { - int index = registrations.indexOf(methodKey); - if (index >= 0) { - registrations.set(index, methodKey); + if (lookup(binding) != null) { + register(binding); return; } } else { - assert !registrations.contains(methodKey) : "a value is already registered for " + declaringType + "." + methodKey; + assert lookup(binding) == null : "a value is already registered for " + binding; + } + register(binding); + } + + InvocationPlugin lookup(Binding binding) { + Binding b = bindings.get(binding.name); + while (b != null) { + if (b.isStatic == binding.isStatic && b.argumentsDescriptor.equals(binding.argumentsDescriptor)) { + return b.plugin; + } + b = b.next; } - registrations.add(methodKey); + return null; } - public boolean isClosed() { - return entries != null; + /** + * Registers {@code binding}. + */ + void register(Binding binding) { + Binding head = bindings.get(binding.name); + assert binding.next == null; + binding.next = head; + bindings.put(binding.name, binding); + } + } + + static class LateClassPlugins extends ClassPlugins { + static final String CLOSED_LATE_CLASS_PLUGIN = "-----"; + private final String className; + private final LateClassPlugins next; + + LateClassPlugins(LateClassPlugins next, String className) { + assert next == null || next.className != CLOSED_LATE_CLASS_PLUGIN : "Late registration of invocation plugins is closed"; + this.next = next; + this.className = className; } } /** - * Adds an entry to this map for a specified method. + * Registers a binding of a method to an invocation plugin. * - * @param value value to be associated with the specified method + * @param plugin invocation plugin to be associated with the specified method * @param isStatic specifies if the method is static - * @param isOptional specifies if the method is optional * @param declaringClass the class declaring the method * @param name the name of the method * @param argumentTypes the argument types of the method. Element 0 of this array must be * {@code declaringClass} iff the method is non-static. * @return an object representing the method */ - MethodKey put(InvocationPlugin value, boolean isStatic, boolean isOptional, boolean allowOverwrite, Type declaringClass, String name, Type... argumentTypes) { + Binding put(InvocationPlugin plugin, boolean isStatic, boolean allowOverwrite, Type declaringClass, String name, Type... argumentTypes) { + assert resolvedRegistrations == null : "registration is closed"; + String internalName = MetaUtil.toInternalName(declaringClass.getTypeName()); assert isStatic || argumentTypes[0] == declaringClass; + assert deferredRegistrations != null : "initial registration is closed - use " + LateRegistration.class.getName() + " for late registrations"; - String internalName = MetaUtil.toInternalName(declaringClass.getTypeName()); ClassPlugins classPlugins = registrations.get(internalName); if (classPlugins == null) { - classPlugins = new ClassPlugins(declaringClass); + classPlugins = new ClassPlugins(); registrations.put(internalName, classPlugins); } - assert isStatic || argumentTypes[0] == declaringClass; - MethodKey methodKey = new MethodKey(metaAccess, value, isStatic, isOptional, name, argumentTypes); - classPlugins.register(methodKey, allowOverwrite); - return methodKey; + Binding binding = new Binding(plugin, isStatic, name, argumentTypes); + classPlugins.register(binding, allowOverwrite); + return binding; + } + + InvocationPlugin get(ResolvedJavaMethod method) { + if (resolvedRegistrations != null) { + return resolvedRegistrations.get(method); + } else { + if (!method.isBridge()) { + ResolvedJavaType declaringClass = method.getDeclaringClass(); + flushDeferrables(); + String internalName = declaringClass.getName(); + ClassPlugins classPlugins = registrations.get(internalName); + InvocationPlugin res = null; + if (classPlugins != null) { + res = classPlugins.get(method); + } + if (res == null) { + LateClassPlugins lcp = findLateClassPlugins(internalName); + if (lcp != null) { + res = lcp.get(method); + } + } + if (res != null) { + if (canBeIntrinsified(declaringClass)) { + return res; + } + } + } else { + // Supporting plugins for bridge methods would require including + // the return type in the registered signature. Until needed, + // this extra complexity is best avoided. + } + } + return null; } /** - * Determines if a method denoted by a given {@link MethodKey} is in this map. + * Determines if methods in a given class can have invocation plugins. + * + * @param declaringClass the class to test */ - boolean containsKey(Type declaringType, MethodKey key) { - String internalName = MetaUtil.toInternalName(declaringType.getTypeName()); - ClassPlugins classPlugins = registrations.get(internalName); - return classPlugins != null && classPlugins.registrations.contains(key); + protected boolean canBeIntrinsified(ResolvedJavaType declaringClass) { + return true; } - InvocationPlugin get(ResolvedJavaMethod method) { - flushDeferrables(); - String internalName = method.getDeclaringClass().getName(); - ClassPlugins classPlugins = registrations.get(internalName); - if (classPlugins != null) { - return classPlugins.get(method); + LateClassPlugins findLateClassPlugins(String internalClassName) { + for (LateClassPlugins lcp = lateRegistrations; lcp != null; lcp = lcp.next) { + if (lcp.className.equals(internalClassName)) { + return lcp; + } } return null; } @@ -639,25 +693,39 @@ deferredRegistrations = null; } } - for (Map.Entry e : registrations.entrySet()) { - e.getValue().initializeMap(); - } } } + synchronized void registerLate(Type declaringType, List bindings) { + String internalName = MetaUtil.toInternalName(declaringType.getTypeName()); + assert findLateClassPlugins(internalName) == null : "Cannot have more than one late registration of invocation plugins for " + internalName; + LateClassPlugins lateClassPlugins = new LateClassPlugins(lateRegistrations, internalName); + for (Binding b : bindings) { + lateClassPlugins.register(b); + } + lateRegistrations = lateClassPlugins; + } + + private synchronized boolean closeLateRegistrations() { + if (lateRegistrations == null || lateRegistrations.className != CLOSED_LATE_CLASS_PLUGIN) { + lateRegistrations = new LateClassPlugins(lateRegistrations, CLOSED_LATE_CLASS_PLUGIN); + } + return true; + } + /** - * Disallows new registrations of new plugins, and creates the internal tables for method - * lookup. + * Processes deferred registrations and then closes this object for future registration. */ public void closeRegistration() { + assert closeLateRegistrations(); flushDeferrables(); - for (Map.Entry e : registrations.entrySet()) { - e.getValue().initializeMap(); - } } - public int size() { - return registrations.size(); + public boolean isEmpty() { + if (resolvedRegistrations != null) { + return resolvedRegistrations.isEmpty(); + } + return registrations.size() == 0 && lateRegistrations == null; } /** @@ -666,47 +734,39 @@ */ protected final InvocationPlugins parent; - private InvocationPlugins(InvocationPlugins parent, MetaAccessProvider metaAccess) { - this.metaAccess = metaAccess; - InvocationPlugins p = parent; - this.parent = p; + /** + * Creates a set of invocation plugins with no parent. + */ + public InvocationPlugins() { + this(null); } /** - * Creates a set of invocation plugins with a non-null {@linkplain #getParent() parent}. + * Creates a set of invocation plugins. + * + * @param parent if non-null, this object will be searched first when looking up plugins */ public InvocationPlugins(InvocationPlugins parent) { - this(parent, parent.getMetaAccess()); + InvocationPlugins p = parent; + this.parent = p; + this.registrations = new HashMap<>(); + this.resolvedRegistrations = null; } - public InvocationPlugins(Map plugins, InvocationPlugins parent, MetaAccessProvider metaAccess) { - this.metaAccess = metaAccess; + /** + * Creates a closed set of invocation plugins for a set of resolved methods. Such an object + * cannot have further plugins registered. + */ + public InvocationPlugins(Map plugins, InvocationPlugins parent) { this.parent = parent; - + this.registrations = null; this.deferredRegistrations = null; + Map map = new HashMap<>(plugins.size()); for (Map.Entry entry : plugins.entrySet()) { - ResolvedJavaMethod method = entry.getKey(); - InvocationPlugin plugin = entry.getValue(); - - String internalName = method.getDeclaringClass().getName(); - ClassPlugins classPlugins = registrations.get(internalName); - if (classPlugins == null) { - classPlugins = new ClassPlugins(null); - registrations.put(internalName, classPlugins); - classPlugins.entries = new HashMap<>(); - } - - classPlugins.entries.put(new ResolvedJavaMethodKey(method), plugin); + map.put(entry.getKey(), entry.getValue()); } - } - - public MetaAccessProvider getMetaAccess() { - return metaAccess; - } - - public InvocationPlugins(MetaAccessProvider metaAccess) { - this(null, metaAccess); + this.resolvedRegistrations = map; } protected void register(InvocationPlugin plugin, boolean isOptional, boolean allowOverwrite, Type declaringClass, String name, Type... argumentTypes) { @@ -714,8 +774,9 @@ if (!isStatic) { argumentTypes[0] = declaringClass; } - MethodKey methodKey = put(plugin, isStatic, isOptional, allowOverwrite, declaringClass, name, argumentTypes); - assert Checker.check(this, declaringClass, methodKey, plugin); + Binding binding = put(plugin, isStatic, allowOverwrite, declaringClass, name, argumentTypes); + assert Checks.check(this, declaringClass, binding); + assert Checks.checkResolvable(isOptional, declaringClass, binding); } /** @@ -765,23 +826,56 @@ } /** - * Gets the set of methods for which invocation plugins have been registered. Once this method - * is called, no further registrations can be made. + * Gets the set of registered invocation plugins. + * + * @return a map from class names in {@linkplain MetaUtil#toInternalName(String) internal} form + * to the invocation plugin bindings for methods in the class */ - public Set getMethods() { - Set res = new HashSet<>(); - if (parent != null) { - res.addAll(parent.getMethods()); - } - flushDeferrables(); - for (ClassPlugins cp : registrations.values()) { - for (ResolvedJavaMethodKey key : cp.entries.keySet()) { - res.add(key.method); + public Map> getBindings(boolean includeParents) { + Map> res = new HashMap<>(); + if (parent != null && includeParents) { + res.putAll(parent.getBindings(true)); + } + if (resolvedRegistrations != null) { + for (Map.Entry e : resolvedRegistrations.entrySet()) { + ResolvedJavaMethod method = e.getKey(); + InvocationPlugin plugin = e.getValue(); + String type = method.getDeclaringClass().getName(); + List bindings = res.get(type); + if (bindings == null) { + bindings = new ArrayList<>(); + res.put(type, bindings); + } + bindings.add(new Binding(method, plugin)); + } + } else { + flushDeferrables(); + for (Map.Entry e : registrations.entrySet()) { + String type = e.getKey(); + ClassPlugins cp = e.getValue(); + collectBindingsTo(res, type, cp); + } + for (LateClassPlugins lcp = lateRegistrations; lcp != null; lcp = lcp.next) { + String type = lcp.className; + collectBindingsTo(res, type, lcp); } } return res; } + private static void collectBindingsTo(Map> res, String type, ClassPlugins cp) { + for (Map.Entry e : cp.bindings.entrySet()) { + List bindings = res.get(type); + if (bindings == null) { + bindings = new ArrayList<>(); + res.put(type, bindings); + } + for (Binding b = e.getValue(); b != null; b = b.next) { + bindings.add(b); + } + } + } + /** * Gets the invocation plugins {@linkplain #lookupInvocation(ResolvedJavaMethod) searched} * before searching in this object. @@ -792,17 +886,36 @@ @Override public String toString() { + List all = new ArrayList<>(); + for (Map.Entry> e : getBindings(false).entrySet()) { + String c = MetaUtil.internalNameToJava(e.getKey(), true, false); + for (Binding b : e.getValue()) { + all.add(c + '.' + b); + } + } + Collections.sort(all); StringBuilder buf = new StringBuilder(); - registrations.forEach((name, cp) -> buf.append(name).append('.').append(cp).append(", ")); - String s = buf.toString(); - if (buf.length() != 0) { - s = s.substring(buf.length() - ", ".length()); + String nl = String.format("%n"); + for (String s : all) { + if (buf.length() != 0) { + buf.append(nl); + } + buf.append(s); + } + if (parent != null) { + if (buf.length() != 0) { + buf.append(nl); + } + buf.append("// parent").append(nl).append(parent); } - return s + " / parent: " + this.parent; + return buf.toString(); } - private static class Checker { - private static final int MAX_ARITY = 5; + /** + * Code only used in assertions. Putting this in a separate class reduces class load time. + */ + private static class Checks { + private static final int MAX_ARITY = 7; /** * The set of all {@link InvocationPlugin#apply} method signatures. */ @@ -828,10 +941,17 @@ SIGS = sigs.toArray(new Class[sigs.size()][]); } - public static boolean check(InvocationPlugins plugins, Type declaringType, MethodKey method, InvocationPlugin plugin) { + static boolean containsBinding(InvocationPlugins p, Type declaringType, Binding key) { + String internalName = MetaUtil.toInternalName(declaringType.getTypeName()); + ClassPlugins classPlugins = p.registrations.get(internalName); + return classPlugins != null && classPlugins.lookup(key) != null; + } + + public static boolean check(InvocationPlugins plugins, Type declaringType, Binding binding) { + InvocationPlugin plugin = binding.plugin; InvocationPlugins p = plugins.parent; while (p != null) { - assert !p.containsKey(declaringType, method) : "a plugin is already registered for " + method; + assert !containsBinding(p, declaringType, binding) : "a plugin is already registered for " + binding; p = p.parent; } if (plugin instanceof ForeignCallPlugin || plugin instanceof GeneratedInvocationPlugin) { @@ -843,8 +963,8 @@ assert substitute.getAnnotation(MethodSubstitution.class) != null : format("Substitute method must be annotated with @%s: %s", MethodSubstitution.class.getSimpleName(), substitute); return true; } - int arguments = method.getDeclaredParameterCount(); - assert arguments < SIGS.length : format("need to extend %s to support method with %d arguments: %s", InvocationPlugin.class.getSimpleName(), arguments, method); + int arguments = parseParameters(binding.argumentsDescriptor).size(); + assert arguments < SIGS.length : format("need to extend %s to support method with %d arguments: %s", InvocationPlugin.class.getSimpleName(), arguments, binding); for (Method m : plugin.getClass().getDeclaredMethods()) { if (m.getName().equals("apply")) { Class[] parameterTypes = m.getParameterTypes(); @@ -853,7 +973,24 @@ } } } - throw new AssertionError(format("graph builder plugin for %s not found", method)); + throw new AssertionError(format("graph builder plugin for %s not found", binding)); + } + + static boolean checkResolvable(boolean isOptional, Type declaringType, Binding binding) { + Class declaringClass = InvocationPlugins.resolveType(declaringType, isOptional); + if (declaringClass == null) { + return true; + } + if (binding.name.equals("")) { + if (resolveConstructor(declaringClass, binding) == null && !isOptional) { + throw new AssertionError(String.format("Constructor not found: %s%s", declaringClass.getName(), binding.argumentsDescriptor)); + } + } else { + if (resolveMethod(declaringClass, binding) == null && !isOptional) { + throw new AssertionError(String.format("Method not found: %s.%s%s", declaringClass.getName(), binding.name, binding.argumentsDescriptor)); + } + } + return true; } } @@ -904,31 +1041,119 @@ if (type instanceof Class) { return (Class) type; } - if (optional && type instanceof OptionalLazySymbol) { + if (type instanceof OptionalLazySymbol) { return ((OptionalLazySymbol) type).resolve(); } return resolveClass(type.getTypeName(), optional); } - private static final Class[] NO_CLASSES = {}; + private static List toInternalTypeNames(Class[] types) { + String[] res = new String[types.length]; + for (int i = 0; i < types.length; i++) { + res[i] = MetaUtil.toInternalName(types[i].getTypeName()); + } + return Arrays.asList(res); + } + + /** + * Resolves a given binding to a method in a given class. If more than one method with the + * parameter types matching {@code binding} is found and the return types of all the matching + * methods form an inheritance chain, the one with the most specific type is returned; otherwise + * {@link NoSuchMethodError} is thrown. + * + * @param declaringClass the class to search for a method matching {@code binding} + * @return the method (if any) in {@code declaringClass} matching binding + */ + public static Method resolveMethod(Class declaringClass, Binding binding) { + if (binding.name.equals("")) { + return null; + } + Method[] methods = declaringClass.getDeclaredMethods(); + List parameterTypeNames = parseParameters(binding.argumentsDescriptor); + for (int i = 0; i < methods.length; ++i) { + Method m = methods[i]; + if (binding.isStatic == Modifier.isStatic(m.getModifiers()) && m.getName().equals(binding.name)) { + if (parameterTypeNames.equals(toInternalTypeNames(m.getParameterTypes()))) { + for (int j = i + 1; j < methods.length; ++j) { + Method other = methods[j]; + if (binding.isStatic == Modifier.isStatic(other.getModifiers()) && other.getName().equals(binding.name)) { + if (parameterTypeNames.equals(toInternalTypeNames(other.getParameterTypes()))) { + if (m.getReturnType().isAssignableFrom(other.getReturnType())) { + // `other` has a more specific return type - choose it + // (m is most likely a bridge method) + m = other; + } else { + if (!other.getReturnType().isAssignableFrom(m.getReturnType())) { + throw new NoSuchMethodError(String.format( + "Found 2 methods with same name and parameter types but unrelated return types:%n %s%n %s", m, other)); + } + } + } + } + } + return m; + } + } + } + return null; + } /** - * Resolves an array of {@link Type}s to an array of {@link Class}es. + * Resolves a given binding to a constructor in a given class. * - * @param types the types to resolve - * @param from the initial index of the range to be resolved, inclusive - * @param to the final index of the range to be resolved, exclusive - * @return the resolved class or null if resolution fails and {@code optional} is true + * @param declaringClass the class to search for a constructor matching {@code binding} + * @return the constructor (if any) in {@code declaringClass} matching binding */ - public static Class[] resolveTypes(Type[] types, int from, int to) { - int length = to - from; - if (length <= 0) { - return NO_CLASSES; - } - Class[] classes = new Class[length]; - for (int i = 0; i < length; i++) { - classes[i] = resolveType(types[i + from], false); + public static Constructor resolveConstructor(Class declaringClass, Binding binding) { + if (!binding.name.equals("")) { + return null; } - return classes; + Constructor[] constructors = declaringClass.getDeclaredConstructors(); + List parameterTypeNames = parseParameters(binding.argumentsDescriptor); + for (int i = 0; i < constructors.length; ++i) { + Constructor c = constructors[i]; + if (parameterTypeNames.equals(toInternalTypeNames(c.getParameterTypes()))) { + return c; + } + } + return null; + } + + private static List parseParameters(String argumentsDescriptor) { + assert argumentsDescriptor.startsWith("(") && argumentsDescriptor.endsWith(")") : argumentsDescriptor; + List res = new ArrayList<>(); + int cur = 1; + int end = argumentsDescriptor.length() - 1; + while (cur != end) { + char first; + int start = cur; + do { + first = argumentsDescriptor.charAt(cur++); + } while (first == '['); + + switch (first) { + case 'L': + int endObject = argumentsDescriptor.indexOf(';', cur); + if (endObject == -1) { + throw new GraalError("Invalid object type at index %d in signature: %s", cur, argumentsDescriptor); + } + cur = endObject + 1; + break; + case 'V': + case 'I': + case 'B': + case 'C': + case 'D': + case 'F': + case 'J': + case 'S': + case 'Z': + break; + default: + throw new GraalError("Invalid character at index %d in signature: %s", cur, argumentsDescriptor); + } + res.add(argumentsDescriptor.substring(start, cur)); + } + return res; } } --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinter.java 2017-04-28 11:49:03.000000000 +0200 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinter.java 2017-04-28 11:49:02.000000000 +0200 @@ -69,8 +69,7 @@ void close(); /** - * A JVMCI package {@linkplain Services#exportJVMCITo(Class) dynamically exported} to trusted - * modules. + * A JVMCI package dynamically exported to trusted modules. */ String JVMCI_RUNTIME_PACKAGE = JVMCI.class.getPackage().getName(); --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/DeoptimizeOnExceptionTest.java 2017-04-28 11:49:03.000000000 +0200 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/DeoptimizeOnExceptionTest.java 2017-04-28 11:49:03.000000000 +0200 @@ -30,10 +30,10 @@ import org.junit.Assert; import org.junit.Test; -import jdk.internal.org.objectweb.asm.ClassWriter; -import jdk.internal.org.objectweb.asm.Label; -import jdk.internal.org.objectweb.asm.MethodVisitor; -import jdk.internal.org.objectweb.asm.Opcodes; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.Label; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; import jdk.vm.ci.meta.ResolvedJavaMethod; /** --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/GraalServices.java 2017-04-28 11:49:04.000000000 +0200 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/GraalServices.java 2017-04-28 11:49:04.000000000 +0200 @@ -22,9 +22,17 @@ */ package org.graalvm.compiler.serviceprovider; +import static org.graalvm.compiler.serviceprovider.JDK9Method.Java8OrEarlier; +import static org.graalvm.compiler.serviceprovider.JDK9Method.addOpens; +import static org.graalvm.compiler.serviceprovider.JDK9Method.getModule; +import static org.graalvm.compiler.serviceprovider.JDK9Method.getPackages; +import static org.graalvm.compiler.serviceprovider.JDK9Method.isOpenTo; + +import java.lang.reflect.Method; import java.util.Iterator; import java.util.ServiceConfigurationError; import java.util.ServiceLoader; +import java.util.Set; import jdk.vm.ci.services.JVMCIPermission; import jdk.vm.ci.services.Services; @@ -32,14 +40,32 @@ /** * A mechanism for accessing service providers that abstracts over whether Graal is running on * JVMCI-8 or JVMCI-9. In JVMCI-8, a JVMCI specific mechanism is used to lookup services via the - * hidden JVMCI class loader. in JVMCI-9, the standard {@link ServiceLoader} mechanism is used. + * hidden JVMCI class loader. In JVMCI-9, the standard {@link ServiceLoader} mechanism is used. */ public final class GraalServices { private GraalServices() { } - public static final boolean Java8OrEarlier = System.getProperty("java.specification.version").compareTo("1.9") < 0; + /** + * Opens all JVMCI packages to the module of a given class. This relies on JVMCI already having + * opened all its packages to the module defining {@link GraalServices}. + * + * @param other all JVMCI packages will be opened to the module defining this class + */ + public static void openJVMCITo(Class other) { + Object jvmci = getModule.invoke(Services.class); + Object otherModule = getModule.invoke(other); + if (jvmci != otherModule) { + Set packages = getPackages.invoke(jvmci); + for (String pkg : packages) { + boolean opened = isOpenTo.invoke(jvmci, pkg, otherModule); + if (!opened) { + addOpens.invoke(jvmci, pkg, otherModule); + } + } + } + } /** * Gets an {@link Iterable} of the providers available for a given service. @@ -50,9 +76,9 @@ public static Iterable load(Class service) { assert !service.getName().startsWith("jdk.vm.ci") : "JVMCI services must be loaded via " + Services.class.getName(); if (Java8OrEarlier) { - return Services.load(service); + return load8(service); } - ServiceLoader iterable = ServiceLoader.load(service); + Iterable iterable = ServiceLoader.load(service); return new Iterable() { @Override public Iterator iterator() { @@ -66,8 +92,8 @@ @Override public S next() { S provider = iterator.next(); - // Allow Graal extensions to access JVMCI assuming they have JVMCIPermission - Services.exportJVMCITo(provider.getClass()); + // Allow Graal extensions to access JVMCI + openJVMCITo(provider.getClass()); return provider; } @@ -81,6 +107,23 @@ } /** + * {@code Services.load(Class)} is only defined in JVMCI-8. + */ + private static volatile Method loadMethod; + + @SuppressWarnings("unchecked") + private static Iterable load8(Class service) throws InternalError { + try { + if (loadMethod == null) { + loadMethod = Services.class.getMethod("load", Class.class); + } + return (Iterable) loadMethod.invoke(null, service); + } catch (Exception e) { + throw new InternalError(e); + } + } + + /** * Gets the provider for a given service for which at most one provider must be available. * * @param service the service whose provider is being requested @@ -92,16 +135,14 @@ */ public static S loadSingle(Class service, boolean required) { assert !service.getName().startsWith("jdk.vm.ci") : "JVMCI services must be loaded via " + Services.class.getName(); - if (Java8OrEarlier) { - return Services.loadSingle(service, required); - } - Iterable providers = ServiceLoader.load(service); + Iterable providers = load(service); S singleProvider = null; 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())); + S other = it.next(); + throw new InternalError(String.format("Multiple %s providers found: %s, %s", service.getName(), singleProvider.getClass().getName(), other.getClass().getName())); } } } catch (ServiceConfigurationError e) { @@ -111,9 +152,6 @@ if (required) { throw new InternalError(String.format("No provider for %s found", service.getName())); } - } else { - // Allow Graal extensions to access JVMCI assuming they have JVMCIPermission - Services.exportJVMCITo(singleProvider.getClass()); } return singleProvider; } --- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.test/src/org/graalvm/compiler/test/JLModule.java 2017-04-28 11:49:05.000000000 +0200 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.test/src/org/graalvm/compiler/test/JLModule.java 2017-04-28 11:49:04.000000000 +0200 @@ -96,6 +96,7 @@ } } + @SuppressWarnings("unchecked") public Set getPackages() { try { return (Set) getPackagesMethod.invoke(realModule); --- old/src/share/vm/runtime/arguments.cpp 2017-04-28 11:49:05.000000000 +0200 +++ new/src/share/vm/runtime/arguments.cpp 2017-04-28 11:49:05.000000000 +0200 @@ -2515,6 +2515,9 @@ status = status && check_jvmci_args_consistency(); if (EnableJVMCI) { + PropertyList_unique_add(&_system_properties, "jdk.internal.vm.ci.enabled", "true", + AddProperty, UnwriteableProperty, InternalProperty); + if (!ScavengeRootsInCode) { warning("forcing ScavengeRootsInCode non-zero because JVMCI is enabled"); ScavengeRootsInCode = 1; --- old/test/compiler/jvmci/JVM_GetJVMCIRuntimeTest.java 2017-04-28 11:49:06.000000000 +0200 +++ new/test/compiler/jvmci/JVM_GetJVMCIRuntimeTest.java 2017-04-28 11:49:06.000000000 +0200 @@ -30,7 +30,7 @@ * @modules jdk.internal.vm.ci/jdk.vm.ci.runtime * @run main/othervm -XX:+UnlockExperimentalVMOptions * -Dcompiler.jvmci.JVM_GetJVMCIRuntimeTest.positive=true - * -XX:+EnableJVMCI + * -XX:+EnableJVMCI -Djvmci.Compiler=null * compiler.jvmci.JVM_GetJVMCIRuntimeTest * @run main/othervm -XX:+UnlockExperimentalVMOptions * -Dcompiler.jvmci.JVM_GetJVMCIRuntimeTest.positive=false @@ -39,7 +39,7 @@ * @run main/othervm -XX:+UnlockExperimentalVMOptions * -Dcompiler.jvmci.JVM_GetJVMCIRuntimeTest.positive=true * -Dcompiler.jvmci.JVM_GetJVMCIRuntimeTest.threaded=true - * -XX:+EnableJVMCI + * -XX:+EnableJVMCI -Djvmci.Compiler=null * compiler.jvmci.JVM_GetJVMCIRuntimeTest * @run main/othervm -XX:+UnlockExperimentalVMOptions * -Dcompiler.jvmci.JVM_GetJVMCIRuntimeTest.positive=false --- old/test/compiler/jvmci/TestJVMCIPrintProperties.java 2017-04-28 11:49:07.000000000 +0200 +++ new/test/compiler/jvmci/TestJVMCIPrintProperties.java 2017-04-28 11:49:07.000000000 +0200 @@ -36,11 +36,11 @@ public static void main(String[] args) throws Exception { ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( "-XX:+UnlockExperimentalVMOptions", - "-XX:+EnableJVMCI", + "-XX:+EnableJVMCI", "-Djvmci.Compiler=null", "-XX:+JVMCIPrintProperties"); OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldContain("[JVMCI properties]"); // expected message - output.shouldContain("jvmci.Compiler = null"); // expected message + output.shouldContain("jvmci.Compiler := \"null\""); // expected message output.shouldContain("jvmci.InitTimer = false"); // expected message output.shouldContain("jvmci.PrintConfig = false"); // expected message output.shouldContain("jvmci.TraceMethodDataFilter = null"); // expected message --- old/test/compiler/jvmci/compilerToVM/AsResolvedJavaMethodTest.java 2017-04-28 11:49:07.000000000 +0200 +++ new/test/compiler/jvmci/compilerToVM/AsResolvedJavaMethodTest.java 2017-04-28 11:49:07.000000000 +0200 @@ -34,7 +34,7 @@ * jdk.internal.vm.ci/jdk.vm.ci.code * jdk.internal.vm.ci/jdk.vm.ci.meta * @build jdk.internal.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper - * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI + * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -Djvmci.Compiler=null * compiler.jvmci.compilerToVM.AsResolvedJavaMethodTest */ --- old/test/compiler/jvmci/compilerToVM/DoNotInlineOrCompileTest.java 2017-04-28 11:49:08.000000000 +0200 +++ new/test/compiler/jvmci/compilerToVM/DoNotInlineOrCompileTest.java 2017-04-28 11:49:08.000000000 +0200 @@ -39,6 +39,7 @@ * @run main/othervm -Xbootclasspath/a:. * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI * -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI + * -Djvmci.Compiler=null * compiler.jvmci.compilerToVM.DoNotInlineOrCompileTest */ --- old/test/compiler/jvmci/compilerToVM/FindUniqueConcreteMethodTest.java 2017-04-28 11:49:09.000000000 +0200 +++ new/test/compiler/jvmci/compilerToVM/FindUniqueConcreteMethodTest.java 2017-04-28 11:49:08.000000000 +0200 @@ -36,6 +36,7 @@ * jdk.internal.vm.ci/jdk.vm.ci.runtime * @build jdk.internal.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI + * -Djvmci.Compiler=null * compiler.jvmci.compilerToVM.FindUniqueConcreteMethodTest */ --- old/test/compiler/jvmci/compilerToVM/GetBytecodeTest.java 2017-04-28 11:49:09.000000000 +0200 +++ new/test/compiler/jvmci/compilerToVM/GetBytecodeTest.java 2017-04-28 11:49:09.000000000 +0200 @@ -34,6 +34,7 @@ * jdk.internal.vm.ci/jdk.vm.ci.code * @build jdk.internal.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI + * -Djvmci.Compiler=null * compiler.jvmci.compilerToVM.GetBytecodeTest */ --- old/test/compiler/jvmci/compilerToVM/GetClassInitializerTest.java 2017-04-28 11:49:10.000000000 +0200 +++ new/test/compiler/jvmci/compilerToVM/GetClassInitializerTest.java 2017-04-28 11:49:10.000000000 +0200 @@ -31,6 +31,7 @@ * @modules jdk.internal.vm.ci/jdk.vm.ci.hotspot * @build jdk.internal.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI + * -Djvmci.Compiler=null * compiler.jvmci.compilerToVM.GetClassInitializerTest */ --- old/test/compiler/jvmci/compilerToVM/GetConstantPoolTest.java 2017-04-28 11:49:11.000000000 +0200 +++ new/test/compiler/jvmci/compilerToVM/GetConstantPoolTest.java 2017-04-28 11:49:10.000000000 +0200 @@ -38,6 +38,7 @@ * @run main/othervm -Xbootclasspath/a:. * -XX:+UnlockDiagnosticVMOptions * -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI + * -Djvmci.Compiler=null * compiler.jvmci.compilerToVM.GetConstantPoolTest */ package compiler.jvmci.compilerToVM; --- old/test/compiler/jvmci/compilerToVM/GetExceptionTableTest.java 2017-04-28 11:49:11.000000000 +0200 +++ new/test/compiler/jvmci/compilerToVM/GetExceptionTableTest.java 2017-04-28 11:49:11.000000000 +0200 @@ -34,6 +34,7 @@ * jdk.internal.vm.ci/jdk.vm.ci.code * @build jdk.internal.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI + * -Djvmci.Compiler=null * compiler.jvmci.compilerToVM.GetExceptionTableTest */ @@ -137,4 +138,3 @@ } } } - --- old/test/compiler/jvmci/compilerToVM/GetImplementorTest.java 2017-04-28 11:49:12.000000000 +0200 +++ new/test/compiler/jvmci/compilerToVM/GetImplementorTest.java 2017-04-28 11:49:12.000000000 +0200 @@ -31,6 +31,7 @@ * @modules jdk.internal.vm.ci/jdk.vm.ci.hotspot * @build jdk.internal.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI + * -Djvmci.Compiler=null * compiler.jvmci.compilerToVM.GetImplementorTest */ --- old/test/compiler/jvmci/compilerToVM/GetLineNumberTableTest.java 2017-04-28 11:49:12.000000000 +0200 +++ new/test/compiler/jvmci/compilerToVM/GetLineNumberTableTest.java 2017-04-28 11:49:12.000000000 +0200 @@ -35,6 +35,7 @@ * jdk.internal.vm.ci/jdk.vm.ci.code * @build jdk.internal.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI + * -Djvmci.Compiler=null * compiler.jvmci.compilerToVM.GetLineNumberTableTest */ --- old/test/compiler/jvmci/compilerToVM/GetLocalVariableTableTest.java 2017-04-28 11:49:13.000000000 +0200 +++ new/test/compiler/jvmci/compilerToVM/GetLocalVariableTableTest.java 2017-04-28 11:49:13.000000000 +0200 @@ -38,6 +38,7 @@ * @compile -g DummyClass.java * @build jdk.internal.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI + * -Djvmci.Compiler=null * compiler.jvmci.compilerToVM.GetLocalVariableTableTest * @clean compiler.jvmci.compilerToVM.* */ --- old/test/compiler/jvmci/compilerToVM/GetNextStackFrameTest.java 2017-04-28 11:49:14.000000000 +0200 +++ new/test/compiler/jvmci/compilerToVM/GetNextStackFrameTest.java 2017-04-28 11:49:14.000000000 +0200 @@ -35,6 +35,7 @@ * jdk.internal.vm.ci/jdk.vm.ci.meta * @build jdk.internal.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI + * -Djvmci.Compiler=null * compiler.jvmci.compilerToVM.GetNextStackFrameTest */ --- old/test/compiler/jvmci/compilerToVM/GetResolvedJavaMethodTest.java 2017-04-28 11:49:14.000000000 +0200 +++ new/test/compiler/jvmci/compilerToVM/GetResolvedJavaMethodTest.java 2017-04-28 11:49:14.000000000 +0200 @@ -38,6 +38,7 @@ * @run main/othervm -Xbootclasspath/a:. * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI * -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI + * -Djvmci.Compiler=null * compiler.jvmci.compilerToVM.GetResolvedJavaMethodTest */ --- old/test/compiler/jvmci/compilerToVM/GetResolvedJavaTypeTest.java 2017-04-28 11:49:15.000000000 +0200 +++ new/test/compiler/jvmci/compilerToVM/GetResolvedJavaTypeTest.java 2017-04-28 11:49:15.000000000 +0200 @@ -44,7 +44,7 @@ * @run main/othervm -Xbootclasspath/a:. * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI * -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI - * -XX:-UseCompressedOops + * -XX:-UseCompressedOops -Djvmci.Compiler=null * compiler.jvmci.compilerToVM.GetResolvedJavaTypeTest */ --- old/test/compiler/jvmci/compilerToVM/GetStackTraceElementTest.java 2017-04-28 11:49:16.000000000 +0200 +++ new/test/compiler/jvmci/compilerToVM/GetStackTraceElementTest.java 2017-04-28 11:49:16.000000000 +0200 @@ -34,6 +34,7 @@ * jdk.internal.vm.ci/jdk.vm.ci.code * @build jdk.internal.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI + * -Djvmci.Compiler=null * compiler.jvmci.compilerToVM.GetStackTraceElementTest */ --- old/test/compiler/jvmci/compilerToVM/GetSymbolTest.java 2017-04-28 11:49:17.000000000 +0200 +++ new/test/compiler/jvmci/compilerToVM/GetSymbolTest.java 2017-04-28 11:49:16.000000000 +0200 @@ -35,6 +35,7 @@ * jdk.internal.vm.ci/jdk.vm.ci.meta * @build jdk.internal.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI + * -Djvmci.Compiler=null * compiler.jvmci.compilerToVM.GetSymbolTest */ --- old/test/compiler/jvmci/compilerToVM/GetVtableIndexForInterfaceTest.java 2017-04-28 11:49:17.000000000 +0200 +++ new/test/compiler/jvmci/compilerToVM/GetVtableIndexForInterfaceTest.java 2017-04-28 11:49:17.000000000 +0200 @@ -34,6 +34,7 @@ * jdk.internal.vm.ci/jdk.vm.ci.code * @build jdk.internal.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI + * -Djvmci.Compiler=null * compiler.jvmci.compilerToVM.GetVtableIndexForInterfaceTest */ --- old/test/compiler/jvmci/compilerToVM/HasCompiledCodeForOSRTest.java 2017-04-28 11:49:18.000000000 +0200 +++ new/test/compiler/jvmci/compilerToVM/HasCompiledCodeForOSRTest.java 2017-04-28 11:49:18.000000000 +0200 @@ -39,7 +39,7 @@ * @run main/othervm -Xbootclasspath/a:. * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI * -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI - * -XX:-BackgroundCompilation + * -XX:-BackgroundCompilation -Djvmci.Compiler=null * compiler.jvmci.compilerToVM.HasCompiledCodeForOSRTest */ --- old/test/compiler/jvmci/compilerToVM/HasFinalizableSubclassTest.java 2017-04-28 11:49:19.000000000 +0200 +++ new/test/compiler/jvmci/compilerToVM/HasFinalizableSubclassTest.java 2017-04-28 11:49:18.000000000 +0200 @@ -31,7 +31,8 @@ * @modules jdk.internal.vm.ci/jdk.vm.ci.hotspot * @build jdk.internal.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI - * compiler.jvmci.compilerToVM.HasFinalizableSubclassTest + * -Djvmci.Compiler=null + * compiler.jvmci.compilerToVM.HasFinalizableSubclassTest */ package compiler.jvmci.compilerToVM; --- old/test/compiler/jvmci/compilerToVM/HasNeverInlineDirectiveTest.java 2017-04-28 11:49:19.000000000 +0200 +++ new/test/compiler/jvmci/compilerToVM/HasNeverInlineDirectiveTest.java 2017-04-28 11:49:19.000000000 +0200 @@ -39,6 +39,7 @@ * @run main/othervm -Xbootclasspath/a:. * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI * -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI + * -Djvmci.Compiler=null * compiler.jvmci.compilerToVM.HasNeverInlineDirectiveTest */ --- old/test/compiler/jvmci/compilerToVM/InvalidateInstalledCodeTest.java 2017-04-28 11:49:20.000000000 +0200 +++ new/test/compiler/jvmci/compilerToVM/InvalidateInstalledCodeTest.java 2017-04-28 11:49:20.000000000 +0200 @@ -42,6 +42,7 @@ * @run main/othervm -Xbootclasspath/a:. * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI * -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI + * -Djvmci.Compiler=null * compiler.jvmci.compilerToVM.InvalidateInstalledCodeTest */ --- old/test/compiler/jvmci/compilerToVM/IsCompilableTest.java 2017-04-28 11:49:21.000000000 +0200 +++ new/test/compiler/jvmci/compilerToVM/IsCompilableTest.java 2017-04-28 11:49:20.000000000 +0200 @@ -39,10 +39,12 @@ * @run main/othervm -Xbootclasspath/a:. * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI * -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:+UseJVMCICompiler + * -Djvmci.Compiler=null * compiler.jvmci.compilerToVM.IsCompilableTest * @run main/othervm -Xbootclasspath/a:. * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI * -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:-UseJVMCICompiler + * -Djvmci.Compiler=null * compiler.jvmci.compilerToVM.IsCompilableTest */ --- old/test/compiler/jvmci/compilerToVM/IsMatureVsReprofileTest.java 2017-04-28 11:49:21.000000000 +0200 +++ new/test/compiler/jvmci/compilerToVM/IsMatureVsReprofileTest.java 2017-04-28 11:49:21.000000000 +0200 @@ -38,6 +38,7 @@ * sun.hotspot.WhiteBox$WhiteBoxPermission * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -Xbatch + * -Djvmci.Compiler=null * compiler.jvmci.compilerToVM.IsMatureVsReprofileTest */ --- old/test/compiler/jvmci/compilerToVM/LookupKlassInPoolTest.java 2017-04-28 11:49:22.000000000 +0200 +++ new/test/compiler/jvmci/compilerToVM/LookupKlassInPoolTest.java 2017-04-28 11:49:22.000000000 +0200 @@ -42,6 +42,7 @@ * @run main/othervm -Xbootclasspath/a:. * -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -Djvmci.Compiler=null * compiler.jvmci.compilerToVM.LookupKlassInPoolTest */ --- old/test/compiler/jvmci/compilerToVM/LookupKlassRefIndexInPoolTest.java 2017-04-28 11:49:22.000000000 +0200 +++ new/test/compiler/jvmci/compilerToVM/LookupKlassRefIndexInPoolTest.java 2017-04-28 11:49:22.000000000 +0200 @@ -40,6 +40,7 @@ * sun.hotspot.WhiteBox$WhiteBoxPermission * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI + * -Djvmci.Compiler=null * compiler.jvmci.compilerToVM.LookupKlassRefIndexInPoolTest */ --- old/test/compiler/jvmci/compilerToVM/LookupMethodInPoolTest.java 2017-04-28 11:49:23.000000000 +0200 +++ new/test/compiler/jvmci/compilerToVM/LookupMethodInPoolTest.java 2017-04-28 11:49:23.000000000 +0200 @@ -40,6 +40,7 @@ * sun.hotspot.WhiteBox$WhiteBoxPermission * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI + * -Djvmci.Compiler=null * compiler.jvmci.compilerToVM.LookupMethodInPoolTest */ --- old/test/compiler/jvmci/compilerToVM/LookupNameAndTypeRefIndexInPoolTest.java 2017-04-28 11:49:24.000000000 +0200 +++ new/test/compiler/jvmci/compilerToVM/LookupNameAndTypeRefIndexInPoolTest.java 2017-04-28 11:49:24.000000000 +0200 @@ -40,6 +40,7 @@ * sun.hotspot.WhiteBox$WhiteBoxPermission * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI + * -Djvmci.Compiler=null * compiler.jvmci.compilerToVM.LookupNameAndTypeRefIndexInPoolTest */ --- old/test/compiler/jvmci/compilerToVM/LookupNameInPoolTest.java 2017-04-28 11:49:24.000000000 +0200 +++ new/test/compiler/jvmci/compilerToVM/LookupNameInPoolTest.java 2017-04-28 11:49:24.000000000 +0200 @@ -41,6 +41,7 @@ * sun.hotspot.WhiteBox$WhiteBoxPermission * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI + * -Djvmci.Compiler=null * compiler.jvmci.compilerToVM.LookupNameInPoolTest */ --- old/test/compiler/jvmci/compilerToVM/LookupSignatureInPoolTest.java 2017-04-28 11:49:25.000000000 +0200 +++ new/test/compiler/jvmci/compilerToVM/LookupSignatureInPoolTest.java 2017-04-28 11:49:25.000000000 +0200 @@ -41,6 +41,7 @@ * sun.hotspot.WhiteBox$WhiteBoxPermission * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI + * -Djvmci.Compiler=null * compiler.jvmci.compilerToVM.LookupSignatureInPoolTest */ --- old/test/compiler/jvmci/compilerToVM/LookupTypeTest.java 2017-04-28 11:49:26.000000000 +0200 +++ new/test/compiler/jvmci/compilerToVM/LookupTypeTest.java 2017-04-28 11:49:26.000000000 +0200 @@ -31,6 +31,7 @@ * @modules jdk.internal.vm.ci/jdk.vm.ci.hotspot * @build jdk.internal.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI + * -Djvmci.Compiler=null * compiler.jvmci.compilerToVM.LookupTypeTest */ --- old/test/compiler/jvmci/compilerToVM/MaterializeVirtualObjectTest.java 2017-04-28 11:49:27.000000000 +0200 +++ new/test/compiler/jvmci/compilerToVM/MaterializeVirtualObjectTest.java 2017-04-28 11:49:27.000000000 +0200 @@ -49,6 +49,7 @@ * -XX:+DoEscapeAnalysis -XX:-UseCounterDecay * -Dcompiler.jvmci.compilerToVM.MaterializeVirtualObjectTest.materializeFirst=true * -Dcompiler.jvmci.compilerToVM.MaterializeVirtualObjectTest.invalidate=false + * -Djvmci.Compiler=null * compiler.jvmci.compilerToVM.MaterializeVirtualObjectTest * @run main/othervm -Xmixed -Xbatch -Xbootclasspath/a:. * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI @@ -60,6 +61,7 @@ * -XX:+DoEscapeAnalysis -XX:-UseCounterDecay * -Dcompiler.jvmci.compilerToVM.MaterializeVirtualObjectTest.materializeFirst=false * -Dcompiler.jvmci.compilerToVM.MaterializeVirtualObjectTest.invalidate=false + * -Djvmci.Compiler=null * compiler.jvmci.compilerToVM.MaterializeVirtualObjectTest * @run main/othervm -Xmixed -Xbatch -Xbootclasspath/a:. * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI @@ -71,6 +73,7 @@ * -XX:+DoEscapeAnalysis -XX:-UseCounterDecay * -Dcompiler.jvmci.compilerToVM.MaterializeVirtualObjectTest.materializeFirst=true * -Dcompiler.jvmci.compilerToVM.MaterializeVirtualObjectTest.invalidate=true + * -Djvmci.Compiler=null * compiler.jvmci.compilerToVM.MaterializeVirtualObjectTest * @run main/othervm -Xmixed -Xbatch -Xbootclasspath/a:. * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI @@ -82,6 +85,7 @@ * -XX:+DoEscapeAnalysis -XX:-UseCounterDecay * -Dcompiler.jvmci.compilerToVM.MaterializeVirtualObjectTest.materializeFirst=false * -Dcompiler.jvmci.compilerToVM.MaterializeVirtualObjectTest.invalidate=true + * -Djvmci.Compiler=null * compiler.jvmci.compilerToVM.MaterializeVirtualObjectTest */ --- old/test/compiler/jvmci/compilerToVM/MethodIsIgnoredBySecurityStackWalkTest.java 2017-04-28 11:49:27.000000000 +0200 +++ new/test/compiler/jvmci/compilerToVM/MethodIsIgnoredBySecurityStackWalkTest.java 2017-04-28 11:49:27.000000000 +0200 @@ -35,6 +35,7 @@ * jdk.internal.vm.ci/jdk.vm.ci.code * @build jdk.internal.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI + * -Djvmci.Compiler=null * compiler.jvmci.compilerToVM.MethodIsIgnoredBySecurityStackWalkTest */ --- old/test/compiler/jvmci/compilerToVM/ReadConfigurationTest.java 2017-04-28 11:49:28.000000000 +0200 +++ new/test/compiler/jvmci/compilerToVM/ReadConfigurationTest.java 2017-04-28 11:49:28.000000000 +0200 @@ -32,6 +32,7 @@ * @build jdk.internal.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper * @build compiler.jvmci.compilerToVM.ReadConfigurationTest * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI + * -Djvmci.Compiler=null * compiler.jvmci.compilerToVM.ReadConfigurationTest */ --- old/test/compiler/jvmci/compilerToVM/ReprofileTest.java 2017-04-28 11:49:29.000000000 +0200 +++ new/test/compiler/jvmci/compilerToVM/ReprofileTest.java 2017-04-28 11:49:29.000000000 +0200 @@ -40,7 +40,7 @@ * @run main/othervm -Xbootclasspath/a:. * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI * -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI - * -Xmixed -Xbatch + * -Xmixed -Xbatch -Djvmci.Compiler=null * compiler.jvmci.compilerToVM.ReprofileTest */ --- old/test/compiler/jvmci/compilerToVM/ResolveConstantInPoolTest.java 2017-04-28 11:49:30.000000000 +0200 +++ new/test/compiler/jvmci/compilerToVM/ResolveConstantInPoolTest.java 2017-04-28 11:49:29.000000000 +0200 @@ -40,6 +40,7 @@ * @run main/othervm -Xbootclasspath/a:. * -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -Djvmci.Compiler=null * compiler.jvmci.compilerToVM.ResolveConstantInPoolTest */ --- old/test/compiler/jvmci/compilerToVM/ResolveFieldInPoolTest.java 2017-04-28 11:49:31.000000000 +0200 +++ new/test/compiler/jvmci/compilerToVM/ResolveFieldInPoolTest.java 2017-04-28 11:49:30.000000000 +0200 @@ -40,6 +40,7 @@ * sun.hotspot.WhiteBox$WhiteBoxPermission * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI + * -Djvmci.Compiler=null * compiler.jvmci.compilerToVM.ResolveFieldInPoolTest */ --- old/test/compiler/jvmci/compilerToVM/ResolveMethodTest.java 2017-04-28 11:49:31.000000000 +0200 +++ new/test/compiler/jvmci/compilerToVM/ResolveMethodTest.java 2017-04-28 11:49:31.000000000 +0200 @@ -34,6 +34,7 @@ * jdk.internal.vm.ci/jdk.vm.ci.code * @build jdk.internal.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI + * -Djvmci.Compiler=null * compiler.jvmci.compilerToVM.ResolveMethodTest */ --- old/test/compiler/jvmci/compilerToVM/ResolvePossiblyCachedConstantInPoolTest.java 2017-04-28 11:49:32.000000000 +0200 +++ new/test/compiler/jvmci/compilerToVM/ResolvePossiblyCachedConstantInPoolTest.java 2017-04-28 11:49:32.000000000 +0200 @@ -40,6 +40,7 @@ * sun.hotspot.WhiteBox$WhiteBoxPermission * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI + * -Djvmci.Compiler=null * compiler.jvmci.compilerToVM.ResolvePossiblyCachedConstantInPoolTest */ --- old/test/compiler/jvmci/compilerToVM/ResolveTypeInPoolTest.java 2017-04-28 11:49:33.000000000 +0200 +++ new/test/compiler/jvmci/compilerToVM/ResolveTypeInPoolTest.java 2017-04-28 11:49:33.000000000 +0200 @@ -41,6 +41,7 @@ * @run main/othervm -Xbootclasspath/a:. * -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -Djvmci.Compiler=null * compiler.jvmci.compilerToVM.ResolveTypeInPoolTest */ --- old/test/compiler/jvmci/compilerToVM/ShouldInlineMethodTest.java 2017-04-28 11:49:34.000000000 +0200 +++ new/test/compiler/jvmci/compilerToVM/ShouldInlineMethodTest.java 2017-04-28 11:49:33.000000000 +0200 @@ -39,6 +39,7 @@ * @run main/othervm -Xbootclasspath/a:. * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI * -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI + * -Djvmci.Compiler=null * compiler.jvmci.compilerToVM.ShouldInlineMethodTest */ --- old/test/compiler/jvmci/errors/TestInvalidCompilationResult.java 2017-04-28 11:49:34.000000000 +0200 +++ new/test/compiler/jvmci/errors/TestInvalidCompilationResult.java 2017-04-28 11:49:34.000000000 +0200 @@ -31,7 +31,8 @@ * jdk.internal.vm.ci/jdk.vm.ci.runtime * jdk.internal.vm.ci/jdk.vm.ci.common * @compile CodeInstallerTest.java - * @run junit/othervm -da:jdk.vm.ci... -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI compiler.jvmci.errors.TestInvalidCompilationResult + * @run junit/othervm -da:jdk.vm.ci... -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI + * -Djvmci.Compiler=null compiler.jvmci.errors.TestInvalidCompilationResult */ package compiler.jvmci.errors; --- old/test/compiler/jvmci/errors/TestInvalidDebugInfo.java 2017-04-28 11:49:35.000000000 +0200 +++ new/test/compiler/jvmci/errors/TestInvalidDebugInfo.java 2017-04-28 11:49:35.000000000 +0200 @@ -31,7 +31,8 @@ * jdk.internal.vm.ci/jdk.vm.ci.runtime * jdk.internal.vm.ci/jdk.vm.ci.common * @compile CodeInstallerTest.java - * @run junit/othervm -da:jdk.vm.ci... -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI compiler.jvmci.errors.TestInvalidDebugInfo + * @run junit/othervm -da:jdk.vm.ci... -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI + * -Djvmci.Compiler=null compiler.jvmci.errors.TestInvalidDebugInfo */ package compiler.jvmci.errors; --- old/test/compiler/jvmci/errors/TestInvalidOopMap.java 2017-04-28 11:49:36.000000000 +0200 +++ new/test/compiler/jvmci/errors/TestInvalidOopMap.java 2017-04-28 11:49:36.000000000 +0200 @@ -31,7 +31,8 @@ * jdk.internal.vm.ci/jdk.vm.ci.runtime * jdk.internal.vm.ci/jdk.vm.ci.common * @compile CodeInstallerTest.java - * @run junit/othervm -da:jdk.vm.ci... -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI compiler.jvmci.errors.TestInvalidOopMap + * @run junit/othervm -da:jdk.vm.ci... -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI + * -Djvmci.Compiler=null compiler.jvmci.errors.TestInvalidOopMap */ package compiler.jvmci.errors; --- old/test/compiler/jvmci/events/JvmciNotifyInstallEventTest.java 2017-04-28 11:49:38.000000000 +0200 +++ new/test/compiler/jvmci/events/JvmciNotifyInstallEventTest.java 2017-04-28 11:49:38.000000000 +0200 @@ -49,21 +49,14 @@ * @run main/othervm -XX:+UnlockExperimentalVMOptions * -Xbootclasspath/a:. -Xmixed * -XX:+UseJVMCICompiler -XX:-BootstrapJVMCI - * -Dcompiler.jvmci.events.JvmciNotifyInstallEventTest.failoninit=false * compiler.jvmci.events.JvmciNotifyInstallEventTest * @run main/othervm -XX:+UnlockExperimentalVMOptions - * -Djvmci.compiler=EmptyCompiler -Xbootclasspath/a:. -Xmixed + * -Djvmci.Compiler=EmptyCompiler -Xbootclasspath/a:. -Xmixed * -XX:+UseJVMCICompiler -XX:-BootstrapJVMCI - * -Dcompiler.jvmci.events.JvmciNotifyInstallEventTest.failoninit=false * compiler.jvmci.events.JvmciNotifyInstallEventTest * @run main/othervm -XX:+UnlockExperimentalVMOptions - * -Djvmci.compiler=EmptyCompiler -Xbootclasspath/a:. -Xmixed + * -Djvmci.Compiler=EmptyCompiler -Xbootclasspath/a:. -Xmixed * -XX:+UseJVMCICompiler -XX:-BootstrapJVMCI -XX:JVMCINMethodSizeLimit=0 - * -Dcompiler.jvmci.events.JvmciNotifyInstallEventTest.failoninit=false - * compiler.jvmci.events.JvmciNotifyInstallEventTest - * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:-EnableJVMCI - * -Djvmci.compiler=EmptyCompiler -Xbootclasspath/a:. -Xmixed - * -Dcompiler.jvmci.events.JvmciNotifyInstallEventTest.failoninit=true * compiler.jvmci.events.JvmciNotifyInstallEventTest */ @@ -91,8 +84,6 @@ public class JvmciNotifyInstallEventTest extends JVMCIServiceLocator implements HotSpotVMEventListener { private static final String METHOD_NAME = "testMethod"; - private static final boolean FAIL_ON_INIT = !Boolean.getBoolean( - "compiler.jvmci.events.JvmciNotifyInstallEventTest.failoninit"); private static volatile int gotInstallNotification = 0; public static void main(String args[]) { @@ -116,16 +107,9 @@ codeCache = (HotSpotCodeCacheProvider) HotSpotJVMCIRuntime.runtime() .getHostJVMCIBackend().getCodeCache(); } catch (InternalError ie) { - if (FAIL_ON_INIT) { - throw new AssertionError( - "Got unexpected InternalError trying to get code cache", - ie); - } // passed return; } - Asserts.assertTrue(FAIL_ON_INIT, - "Haven't caught InternalError in negative case"); Method testMethod; try { testMethod = SimpleClass.class.getDeclaredMethod(METHOD_NAME); --- old/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/DataPatchTest.java 2017-04-28 11:49:39.000000000 +0200 +++ new/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/DataPatchTest.java 2017-04-28 11:49:39.000000000 +0200 @@ -33,7 +33,7 @@ * jdk.internal.vm.ci/jdk.vm.ci.amd64 * jdk.internal.vm.ci/jdk.vm.ci.sparc * @compile CodeInstallationTest.java DebugInfoTest.java TestAssembler.java TestHotSpotVMConfig.java amd64/AMD64TestAssembler.java sparc/SPARCTestAssembler.java - * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI jdk.vm.ci.code.test.DataPatchTest + * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -Djvmci.Compiler=null jdk.vm.ci.code.test.DataPatchTest */ package jdk.vm.ci.code.test; --- old/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/InterpreterFrameSizeTest.java 2017-04-28 11:49:39.000000000 +0200 +++ new/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/InterpreterFrameSizeTest.java 2017-04-28 11:49:39.000000000 +0200 @@ -33,7 +33,7 @@ * jdk.internal.vm.ci/jdk.vm.ci.amd64 * jdk.internal.vm.ci/jdk.vm.ci.sparc * @compile CodeInstallationTest.java TestAssembler.java TestHotSpotVMConfig.java amd64/AMD64TestAssembler.java sparc/SPARCTestAssembler.java - * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI jdk.vm.ci.code.test.InterpreterFrameSizeTest + * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -Djvmci.Compiler=null jdk.vm.ci.code.test.InterpreterFrameSizeTest */ package jdk.vm.ci.code.test; --- old/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/MaxOopMapStackOffsetTest.java 2017-04-28 11:49:40.000000000 +0200 +++ new/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/MaxOopMapStackOffsetTest.java 2017-04-28 11:49:40.000000000 +0200 @@ -34,7 +34,7 @@ * jdk.internal.vm.ci/jdk.vm.ci.amd64 * jdk.internal.vm.ci/jdk.vm.ci.sparc * @compile CodeInstallationTest.java DebugInfoTest.java TestAssembler.java TestHotSpotVMConfig.java amd64/AMD64TestAssembler.java sparc/SPARCTestAssembler.java - * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI jdk.vm.ci.code.test.MaxOopMapStackOffsetTest + * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -Djvmci.Compiler=null jdk.vm.ci.code.test.MaxOopMapStackOffsetTest */ package jdk.vm.ci.code.test; --- old/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/SimpleCodeInstallationTest.java 2017-04-28 11:49:41.000000000 +0200 +++ new/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/SimpleCodeInstallationTest.java 2017-04-28 11:49:40.000000000 +0200 @@ -33,7 +33,7 @@ * jdk.internal.vm.ci/jdk.vm.ci.amd64 * jdk.internal.vm.ci/jdk.vm.ci.sparc * @compile CodeInstallationTest.java DebugInfoTest.java TestAssembler.java TestHotSpotVMConfig.java amd64/AMD64TestAssembler.java sparc/SPARCTestAssembler.java - * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI jdk.vm.ci.code.test.SimpleCodeInstallationTest + * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -Djvmci.Compiler=null jdk.vm.ci.code.test.SimpleCodeInstallationTest */ package jdk.vm.ci.code.test; --- old/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/SimpleDebugInfoTest.java 2017-04-28 11:49:41.000000000 +0200 +++ new/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/SimpleDebugInfoTest.java 2017-04-28 11:49:41.000000000 +0200 @@ -33,7 +33,7 @@ * jdk.internal.vm.ci/jdk.vm.ci.amd64 * jdk.internal.vm.ci/jdk.vm.ci.sparc * @compile CodeInstallationTest.java DebugInfoTest.java TestAssembler.java TestHotSpotVMConfig.java amd64/AMD64TestAssembler.java sparc/SPARCTestAssembler.java - * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI jdk.vm.ci.code.test.SimpleDebugInfoTest + * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -Djvmci.Compiler=null jdk.vm.ci.code.test.SimpleDebugInfoTest */ package jdk.vm.ci.code.test; --- old/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/VirtualObjectDebugInfoTest.java 2017-04-28 11:49:42.000000000 +0200 +++ new/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/VirtualObjectDebugInfoTest.java 2017-04-28 11:49:42.000000000 +0200 @@ -33,7 +33,7 @@ * jdk.internal.vm.ci/jdk.vm.ci.amd64 * jdk.internal.vm.ci/jdk.vm.ci.sparc * @compile CodeInstallationTest.java DebugInfoTest.java TestAssembler.java TestHotSpotVMConfig.java amd64/AMD64TestAssembler.java sparc/SPARCTestAssembler.java - * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI jdk.vm.ci.code.test.VirtualObjectDebugInfoTest + * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -Djvmci.Compiler=null jdk.vm.ci.code.test.VirtualObjectDebugInfoTest */ package jdk.vm.ci.code.test; --- old/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/HotSpotConstantReflectionProviderTest.java 2017-04-28 11:49:42.000000000 +0200 +++ new/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/HotSpotConstantReflectionProviderTest.java 2017-04-28 11:49:42.000000000 +0200 @@ -34,7 +34,7 @@ * @run driver ClassFileInstaller jdk.vm.ci.hotspot.test.DummyClass * @run testng/othervm/timeout=300 -Xbootclasspath/a:. * -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI - * jdk.vm.ci.hotspot.test.HotSpotConstantReflectionProviderTest + * -Djvmci.Compiler=null jdk.vm.ci.hotspot.test.HotSpotConstantReflectionProviderTest */ package jdk.vm.ci.hotspot.test; --- old/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/MemoryAccessProviderTest.java 2017-04-28 11:49:43.000000000 +0200 +++ new/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/MemoryAccessProviderTest.java 2017-04-28 11:49:43.000000000 +0200 @@ -37,7 +37,7 @@ * @run testng/othervm -Xbootclasspath/a:. * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI * -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI - * jdk.vm.ci.hotspot.test.MemoryAccessProviderTest + * -Djvmci.Compiler=null jdk.vm.ci.hotspot.test.MemoryAccessProviderTest */ package jdk.vm.ci.hotspot.test; --- old/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/MethodHandleAccessProviderTest.java 2017-04-28 11:49:44.000000000 +0200 +++ new/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/MethodHandleAccessProviderTest.java 2017-04-28 11:49:44.000000000 +0200 @@ -32,7 +32,7 @@ * jdk.internal.vm.ci/jdk.vm.ci.runtime * @modules jdk.internal.vm.ci/jdk.vm.ci.hotspot:+open * @run testng/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI - * jdk.vm.ci.hotspot.test.MethodHandleAccessProviderTest + * -Djvmci.Compiler=null jdk.vm.ci.hotspot.test.MethodHandleAccessProviderTest */ package jdk.vm.ci.hotspot.test; --- old/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ConstantTest.java 2017-04-28 11:49:45.000000000 +0200 +++ new/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ConstantTest.java 2017-04-28 11:49:44.000000000 +0200 @@ -28,7 +28,7 @@ * @modules jdk.internal.vm.ci/jdk.vm.ci.meta * jdk.internal.vm.ci/jdk.vm.ci.runtime * java.base/jdk.internal.misc - * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI jdk.vm.ci.runtime.test.ConstantTest + * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -Djvmci.Compiler=null jdk.vm.ci.runtime.test.ConstantTest */ package jdk.vm.ci.runtime.test; --- old/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/RedefineClassTest.java 2017-04-28 11:49:45.000000000 +0200 +++ new/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/RedefineClassTest.java 2017-04-28 11:49:45.000000000 +0200 @@ -29,7 +29,7 @@ * jdk.internal.vm.ci/jdk.vm.ci.runtime * jdk.attach * java.base/jdk.internal.misc - * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI jdk.vm.ci.runtime.test.RedefineClassTest + * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -Djvmci.Compiler=null jdk.vm.ci.runtime.test.RedefineClassTest */ package jdk.vm.ci.runtime.test; --- old/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ResolvedJavaTypeResolveConcreteMethodTest.java 2017-04-28 11:49:46.000000000 +0200 +++ new/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ResolvedJavaTypeResolveConcreteMethodTest.java 2017-04-28 11:49:46.000000000 +0200 @@ -26,7 +26,7 @@ * @requires vm.jvmci * @modules jdk.internal.vm.ci/jdk.vm.ci.meta * jdk.internal.vm.ci/jdk.vm.ci.runtime - * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI jdk.vm.ci.runtime.test.ResolvedJavaTypeResolveConcreteMethodTest + * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -Djvmci.Compiler=null jdk.vm.ci.runtime.test.ResolvedJavaTypeResolveConcreteMethodTest */ package jdk.vm.ci.runtime.test; --- old/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ResolvedJavaTypeResolveMethodTest.java 2017-04-28 11:49:47.000000000 +0200 +++ new/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ResolvedJavaTypeResolveMethodTest.java 2017-04-28 11:49:46.000000000 +0200 @@ -26,7 +26,7 @@ * @requires vm.jvmci * @modules jdk.internal.vm.ci/jdk.vm.ci.meta * jdk.internal.vm.ci/jdk.vm.ci.runtime - * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI jdk.vm.ci.runtime.test.ResolvedJavaTypeResolveMethodTest + * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -Djvmci.Compiler=null jdk.vm.ci.runtime.test.ResolvedJavaTypeResolveMethodTest */ package jdk.vm.ci.runtime.test; --- old/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestConstantReflectionProvider.java 2017-04-28 11:49:47.000000000 +0200 +++ new/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestConstantReflectionProvider.java 2017-04-28 11:49:47.000000000 +0200 @@ -28,7 +28,7 @@ * @modules jdk.internal.vm.ci/jdk.vm.ci.meta * jdk.internal.vm.ci/jdk.vm.ci.runtime * java.base/jdk.internal.misc - * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI jdk.vm.ci.runtime.test.TestConstantReflectionProvider + * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -Djvmci.Compiler=null jdk.vm.ci.runtime.test.TestConstantReflectionProvider */ package jdk.vm.ci.runtime.test; --- old/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestJavaField.java 2017-04-28 11:49:48.000000000 +0200 +++ new/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestJavaField.java 2017-04-28 11:49:48.000000000 +0200 @@ -28,7 +28,7 @@ * @modules jdk.internal.vm.ci/jdk.vm.ci.meta * jdk.internal.vm.ci/jdk.vm.ci.runtime * java.base/jdk.internal.misc - * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI jdk.vm.ci.runtime.test.TestJavaField + * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -Djvmci.Compiler=null jdk.vm.ci.runtime.test.TestJavaField */ package jdk.vm.ci.runtime.test; --- old/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestJavaMethod.java 2017-04-28 11:49:49.000000000 +0200 +++ new/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestJavaMethod.java 2017-04-28 11:49:48.000000000 +0200 @@ -28,7 +28,7 @@ * @modules jdk.internal.vm.ci/jdk.vm.ci.meta * jdk.internal.vm.ci/jdk.vm.ci.runtime * java.base/jdk.internal.misc - * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI jdk.vm.ci.runtime.test.TestJavaMethod + * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -Djvmci.Compiler=null jdk.vm.ci.runtime.test.TestJavaMethod */ package jdk.vm.ci.runtime.test; --- old/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestJavaType.java 2017-04-28 11:49:49.000000000 +0200 +++ new/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestJavaType.java 2017-04-28 11:49:49.000000000 +0200 @@ -28,7 +28,7 @@ * @modules jdk.internal.vm.ci/jdk.vm.ci.meta * jdk.internal.vm.ci/jdk.vm.ci.runtime * java.base/jdk.internal.misc - * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI jdk.vm.ci.runtime.test.TestJavaType + * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -Djvmci.Compiler=null jdk.vm.ci.runtime.test.TestJavaType */ package jdk.vm.ci.runtime.test; --- old/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestMetaAccessProvider.java 2017-04-28 11:49:50.000000000 +0200 +++ new/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestMetaAccessProvider.java 2017-04-28 11:49:50.000000000 +0200 @@ -28,7 +28,7 @@ * @modules jdk.internal.vm.ci/jdk.vm.ci.meta * jdk.internal.vm.ci/jdk.vm.ci.runtime * java.base/jdk.internal.misc - * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI jdk.vm.ci.runtime.test.TestMetaAccessProvider + * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -Djvmci.Compiler=null jdk.vm.ci.runtime.test.TestMetaAccessProvider */ package jdk.vm.ci.runtime.test; --- old/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaField.java 2017-04-28 11:49:50.000000000 +0200 +++ new/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaField.java 2017-04-28 11:49:50.000000000 +0200 @@ -28,7 +28,7 @@ * @modules jdk.internal.vm.ci/jdk.vm.ci.meta * jdk.internal.vm.ci/jdk.vm.ci.runtime * java.base/jdk.internal.misc - * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI jdk.vm.ci.runtime.test.TestResolvedJavaField + * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -Djvmci.Compiler=null jdk.vm.ci.runtime.test.TestResolvedJavaField */ package jdk.vm.ci.runtime.test; --- old/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaMethod.java 2017-04-28 11:49:51.000000000 +0200 +++ new/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaMethod.java 2017-04-28 11:49:51.000000000 +0200 @@ -28,7 +28,7 @@ * @modules jdk.internal.vm.ci/jdk.vm.ci.meta * jdk.internal.vm.ci/jdk.vm.ci.runtime * java.base/jdk.internal.misc - * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI jdk.vm.ci.runtime.test.TestResolvedJavaMethod + * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -Djvmci.Compiler=null jdk.vm.ci.runtime.test.TestResolvedJavaMethod */ package jdk.vm.ci.runtime.test; --- old/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java 2017-04-28 11:49:52.000000000 +0200 +++ new/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java 2017-04-28 11:49:52.000000000 +0200 @@ -30,7 +30,7 @@ * jdk.internal.vm.ci/jdk.vm.ci.runtime * jdk.internal.vm.ci/jdk.vm.ci.common * java.base/jdk.internal.misc - * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI jdk.vm.ci.runtime.test.TestResolvedJavaType + * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -Djvmci.Compiler=null jdk.vm.ci.runtime.test.TestResolvedJavaType */ package jdk.vm.ci.runtime.test; --- old/test/compiler/jvmci/meta/StableFieldTest.java 2017-04-28 11:49:52.000000000 +0200 +++ new/test/compiler/jvmci/meta/StableFieldTest.java 2017-04-28 11:49:52.000000000 +0200 @@ -34,7 +34,7 @@ * * @compile StableFieldTest.java * @run driver ClassFileInstaller compiler.jvmci.meta.StableFieldTest - * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -Xbootclasspath/a:. compiler.jvmci.meta.StableFieldTest + * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -Djvmci.Compiler=null -Xbootclasspath/a:. compiler.jvmci.meta.StableFieldTest */ package compiler.jvmci.meta; --- /dev/null 2017-04-28 11:49:53.000000000 +0200 +++ new/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/internal/ReflectionAccessJDK.java 2017-04-28 11:49:53.000000000 +0200 @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.services.internal; + +import java.lang.reflect.Method; +import java.util.Set; + +import jdk.vm.ci.services.Services; + +/** + * Reflection based access to API introduced in JDK 9. This allows the API to be used in code that + * must be compiled (but not executed) on JDK 8. + */ +public final class ReflectionAccessJDK { + + /** + * {@code Class.getModule()}. + */ + private static final Method getModule; + + /** + * {@code java.lang.Module.addOpens(String, Module)}. + */ + private static final Method addOpens; + + /** + * {@code java.lang.Module.getPackages(Module, String, Module)}. + */ + private static final Method getPackages; + + /** + * {@code java.lang.Module.isOpen(String, Module)}. + */ + private static final Method isOpenTo; + + /** + * Opens all JVMCI packages to the module of a given class. + * + * @param other all JVMCI packages will be opened to the module of this class + */ + @SuppressWarnings("unchecked") + public static void openJVMCITo(Class other) { + try { + Object jvmci = getModule.invoke(Services.class); + Object otherModule = getModule.invoke(other); + if (jvmci != otherModule) { + Set packages = (Set) getPackages.invoke(jvmci); + for (String pkg : packages) { + boolean opened = (Boolean) isOpenTo.invoke(jvmci, pkg, otherModule); + if (!opened) { + addOpens.invoke(jvmci, pkg, otherModule); + } + } + } + } catch (Exception e) { + throw new InternalError(e); + } + } + + static { + try { + getModule = Class.class.getMethod("getModule"); + Class moduleClass = getModule.getReturnType(); + getPackages = moduleClass.getMethod("getPackages"); + isOpenTo = moduleClass.getMethod("isOpen", String.class, moduleClass); + addOpens = moduleClass.getDeclaredMethod("addOpens", String.class, moduleClass); + } catch (NoSuchMethodException | SecurityException e) { + throw new InternalError(e); + } + } +} --- /dev/null 2017-04-28 11:49:54.000000000 +0200 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/JDK9Method.java 2017-04-28 11:49:54.000000000 +0200 @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.graalvm.compiler.serviceprovider; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + +/** + * Reflection based access to API introduced by JDK 9. This allows the API to be used in code that + * must be compiled on a JDK prior to 9. + */ +public final class JDK9Method { + + 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(); + + public JDK9Method(Class declaringClass, String name, Class... parameterTypes) { + try { + this.method = declaringClass.getMethod(name, parameterTypes); + } catch (Exception e) { + throw new InternalError(e); + } + } + + /** + * Determines if the Java runtime is version 8 or earlier. + */ + public static final boolean Java8OrEarlier = JAVA_SPECIFICATION_VERSION <= 8; + + public final Method method; + + public Class getReturnType() { + return method.getReturnType(); + } + + /** + * {@code Class.getModule()}. + */ + public static final JDK9Method getModule; + + /** + * {@code java.lang.Module.getPackages()}. + */ + public static final JDK9Method getPackages; + + /** + * {@code java.lang.Module.getResourceAsStream(String)}. + */ + public static final JDK9Method getResourceAsStream; + + /** + * {@code java.lang.Module.addOpens(String, Module)}. + */ + public static final JDK9Method addOpens; + + /** + * {@code java.lang.Module.isOpen(String, Module)}. + */ + public static final JDK9Method isOpenTo; + + /** + * Invokes the static Module API method represented by this object. + */ + @SuppressWarnings("unchecked") + public T invokeStatic(Object... args) { + checkAvailability(); + assert Modifier.isStatic(method.getModifiers()); + try { + return (T) method.invoke(null, args); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + throw new InternalError(e); + } + } + + /** + * Invokes the non-static Module API method represented by this object. + */ + @SuppressWarnings("unchecked") + public T invoke(Object receiver, Object... args) { + checkAvailability(); + assert !Modifier.isStatic(method.getModifiers()); + try { + return (T) method.invoke(receiver, args); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + throw new InternalError(e); + } + } + + private void checkAvailability() throws InternalError { + if (method == null) { + throw new InternalError("Cannot use Module API on JDK " + JAVA_SPECIFICATION_VERSION); + } + } + + static { + if (JAVA_SPECIFICATION_VERSION >= 9) { + getModule = new JDK9Method(Class.class, "getModule"); + Class moduleClass = getModule.getReturnType(); + getPackages = new JDK9Method(moduleClass, "getPackages"); + addOpens = new JDK9Method(moduleClass, "addOpens", String.class, moduleClass); + getResourceAsStream = new JDK9Method(moduleClass, "getResourceAsStream", String.class); + isOpenTo = new JDK9Method(moduleClass, "isOpen", String.class, moduleClass); + } else { + JDK9Method unavailable = new JDK9Method(); + getModule = unavailable; + getPackages = unavailable; + addOpens = unavailable; + getResourceAsStream = unavailable; + isOpenTo = unavailable; + } + } + + private JDK9Method() { + method = null; + } +}