diff --git a/compiler/src/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/util/ModuleAPI.java b/compiler/src/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/util/ModuleAPI.java deleted file mode 100644 index 2c38dfdeba04..000000000000 --- a/compiler/src/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/util/ModuleAPI.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * 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.core.common.util; - -import static org.graalvm.compiler.serviceprovider.JDK9Method.JAVA_SPECIFICATION_VERSION; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; - -import org.graalvm.compiler.debug.GraalError; - -/** - * Reflection based access to the Module API introduced by JDK 9. This allows the API to be used in - * code that must be compiled on a JDK prior to 9. Use of this class must be guarded by a test for - * JDK 9 or later. For example: - * - *
- * if (Util.JAVA_SPECIFICATION_VERSION >= 9) {
- *     // Use of ModuleAPI
- * }
- * 
- */ -public final class ModuleAPI { - - public ModuleAPI(Class declaringClass, String name, Class... parameterTypes) { - try { - this.method = declaringClass.getMethod(name, parameterTypes); - } catch (Exception e) { - throw new GraalError(e); - } - } - - public final Method method; - - public Class getReturnType() { - return method.getReturnType(); - } - - /** - * {@code Class.getModule()}. - */ - public static final ModuleAPI getModule; - - /** - * {@code java.lang.Module.getResourceAsStream(String)}. - */ - public static final ModuleAPI getResourceAsStream; - - /** - * {@code java.lang.Module.isExported(String, Module)}. - */ - public static final ModuleAPI isExportedTo; - - /** - * 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 GraalError(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 GraalError(e); - } - } - - private void checkAvailability() throws GraalError { - if (method == null) { - throw new GraalError("Cannot use Module API on JDK " + JAVA_SPECIFICATION_VERSION); - } - } - - static { - if (JAVA_SPECIFICATION_VERSION >= 9) { - getModule = new ModuleAPI(Class.class, "getModule"); - Class moduleClass = getModule.getReturnType(); - getResourceAsStream = new ModuleAPI(moduleClass, "getResourceAsStream", String.class); - isExportedTo = new ModuleAPI(moduleClass, "isExported", String.class, moduleClass); - } else { - ModuleAPI unavailable = new ModuleAPI(); - getModule = unavailable; - getResourceAsStream = unavailable; - isExportedTo = unavailable; - } - } - - private ModuleAPI() { - method = null; - } -} diff --git a/compiler/src/org.graalvm.compiler.hotspot.jdk9/src/org/graalvm/compiler/hotspot/IsGraalPredicate.java b/compiler/src/org.graalvm.compiler.hotspot.jdk9/src/org/graalvm/compiler/hotspot/IsGraalPredicate.java new file mode 100644 index 000000000000..27d1051a264c --- /dev/null +++ b/compiler/src/org.graalvm.compiler.hotspot.jdk9/src/org/graalvm/compiler/hotspot/IsGraalPredicate.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2018, 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.hotspot; + +import jdk.vm.ci.hotspot.HotSpotJVMCICompilerFactory; + +/** + * Determines if a given class is a JVMCI or Graal class for the purpose of + * {@link HotSpotGraalCompilerFactory.Options#CompileGraalWithC1Only}. + */ +public class IsGraalPredicate { + /** + * Module containing {@link HotSpotJVMCICompilerFactory}. + */ + private final Module jvmciModule; + + /** + * Module containing {@link HotSpotGraalCompilerFactory}. + */ + private final Module graalModule; + + /** + * Module containing the {@linkplain CompilerConfigurationFactory#selectFactory selected} + * configuration. + */ + private Module compilerConfigurationModule; + + public IsGraalPredicate() { + jvmciModule = HotSpotJVMCICompilerFactory.class.getModule(); + graalModule = HotSpotGraalCompilerFactory.class.getModule(); + } + + void onCompilerConfigurationFactorySelection(CompilerConfigurationFactory factory) { + compilerConfigurationModule = factory.getClass().getModule(); + } + + boolean apply(Class declaringClass) { + Module module = declaringClass.getModule(); + return jvmciModule == module || graalModule == module || compilerConfigurationModule == module; + } +} diff --git a/compiler/src/org.graalvm.compiler.hotspot.jdk9/src/org/graalvm/compiler/hotspot/meta/HotSpotTrustedModules.java b/compiler/src/org.graalvm.compiler.hotspot.jdk9/src/org/graalvm/compiler/hotspot/meta/IntrinsificationPredicate.java similarity index 71% rename from compiler/src/org.graalvm.compiler.hotspot.jdk9/src/org/graalvm/compiler/hotspot/meta/HotSpotTrustedModules.java rename to compiler/src/org.graalvm.compiler.hotspot.jdk9/src/org/graalvm/compiler/hotspot/meta/IntrinsificationPredicate.java index 59e533b712c4..3a9dc6250134 100644 --- a/compiler/src/org.graalvm.compiler.hotspot.jdk9/src/org/graalvm/compiler/hotspot/meta/HotSpotTrustedModules.java +++ b/compiler/src/org.graalvm.compiler.hotspot.jdk9/src/org/graalvm/compiler/hotspot/meta/IntrinsificationPredicate.java @@ -28,28 +28,39 @@ import org.graalvm.compiler.phases.tiers.CompilerConfiguration; /** - * Builds the result for {@link HotSpotInvocationPlugins#initTrustedModules(CompilerConfiguration)}. + * Determines if methods in a given class can be intrinsified. * - * This version of the class must be used on JDK 9 or later. + * Only classes loaded from the module defining the compiler configuration or any of its transitive + * dependencies can be intrinsified. * - * @see "https://docs.oracle.com/javase/9/docs/specs/jar/jar.html#Multi-release" + * This version of the class must be used on JDK 9 or later. */ -public final class HotSpotTrustedModules { - static EconomicSet build(CompilerConfiguration compilerConfiguration) { - EconomicSet res = EconomicSet.create(); +public final class IntrinsificationPredicate { + /** + * Set of modules composed of the module defining the compiler configuration and its transitive + * dependencies. + */ + private final EconomicSet trustedModules; + + IntrinsificationPredicate(CompilerConfiguration compilerConfiguration) { + trustedModules = EconomicSet.create(); Module compilerConfigurationModule = compilerConfiguration.getClass().getModule(); if (compilerConfigurationModule.getDescriptor().isAutomatic()) { throw new IllegalArgumentException(String.format("The module '%s' defining the Graal compiler configuration class '%s' must not be an automatic module", compilerConfigurationModule.getName(), compilerConfiguration.getClass().getName())); } - res.add(compilerConfigurationModule); + trustedModules.add(compilerConfigurationModule); for (Requires require : compilerConfigurationModule.getDescriptor().requires()) { for (Module module : compilerConfigurationModule.getLayer().modules()) { if (module.getName().equals(require.name())) { - res.add(module); + trustedModules.add(module); } } } - return res; + } + + public boolean apply(Class declaringClass) { + Module module = declaringClass.getModule(); + return trustedModules.contains(module); } } diff --git a/compiler/src/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java b/compiler/src/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java index 93a141924f8d..f699e4b5c932 100644 --- a/compiler/src/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java +++ b/compiler/src/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java @@ -43,7 +43,7 @@ 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.serviceprovider.JDK9Method; +import org.graalvm.compiler.serviceprovider.GraalServices; import org.graalvm.compiler.test.GraalTest; import org.junit.Test; @@ -542,11 +542,11 @@ private static Collection add(Collection c, String... elements) } private static boolean isJDK9OrHigher() { - return JDK9Method.JAVA_SPECIFICATION_VERSION >= 9; + return GraalServices.JAVA_SPECIFICATION_VERSION >= 9; } private static boolean isJDK10OrHigher() { - return JDK9Method.JAVA_SPECIFICATION_VERSION >= 10; + return GraalServices.JAVA_SPECIFICATION_VERSION >= 10; } private static String getHostArchitectureName() { diff --git a/compiler/src/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorld.java b/compiler/src/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorld.java index 484b95be3387..c301824a9f03 100644 --- a/compiler/src/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorld.java +++ b/compiler/src/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorld.java @@ -29,7 +29,7 @@ import static org.graalvm.compiler.core.test.ReflectionOptionDescriptors.extractEntries; import static org.graalvm.compiler.debug.MemUseTrackerKey.getCurrentThreadAllocatedBytes; import static org.graalvm.compiler.hotspot.test.CompileTheWorld.Options.DESCRIPTORS; -import static org.graalvm.compiler.serviceprovider.JDK9Method.Java8OrEarlier; +import static org.graalvm.compiler.serviceprovider.GraalServices.Java8OrEarlier; import java.io.Closeable; import java.io.File; @@ -88,7 +88,7 @@ import org.graalvm.compiler.options.OptionKey; import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.options.OptionsParser; -import org.graalvm.compiler.serviceprovider.JDK9Method; +import org.graalvm.compiler.serviceprovider.GraalServices; import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider; import jdk.vm.ci.hotspot.HotSpotCompilationRequest; @@ -109,8 +109,8 @@ public final class CompileTheWorld { /** * Magic token to denote that JDK classes are to be compiled. If - * {@link JDK9Method#Java8OrEarlier}, then the classes in {@code rt.jar} are compiled. Otherwise - * the classes in the Java runtime image are compiled. + * {@link GraalServices#Java8OrEarlier}, then the classes in {@code rt.jar} are compiled. + * Otherwise the classes in the Java runtime image are compiled. */ public static final String SUN_BOOT_CLASS_PATH = "sun.boot.class.path"; diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompilerFactory.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompilerFactory.java index b5c9ff861fcc..7138ae3224f3 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompilerFactory.java +++ b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompilerFactory.java @@ -36,7 +36,6 @@ import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.options.OptionsParser; import org.graalvm.compiler.phases.tiers.CompilerConfiguration; -import org.graalvm.compiler.serviceprovider.JDK9Method; import jdk.vm.ci.common.InitTimer; import jdk.vm.ci.hotspot.HotSpotJVMCICompilerFactory; @@ -49,21 +48,7 @@ public final class HotSpotGraalCompilerFactory extends HotSpotJVMCICompilerFacto private static MethodFilter[] graalCompileOnlyFilter; private static boolean compileGraalWithC1Only; - /** - * Module containing {@link HotSpotJVMCICompilerFactory}. - */ - private Object jvmciModule; - - /** - * Module containing {@link HotSpotGraalCompilerFactory}. - */ - private Object graalModule; - - /** - * Module containing the {@linkplain CompilerConfigurationFactory#selectFactory selected} - * configuration. - */ - private Object compilerConfigurationModule; + private IsGraalPredicate isGraalPredicate; private final HotSpotGraalJVMCIServiceLocator locator; @@ -87,10 +72,7 @@ public void onSelection() { assert options == null : "cannot select " + getClass() + " service more than once"; options = HotSpotGraalOptionValues.HOTSPOT_OPTIONS; initializeGraalCompilePolicyFields(options); - if (!JDK9Method.Java8OrEarlier) { - jvmciModule = JDK9Method.getModule(HotSpotJVMCICompilerFactory.class); - graalModule = JDK9Method.getModule(HotSpotGraalCompilerFactory.class); - } + isGraalPredicate = compileGraalWithC1Only ? new IsGraalPredicate() : null; /* * Exercise this code path early to encourage loading now. This doesn't solve problem of * deadlock during class loading but seems to eliminate it in practice. @@ -134,8 +116,8 @@ static class Options { @Override public HotSpotGraalCompiler createCompiler(JVMCIRuntime runtime) { CompilerConfigurationFactory factory = CompilerConfigurationFactory.selectFactory(null, options); - if (!JDK9Method.Java8OrEarlier) { - compilerConfigurationModule = JDK9Method.getModule(factory.getClass()); + if (isGraalPredicate != null) { + isGraalPredicate.onCompilerConfigurationFactorySelection(factory); } HotSpotGraalCompiler compiler = createCompiler(runtime, options, factory); // Only the HotSpotGraalRuntime associated with the compiler created via @@ -187,54 +169,11 @@ public CompilationLevel adjustCompilationLevel(Class declaringClass, String n assert HotSpotGraalCompilerFactory.class.getName().equals("org.graalvm.compiler.hotspot.HotSpotGraalCompilerFactory"); } - static final ClassLoader JVMCI_LOADER = HotSpotGraalCompilerFactory.class.getClassLoader(); - - /* - * This method is static so it can be exercised during initialization. - */ private CompilationLevel adjustCompilationLevelInternal(Class declaringClass, String name, String signature, CompilationLevel level) { if (compileGraalWithC1Only) { if (level.ordinal() > CompilationLevel.Simple.ordinal()) { - if (JDK9Method.Java8OrEarlier) { - if (JVMCI_LOADER != null) { - // When running with +UseJVMCIClassLoader all classes in - // the JVMCI loader should be compiled with C1. - try { - if (declaringClass.getClassLoader() == JVMCI_LOADER) { - return CompilationLevel.Simple; - } - } catch (SecurityException e) { - // This is definitely not a JVMCI or Graal class - } - } else { - // JVMCI and Graal are on the bootclasspath so match based on the package. - String declaringClassName = declaringClass.getName(); - if (declaringClassName.startsWith("jdk.vm.ci")) { - return CompilationLevel.Simple; - } - if (declaringClassName.startsWith("org.graalvm.") && - (declaringClassName.startsWith("org.graalvm.compiler.") || - declaringClassName.startsWith("org.graalvm.collections.") || - declaringClassName.startsWith("org.graalvm.compiler.word.") || - declaringClassName.startsWith("org.graalvm.graphio."))) { - return CompilationLevel.Simple; - } - if (declaringClassName.startsWith("com.oracle.graal") && - (declaringClassName.startsWith("com.oracle.graal.enterprise") || - declaringClassName.startsWith("com.oracle.graal.vector") || - declaringClassName.startsWith("com.oracle.graal.asm"))) { - return CompilationLevel.Simple; - } - } - } else { - try { - Object module = JDK9Method.getModule(declaringClass); - if (jvmciModule == module || graalModule == module || compilerConfigurationModule == module) { - return CompilationLevel.Simple; - } - } catch (Throwable e) { - throw new InternalError(e); - } + if (isGraalPredicate.apply(declaringClass)) { + return CompilationLevel.Simple; } } } diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/IsGraalPredicate.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/IsGraalPredicate.java new file mode 100644 index 000000000000..04333a42e3ce --- /dev/null +++ b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/IsGraalPredicate.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2018, 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.hotspot; + +/** + * Determines if a given class is a JVMCI or Graal class for the purpose of + * {@link HotSpotGraalCompilerFactory.Options#CompileGraalWithC1Only}. + */ +public final class IsGraalPredicate { + + private final ClassLoader jvmciLoader = getClass().getClassLoader(); + + @SuppressWarnings("unused") + void onCompilerConfigurationFactorySelection(CompilerConfigurationFactory factory) { + } + + boolean apply(Class declaringClass) { + if (jvmciLoader != null) { + // When running with +UseJVMCIClassLoader all classes loaded + // by the JVMCI loader are considered to be Graal classes. + try { + if (declaringClass.getClassLoader() == jvmciLoader) { + return true; + } + } catch (SecurityException e) { + // This is definitely not a JVMCI or Graal class + } + } else { + // JVMCI and Graal are on the bootclasspath so match based on the package. + String declaringClassName = declaringClass.getName(); + if (declaringClassName.startsWith("jdk.vm.ci")) { + return true; + } + if (declaringClassName.startsWith("org.graalvm.") && + (declaringClassName.startsWith("org.graalvm.compiler.") || + declaringClassName.startsWith("org.graalvm.collections.") || + declaringClassName.startsWith("org.graalvm.compiler.word.") || + declaringClassName.startsWith("org.graalvm.graphio."))) { + return true; + } + if (declaringClassName.startsWith("com.oracle.graal") && + (declaringClassName.startsWith("com.oracle.graal.enterprise") || + declaringClassName.startsWith("com.oracle.graal.vector") || + declaringClassName.startsWith("com.oracle.graal.asm"))) { + return true; + } + } + return false; + } +} diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java index cdf8b8f8e5e9..7fc9435c8565 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java +++ b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java @@ -26,7 +26,7 @@ import static org.graalvm.compiler.hotspot.meta.HotSpotAOTProfilingPlugin.Options.TieredAOT; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.JAVA_THREAD_THREAD_OBJECT_LOCATION; import static org.graalvm.compiler.java.BytecodeParserOptions.InlineDuringParsing; -import static org.graalvm.compiler.serviceprovider.JDK9Method.Java8OrEarlier; +import static org.graalvm.compiler.serviceprovider.GraalServices.Java8OrEarlier; import java.lang.invoke.ConstantCallSite; import java.lang.invoke.MutableCallSite; @@ -100,7 +100,6 @@ import org.graalvm.compiler.replacements.ReplacementsImpl; import org.graalvm.compiler.replacements.StandardGraphBuilderPlugins; import org.graalvm.compiler.serviceprovider.GraalServices; -import org.graalvm.compiler.serviceprovider.JDK9Method; import org.graalvm.compiler.word.WordOperationPlugin; import org.graalvm.compiler.word.WordTypes; import org.graalvm.word.LocationIdentity; @@ -440,7 +439,7 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Rec public static final String constantPoolClass; static { - if (JDK9Method.Java8OrEarlier) { + if (Java8OrEarlier) { cbcEncryptName = "encrypt"; cbcDecryptName = "decrypt"; aesEncryptName = "encryptBlock"; diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotInvocationPlugins.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotInvocationPlugins.java index fc3e9fa93fc2..36e04c5e9c45 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotInvocationPlugins.java +++ b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotInvocationPlugins.java @@ -22,13 +22,9 @@ */ package org.graalvm.compiler.hotspot.meta; -import static org.graalvm.compiler.serviceprovider.JDK9Method.Java8OrEarlier; - import java.lang.reflect.Type; -import org.graalvm.collections.EconomicSet; import org.graalvm.compiler.core.common.GraalOptions; -import org.graalvm.compiler.debug.GraalError; import org.graalvm.compiler.graph.Node; import org.graalvm.compiler.graph.iterators.NodeIterable; import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; @@ -41,7 +37,6 @@ import org.graalvm.compiler.nodes.type.StampTool; import org.graalvm.compiler.phases.tiers.CompilerConfiguration; import org.graalvm.compiler.replacements.nodes.MacroNode; -import org.graalvm.compiler.serviceprovider.JDK9Method; import jdk.vm.ci.hotspot.HotSpotResolvedJavaType; import jdk.vm.ci.meta.JavaKind; @@ -52,18 +47,11 @@ */ final class HotSpotInvocationPlugins extends InvocationPlugins { private final GraalHotSpotVMConfig config; - private final EconomicSet trustedModules; - private final ClassLoader extLoader; + private final IntrinsificationPredicate intrinsificationPredicate; HotSpotInvocationPlugins(GraalHotSpotVMConfig config, CompilerConfiguration compilerConfiguration) { this.config = config; - if (Java8OrEarlier) { - extLoader = getExtLoader(); - trustedModules = null; - } else { - extLoader = null; - trustedModules = initTrustedModules(compilerConfiguration); - } + intrinsificationPredicate = new IntrinsificationPredicate(compilerConfiguration); } @Override @@ -112,50 +100,12 @@ private static boolean isClass(ConstantNode node) { return type != null && "Ljava/lang/Class;".equals(type.getName()); } - /** - * {@inheritDoc} - * - * On JDK 8, only classes loaded by the boot, JVMCI or extension class loaders are trusted. - * - * On JDK 9 and later, only classes in the {@link CompilerConfiguration} defining module or any - * of its module dependencies are trusted. - */ @Override public boolean canBeIntrinsified(ResolvedJavaType declaringClass) { if (declaringClass instanceof HotSpotResolvedJavaType) { - Class javaClass = ((HotSpotResolvedJavaType) declaringClass).mirror(); - if (Java8OrEarlier) { - ClassLoader cl = javaClass.getClassLoader(); - return cl == null || cl == getClass().getClassLoader() || cl == extLoader; - } else { - Object module = JDK9Method.getModule(javaClass); - return trustedModules.contains(module); - } + HotSpotResolvedJavaType type = (HotSpotResolvedJavaType) declaringClass; + return intrinsificationPredicate.apply(type.mirror()); } return false; } - - private static ClassLoader getExtLoader() { - try { - Object launcher = Class.forName("sun.misc.Launcher").getMethod("getLauncher").invoke(null); - ClassLoader appLoader = (ClassLoader) launcher.getClass().getMethod("getClassLoader").invoke(launcher); - ClassLoader extLoader = appLoader.getParent(); - assert extLoader.getClass().getName().equals("sun.misc.Launcher$ExtClassLoader") : extLoader; - return extLoader; - } catch (Exception e) { - throw new GraalError(e); - } - } - - /** - * Gets the set of modules trusted by Graal in terms of applying intrinsics. A method declared - * in class C can be intrinsified if C is declared by one of the modules returned by this - * method. The set of trusted modules is module declaring the - * {@code compilerConfiguration.getClass()} and its transitive dependencies. - * - * @param compilerConfiguration the object from which the set of trusted modules is computed - */ - static EconomicSet initTrustedModules(CompilerConfiguration compilerConfiguration) { - return HotSpotTrustedModules.build(compilerConfiguration); - } } diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotTrustedModules.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotTrustedModules.java deleted file mode 100644 index 5eb9c6fcf090..000000000000 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotTrustedModules.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2018, 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.hotspot.meta; - -import static org.graalvm.compiler.serviceprovider.JDK9Method.JAVA_SPECIFICATION_VERSION; - -import org.graalvm.collections.EconomicSet; -import org.graalvm.compiler.phases.tiers.CompilerConfiguration; - -/** - * Builds the result for {@link HotSpotInvocationPlugins#initTrustedModules(CompilerConfiguration)}. - * - * This version of the class must be used on JDK 8. - * - * @see "https://docs.oracle.com/javase/9/docs/specs/jar/jar.html#Multi-release" - */ -public final class HotSpotTrustedModules { - - @SuppressWarnings("unused") - static EconomicSet build(CompilerConfiguration compilerConfiguration) { - throw new InternalError("Cannot use API introduced in Java 9 or later on Java " + JAVA_SPECIFICATION_VERSION); - } -} diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotUnsafeSubstitutions.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotUnsafeSubstitutions.java index d2d709e7436c..e86f76711a20 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotUnsafeSubstitutions.java +++ b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotUnsafeSubstitutions.java @@ -22,7 +22,7 @@ */ package org.graalvm.compiler.hotspot.meta; -import static org.graalvm.compiler.serviceprovider.JDK9Method.Java8OrEarlier; +import static org.graalvm.compiler.serviceprovider.GraalServices.Java8OrEarlier; import org.graalvm.compiler.api.replacements.ClassSubstitution; import org.graalvm.compiler.api.replacements.MethodSubstitution; diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/IntrinsificationPredicate.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/IntrinsificationPredicate.java new file mode 100644 index 000000000000..3fb130ab2e45 --- /dev/null +++ b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/IntrinsificationPredicate.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2018, 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.hotspot.meta; + +import org.graalvm.collections.EconomicSet; +import org.graalvm.compiler.debug.GraalError; +import org.graalvm.compiler.phases.tiers.CompilerConfiguration; + +/** + * Determines if methods in a given class can be intrinsified. + * + * Only classes loaded by the extension class loader or any loader in loader hierarchy spanning the + * JVMCI loader to the boot loader can be intrinsified. + * + * This version of the class must be used on JDK 8. + */ +public final class IntrinsificationPredicate { + private final EconomicSet trustedLoaders; + + public IntrinsificationPredicate(CompilerConfiguration compilerConfiguration) { + trustedLoaders = EconomicSet.create(); + trustedLoaders.add(getExtLoader()); + ClassLoader cl = compilerConfiguration.getClass().getClassLoader(); + while (cl != null) { + trustedLoaders.add(cl); + cl = cl.getParent(); + } + } + + private static ClassLoader getExtLoader() { + try { + Object launcher = Class.forName("sun.misc.Launcher").getMethod("getLauncher").invoke(null); + ClassLoader appLoader = (ClassLoader) launcher.getClass().getMethod("getClassLoader").invoke(launcher); + ClassLoader extLoader = appLoader.getParent(); + assert extLoader.getClass().getName().equals("sun.misc.Launcher$ExtClassLoader") : extLoader; + return extLoader; + } catch (Exception e) { + throw new GraalError(e); + } + } + + public boolean apply(Class declaringClass) { + ClassLoader cl = declaringClass.getClassLoader(); + return cl == null || trustedLoaders.contains(cl); + } +} diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/SHA2Substitutions.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/SHA2Substitutions.java index 43eedc6669b9..9925542e9d65 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/SHA2Substitutions.java +++ b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/SHA2Substitutions.java @@ -23,7 +23,7 @@ package org.graalvm.compiler.hotspot.replacements; import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayBaseOffset; -import static org.graalvm.compiler.serviceprovider.JDK9Method.Java8OrEarlier; +import static org.graalvm.compiler.serviceprovider.GraalServices.Java8OrEarlier; import org.graalvm.compiler.api.replacements.ClassSubstitution; import org.graalvm.compiler.api.replacements.MethodSubstitution; diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/SHA5Substitutions.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/SHA5Substitutions.java index 95ecd5b55d7d..907cb762a41e 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/SHA5Substitutions.java +++ b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/SHA5Substitutions.java @@ -23,7 +23,7 @@ package org.graalvm.compiler.hotspot.replacements; import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayBaseOffset; -import static org.graalvm.compiler.serviceprovider.JDK9Method.Java8OrEarlier; +import static org.graalvm.compiler.serviceprovider.GraalServices.Java8OrEarlier; import org.graalvm.compiler.api.replacements.ClassSubstitution; import org.graalvm.compiler.api.replacements.MethodSubstitution; diff --git a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/SHASubstitutions.java b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/SHASubstitutions.java index 18d101fb16c8..ad734a397a83 100644 --- a/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/SHASubstitutions.java +++ b/compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/SHASubstitutions.java @@ -23,7 +23,7 @@ package org.graalvm.compiler.hotspot.replacements; import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayBaseOffset; -import static org.graalvm.compiler.serviceprovider.JDK9Method.Java8OrEarlier; +import static org.graalvm.compiler.serviceprovider.GraalServices.Java8OrEarlier; import org.graalvm.compiler.api.replacements.ClassSubstitution; import org.graalvm.compiler.api.replacements.MethodSubstitution; diff --git a/compiler/src/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/verify/VerifyCallerSensitiveMethods.java b/compiler/src/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/verify/VerifyCallerSensitiveMethods.java index 35f39ffbd109..25139cc32e12 100644 --- a/compiler/src/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/verify/VerifyCallerSensitiveMethods.java +++ b/compiler/src/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/verify/VerifyCallerSensitiveMethods.java @@ -22,7 +22,7 @@ */ package org.graalvm.compiler.phases.verify; -import static org.graalvm.compiler.serviceprovider.JDK9Method.Java8OrEarlier; +import static org.graalvm.compiler.serviceprovider.GraalServices.Java8OrEarlier; import java.lang.annotation.Annotation; diff --git a/compiler/src/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinter.java b/compiler/src/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinter.java index 5540cb4784c5..0b8f2cdec25e 100644 --- a/compiler/src/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinter.java +++ b/compiler/src/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinter.java @@ -37,15 +37,13 @@ import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.util.JavaConstantFormatter; import org.graalvm.compiler.phases.schedule.SchedulePhase; -import org.graalvm.compiler.serviceprovider.JDK9Method; +import org.graalvm.compiler.serviceprovider.GraalServices; import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.JavaType; import jdk.vm.ci.meta.MetaUtil; import jdk.vm.ci.meta.ResolvedJavaMethod; -import jdk.vm.ci.runtime.JVMCI; -import jdk.vm.ci.services.Services; interface GraphPrinter extends Closeable, JavaConstantFormatter { @@ -71,16 +69,6 @@ interface GraphPrinter extends Closeable, JavaConstantFormatter { @Override void close(); - /** - * A JVMCI package dynamically exported to trusted modules. - */ - String JVMCI_RUNTIME_PACKAGE = JVMCI.class.getPackage().getName(); - - /** - * {@code jdk.vm.ci} module. - */ - Object JVMCI_MODULE = JDK9Method.JAVA_SPECIFICATION_VERSION < 9 ? null : JDK9Method.getModule(Services.class); - /** * Classes whose {@link #toString()} method does not run any untrusted code. */ @@ -105,17 +93,8 @@ static boolean isToStringTrusted(Class c) { if (TRUSTED_CLASSES.contains(c)) { return true; } - if (JDK9Method.JAVA_SPECIFICATION_VERSION < 9) { - if (c.getClassLoader() == Services.class.getClassLoader()) { - // Loaded by the JVMCI class loader - return true; - } - } else { - Object module = JDK9Method.getModule(c); - if (JVMCI_MODULE == module || JDK9Method.isOpenTo(JVMCI_MODULE, JVMCI_RUNTIME_PACKAGE, module)) { - // Can access non-statically-exported package in JVMCI - return true; - } + if (GraalServices.isToStringTrusted(c)) { + return true; } if (c.getClassLoader() == GraphPrinter.class.getClassLoader()) { return true; diff --git a/compiler/src/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64GraphBuilderPlugins.java b/compiler/src/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64GraphBuilderPlugins.java index c2cb77fbee90..5f2e43cd3eff 100644 --- a/compiler/src/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64GraphBuilderPlugins.java +++ b/compiler/src/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64GraphBuilderPlugins.java @@ -29,8 +29,8 @@ import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.LOG10; import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.SIN; import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.TAN; -import static org.graalvm.compiler.serviceprovider.JDK9Method.JAVA_SPECIFICATION_VERSION; -import static org.graalvm.compiler.serviceprovider.JDK9Method.Java8OrEarlier; +import static org.graalvm.compiler.serviceprovider.GraalServices.JAVA_SPECIFICATION_VERSION; +import static org.graalvm.compiler.serviceprovider.GraalServices.Java8OrEarlier; import java.util.Arrays; diff --git a/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java b/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java index 8793b1eba4d0..af1ac1ea8230 100644 --- a/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java +++ b/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java @@ -31,7 +31,7 @@ import static jdk.vm.ci.code.MemoryBarriers.STORE_LOAD; import static jdk.vm.ci.code.MemoryBarriers.STORE_STORE; import static org.graalvm.compiler.nodes.NamedLocationIdentity.OFF_HEAP_LOCATION; -import static org.graalvm.compiler.serviceprovider.JDK9Method.Java8OrEarlier; +import static org.graalvm.compiler.serviceprovider.GraalServices.Java8OrEarlier; import java.lang.reflect.Array; import java.lang.reflect.Field; diff --git a/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/classfile/ClassfileBytecodeProvider.java b/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/classfile/ClassfileBytecodeProvider.java index f3d9ea9faeda..52cdd1e75f9d 100644 --- a/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/classfile/ClassfileBytecodeProvider.java +++ b/compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/classfile/ClassfileBytecodeProvider.java @@ -22,9 +22,6 @@ */ package org.graalvm.compiler.replacements.classfile; -import static org.graalvm.compiler.serviceprovider.JDK9Method.getModule; -import static org.graalvm.compiler.serviceprovider.JDK9Method.getResourceAsStream; - import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; @@ -34,7 +31,7 @@ import org.graalvm.compiler.api.replacements.SnippetReflectionProvider; import org.graalvm.compiler.bytecode.Bytecode; import org.graalvm.compiler.bytecode.BytecodeProvider; -import org.graalvm.compiler.serviceprovider.JDK9Method; +import org.graalvm.compiler.serviceprovider.GraalServices; import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.MetaAccessProvider; @@ -98,20 +95,6 @@ public boolean shouldRecordMethodDependencies() { return false; } - private static InputStream getClassfileAsStream(Class c) { - String classfilePath = c.getName().replace('.', '/') + ".class"; - if (JDK9Method.JAVA_SPECIFICATION_VERSION >= 9) { - Object module = getModule(c); - return getResourceAsStream(module, classfilePath); - } else { - ClassLoader cl = c.getClassLoader(); - if (cl == null) { - return ClassLoader.getSystemResourceAsStream(classfilePath); - } - return cl.getResourceAsStream(classfilePath); - } - } - /** * Gets a {@link Classfile} created by parsing the class file bytes for {@code c}. * @@ -123,7 +106,7 @@ private synchronized Classfile getClassfile(Class c) { if (classfile == null) { try { ResolvedJavaType type = metaAccess.lookupJavaType(c); - InputStream in = getClassfileAsStream(c); + InputStream in = GraalServices.getClassfileAsStream(c); if (in != null) { DataInputStream stream = new DataInputStream(in); classfile = new Classfile(type, stream, this); diff --git a/compiler/src/org.graalvm.compiler.serviceprovider.jdk9/src/org/graalvm/compiler/serviceprovider/GraalServices.java b/compiler/src/org.graalvm.compiler.serviceprovider.jdk9/src/org/graalvm/compiler/serviceprovider/GraalServices.java new file mode 100644 index 000000000000..3137199eac59 --- /dev/null +++ b/compiler/src/org.graalvm.compiler.serviceprovider.jdk9/src/org/graalvm/compiler/serviceprovider/GraalServices.java @@ -0,0 +1,181 @@ +/* + * 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.io.IOException; +import java.io.InputStream; +import java.util.Iterator; +import java.util.ServiceConfigurationError; +import java.util.ServiceLoader; + +import jdk.vm.ci.services.JVMCIPermission; +import jdk.vm.ci.services.Services; + +/** + * Interface to functionality that abstracts over which JDK version Graal is running on. + */ +public final class GraalServices { + + 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(); + + /** + * Determines if the Java runtime is version 8 or earlier. + */ + public static final boolean Java8OrEarlier = JAVA_SPECIFICATION_VERSION <= 8; + + private GraalServices() { + } + + /** + * Gets an {@link Iterable} of the providers available for a given service. + * + * @throws SecurityException if on JDK8 and a security manager is present and it denies + * {@link JVMCIPermission} + */ + public static Iterable load(Class service) { + assert !service.getName().startsWith("jdk.vm.ci") : "JVMCI services must be loaded via " + Services.class.getName(); + Iterable iterable = ServiceLoader.load(service); + return new Iterable<>() { + @Override + public Iterator iterator() { + Iterator iterator = iterable.iterator(); + return new Iterator<>() { + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public S next() { + S provider = iterator.next(); + // Allow Graal extensions to access JVMCI + openJVMCITo(provider.getClass()); + return provider; + } + + @Override + public void remove() { + iterator.remove(); + } + }; + } + }; + } + + /** + * 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 + */ + static void openJVMCITo(Class other) { + Module jvmciModule = JVMCI_MODULE; + Module otherModule = other.getModule(); + if (jvmciModule != otherModule) { + for (String pkg : jvmciModule.getPackages()) { + if (!jvmciModule.isOpen(pkg, otherModule)) { + jvmciModule.addOpens(pkg, otherModule); + } + } + } + } + + /** + * 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 + * @param required specifies if an {@link InternalError} should be thrown if no provider of + * {@code service} is available + * @return the requested provider if available else {@code null} + * @throws SecurityException if on JDK8 and a security manager is present and it denies + * {@link JVMCIPermission} + */ + public static S loadSingle(Class service, boolean required) { + assert !service.getName().startsWith("jdk.vm.ci") : "JVMCI services must be loaded via " + Services.class.getName(); + Iterable providers = load(service); + S singleProvider = null; + try { + for (Iterator it = providers.iterator(); it.hasNext();) { + singleProvider = it.next(); + if (it.hasNext()) { + 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) { + // If the service is required we will bail out below. + } + if (singleProvider == null) { + if (required) { + throw new InternalError(String.format("No provider for %s found", service.getName())); + } + } + return singleProvider; + } + + /** + * Gets the class file bytes for {@code c}. + */ + public static InputStream getClassfileAsStream(Class c) throws IOException { + String classfilePath = c.getName().replace('.', '/') + ".class"; + return c.getModule().getResourceAsStream(classfilePath); + } + + private static final Module JVMCI_MODULE = Services.class.getModule(); + + /** + * A JVMCI package dynamically exported to trusted modules. + */ + private static final String JVMCI_RUNTIME_PACKAGE = "jdk.vm.ci.runtime"; + static { + assert JVMCI_MODULE.getPackages().contains(JVMCI_RUNTIME_PACKAGE); + } + + /** + * Determines if invoking {@link Object#toString()} on an instance of {@code c} will only run + * trusted code. + */ + public static boolean isToStringTrusted(Class c) { + Module module = c.getModule(); + Module jvmciModule = JVMCI_MODULE; + assert jvmciModule.getPackages().contains("jdk.vm.ci.runtime"); + if (module == jvmciModule || jvmciModule.isOpen(JVMCI_RUNTIME_PACKAGE, module)) { + // Can access non-statically-exported package in JVMCI + return true; + } + return false; + } + +} diff --git a/compiler/src/org.graalvm.compiler.serviceprovider.jdk9/src/org/graalvm/compiler/serviceprovider/JDK9Method.java b/compiler/src/org.graalvm.compiler.serviceprovider.jdk9/src/org/graalvm/compiler/serviceprovider/JDK9Method.java deleted file mode 100644 index d9c45c553563..000000000000 --- a/compiler/src/org.graalvm.compiler.serviceprovider.jdk9/src/org/graalvm/compiler/serviceprovider/JDK9Method.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * 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.io.IOException; -import java.io.InputStream; -import java.util.Set; - -/** - * Access to API introduced by JDK 9. Use of any method in this class must ensure that the current - * runtime is JDK 9 or later. For example: - * - *
- * if (!JDK9Method.isJava8OrEarlier) {
- *     Object module = JDK9Method.getModule(c);
- *     ...
- * }
- * 
- * - * This version of the class must be used on JDK 9 or later. - * - * @see "https://docs.oracle.com/javase/9/docs/specs/jar/jar.html#Multi-release" - */ -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(); - - /** - * Determines if the Java runtime is version 8 or earlier. - */ - public static final boolean Java8OrEarlier = JAVA_SPECIFICATION_VERSION <= 8; - - /** - * Wrapper for {@link Class#getModule()}. - */ - public static Object getModule(Class clazz) { - return clazz.getModule(); - } - - /** - * Wrapper for {@link Module#getPackages()}. - */ - public static Set getPackages(Object module) { - return ((Module) module).getPackages(); - } - - /** - * Wrapper for {@link Module#getResourceAsStream(String)}. - */ - public static InputStream getResourceAsStream(Object module, String resource) throws IOException { - return ((Module) module).getResourceAsStream(resource); - } - - /** - * Wrapper for {@link Module#addOpens(String, Module)}. - */ - static void addOpens(Object thisModule, String packageName, Object otherModule) { - ((Module) thisModule).addOpens(packageName, (Module) otherModule); - } - - /** - * Wrapper for {@link Module#isOpen(String, Module)}. - */ - public static boolean isOpenTo(Object module1, String pkg, Object module2) { - return ((Module) module1).isOpen(pkg, (Module) module2); - } -} diff --git a/compiler/src/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/GraalServices.java b/compiler/src/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/GraalServices.java index 4ea7ee9ca058..175db9586332 100644 --- a/compiler/src/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/GraalServices.java +++ b/compiler/src/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/GraalServices.java @@ -22,48 +22,39 @@ */ package org.graalvm.compiler.serviceprovider; -import static org.graalvm.compiler.serviceprovider.JDK9Method.Java8OrEarlier; -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.io.IOException; +import java.io.InputStream; 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; /** - * 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. + * Interface to functionality that abstracts over which JDK version Graal is running on. */ public final class GraalServices { - private GraalServices() { + private static int getJavaSpecificationVersion() { + String value = System.getProperty("java.specification.version"); + if (value.startsWith("1.")) { + value = value.substring(2); + } + return Integer.parseInt(value); } /** - * 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 + * 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 void openJVMCITo(Class other) { - Object jvmci = getModule(Services.class); - Object otherModule = getModule(other); - if (jvmci != otherModule) { - Set packages = getPackages(jvmci); - for (String pkg : packages) { - boolean opened = isOpenTo(jvmci, pkg, otherModule); - if (!opened) { - JDK9Method.addOpens(jvmci, pkg, otherModule); - } - } - } + public static final int JAVA_SPECIFICATION_VERSION = getJavaSpecificationVersion(); + + /** + * Determines if the Java runtime is version 8 or earlier. + */ + public static final boolean Java8OrEarlier = JAVA_SPECIFICATION_VERSION <= 8; + + private GraalServices() { } /** @@ -74,52 +65,7 @@ public static void openJVMCITo(Class other) { */ 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 load8(service); - } - Iterable iterable = ServiceLoader.load(service); - return new Iterable() { - @Override - public Iterator iterator() { - Iterator iterator = iterable.iterator(); - return new Iterator() { - @Override - public boolean hasNext() { - return iterator.hasNext(); - } - - @Override - public S next() { - S provider = iterator.next(); - // Allow Graal extensions to access JVMCI - openJVMCITo(provider.getClass()); - return provider; - } - - @Override - public void remove() { - iterator.remove(); - } - }; - } - }; - } - - /** - * {@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); - } + return Services.load(service); } /** @@ -154,4 +100,32 @@ public static S loadSingle(Class service, boolean required) { } return singleProvider; } + + /** + * Gets the class file bytes for {@code c}. + */ + @SuppressWarnings("unused") + public static InputStream getClassfileAsStream(Class c) throws IOException { + String classfilePath = c.getName().replace('.', '/') + ".class"; + ClassLoader cl = c.getClassLoader(); + if (cl == null) { + return ClassLoader.getSystemResourceAsStream(classfilePath); + } + return cl.getResourceAsStream(classfilePath); + } + + private static final ClassLoader JVMCI_LOADER = GraalServices.class.getClassLoader(); + private static final ClassLoader JVMCI_PARENT_LOADER = JVMCI_LOADER == null ? null : JVMCI_LOADER.getParent(); + static { + assert JVMCI_PARENT_LOADER == null || JVMCI_PARENT_LOADER.getParent() == null; + } + + /** + * Determines if invoking {@link Object#toString()} on an instance of {@code c} will only run + * trusted code. + */ + public static boolean isToStringTrusted(Class c) { + ClassLoader cl = c.getClassLoader(); + return cl == null || cl == JVMCI_LOADER || cl == JVMCI_PARENT_LOADER; + } } diff --git a/compiler/src/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/JDK9Method.java b/compiler/src/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/JDK9Method.java deleted file mode 100644 index db133d40cac3..000000000000 --- a/compiler/src/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/JDK9Method.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * 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.io.InputStream; -import java.util.Set; - -/** - * Access to API introduced by JDK 9. Use of any method in this class must ensure that the current - * runtime is JDK 9 or later. For example: - * - *
- * if (!JDK9Method.isJava8OrEarlier) {
- *     Object module = JDK9Method.getModule(c);
- *     ...
- * }
- * 
- * - * This version of the class must be used on JDK 8. - * - * @see "https://docs.oracle.com/javase/9/docs/specs/jar/jar.html#Multi-release" - */ -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(); - - /** - * Determines if the Java runtime is version 8 or earlier. - */ - public static final boolean Java8OrEarlier = JAVA_SPECIFICATION_VERSION <= 8; - - private static Error unreachable() { - throw new InternalError("Cannot use API introduced in Java 9 or later on Java " + JAVA_SPECIFICATION_VERSION); - } - - /** - * Wrapper for {@code Class.getModule()}. - */ - @SuppressWarnings("unused") - public static Object getModule(Class clazz) { - throw unreachable(); - } - - /** - * Wrapper for {@code Module.getPackages()}. - */ - @SuppressWarnings("unused") - public static Set getPackages(Object module) { - throw unreachable(); - } - - /** - * Wrapper for {@code Module.getResourceAsStream(String)}. - */ - @SuppressWarnings("unused") - public static InputStream getResourceAsStream(Object module, String resource) { - throw unreachable(); - } - - /** - * Wrapper for {@code Module.addOpens(String, Module)}. - */ - @SuppressWarnings("unused") - static void addOpens(Object thisModule, String packageName, Object otherModule) { - throw unreachable(); - } - - /** - * Wrapper for {@code Module.isOpen(String, Module)}. - */ - @SuppressWarnings("unused") - public static boolean isOpenTo(Object module1, String pkg, Object module2) { - throw unreachable(); - } -} diff --git a/compiler/src/org.graalvm.compiler.truffle.runtime/src/org/graalvm/compiler/truffle/runtime/GraalTruffleRuntime.java b/compiler/src/org.graalvm.compiler.truffle.runtime/src/org/graalvm/compiler/truffle/runtime/GraalTruffleRuntime.java index 72b3e8b3fd35..81c0f6221178 100644 --- a/compiler/src/org.graalvm.compiler.truffle.runtime/src/org/graalvm/compiler/truffle/runtime/GraalTruffleRuntime.java +++ b/compiler/src/org.graalvm.compiler.truffle.runtime/src/org/graalvm/compiler/truffle/runtime/GraalTruffleRuntime.java @@ -25,7 +25,7 @@ import static java.util.Collections.singletonList; import static org.graalvm.compiler.debug.DebugContext.DEFAULT_LOG_STREAM; import static org.graalvm.compiler.debug.DebugContext.NO_GLOBAL_METRIC_VALUES; -import static org.graalvm.compiler.serviceprovider.JDK9Method.Java8OrEarlier; +import static org.graalvm.compiler.serviceprovider.GraalServices.Java8OrEarlier; import static org.graalvm.compiler.truffle.common.TruffleCompilerOptions.TruffleCompilationExceptionsAreThrown; import static org.graalvm.compiler.truffle.common.TruffleCompilerOptions.TruffleCompileOnly; import static org.graalvm.compiler.truffle.common.TruffleCompilerOptions.TruffleCompilerThreads; diff --git a/compiler/src/org.graalvm.compiler.truffle.test/src/org/graalvm/compiler/truffle/test/LazyInitializationTest.java b/compiler/src/org.graalvm.compiler.truffle.test/src/org/graalvm/compiler/truffle/test/LazyInitializationTest.java index 8c9243342e78..7386aa07d517 100644 --- a/compiler/src/org.graalvm.compiler.truffle.test/src/org/graalvm/compiler/truffle/test/LazyInitializationTest.java +++ b/compiler/src/org.graalvm.compiler.truffle.test/src/org/graalvm/compiler/truffle/test/LazyInitializationTest.java @@ -43,7 +43,6 @@ import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.options.OptionValuesAccess; import org.graalvm.compiler.options.OptionsParser; -import org.graalvm.compiler.serviceprovider.JDK9Method; import org.graalvm.compiler.test.SubprocessUtil; import org.graalvm.compiler.test.SubprocessUtil.Subprocess; import org.junit.Assert; @@ -214,17 +213,12 @@ private boolean isGraalClassAllowed(Class cls) { return true; } - if (JDK9Method.JAVA_SPECIFICATION_VERSION >= 9 && cls.equals(JDK9Method.class)) { - // Graal initialization needs access to Module API on JDK 9. - return true; - } - if (cls.equals(jvmciVersionCheck)) { // The Graal initialization needs to check the JVMCI version. return true; } - if (JVMCICompilerFactory.class.isAssignableFrom(cls)) { + if (JVMCICompilerFactory.class.isAssignableFrom(cls) || cls.getName().equals("org.graalvm.compiler.hotspot.IsGraalPredicate")) { // The compiler factories have to be loaded and instantiated by the JVMCI. return true; }