hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ReplacementsImpl.java
changeset 46459 7d4e637d3f21
parent 46371 0337d0617e7b
child 46640 70bdce04c59b
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ReplacementsImpl.java	Fri May 12 13:14:25 2017 -0700
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ReplacementsImpl.java	Fri May 12 13:56:13 2017 -0700
@@ -37,6 +37,7 @@
 import org.graalvm.compiler.api.replacements.Snippet;
 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
 import org.graalvm.compiler.api.replacements.SnippetTemplateCache;
+import org.graalvm.compiler.bytecode.Bytecode;
 import org.graalvm.compiler.bytecode.BytecodeProvider;
 import org.graalvm.compiler.bytecode.ResolvedJavaMethodBytecode;
 import org.graalvm.compiler.core.common.GraalOptions;
@@ -74,6 +75,7 @@
 import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.graalvm.compiler.phases.util.Providers;
 import org.graalvm.compiler.word.Word;
+import org.graalvm.compiler.word.WordOperationPlugin;
 import org.graalvm.util.EconomicMap;
 import org.graalvm.util.Equivalence;
 
@@ -101,13 +103,18 @@
      */
     protected final ConcurrentMap<ResolvedJavaMethod, StructuredGraph> graphs;
 
-    protected final BytecodeProvider bytecodeProvider;
+    /**
+     * The default {@link BytecodeProvider} to use for accessing the bytecode of a replacement if
+     * the replacement doesn't provide another {@link BytecodeProvider}.
+     */
+    protected final BytecodeProvider defaultBytecodeProvider;
 
     public void setGraphBuilderPlugins(GraphBuilderConfiguration.Plugins plugins) {
         assert this.graphBuilderPlugins == null;
         this.graphBuilderPlugins = plugins;
     }
 
+    @Override
     public GraphBuilderConfiguration.Plugins getGraphBuilderPlugins() {
         return graphBuilderPlugins;
     }
@@ -131,11 +138,11 @@
      */
     @Override
     public InlineInfo shouldInlineInvoke(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args) {
-        ResolvedJavaMethod subst = getSubstitutionMethod(method);
+        Bytecode subst = getSubstitutionBytecode(method);
         if (subst != null) {
             if (b.parsingIntrinsic() || InlineDuringParsing.getValue(b.getOptions()) || InlineIntrinsicsDuringParsing.getValue(b.getOptions())) {
                 // Forced inlining of intrinsics
-                return createIntrinsicInlineInfo(subst, bytecodeProvider);
+                return createIntrinsicInlineInfo(subst.getMethod(), subst.getOrigin());
             }
             return null;
         }
@@ -143,7 +150,7 @@
             assert b.getDepth() < MAX_GRAPH_INLINING_DEPTH : "inlining limit exceeded";
 
             // Force inlining when parsing replacements
-            return createIntrinsicInlineInfo(method, bytecodeProvider);
+            return createIntrinsicInlineInfo(method, defaultBytecodeProvider);
         } else {
             assert method.getAnnotation(NodeIntrinsic.class) == null : String.format("@%s method %s must only be called from within a replacement%n%s", NodeIntrinsic.class.getSimpleName(),
                             method.format("%h.%n"), b);
@@ -180,7 +187,7 @@
         this.target = target;
         this.graphs = new ConcurrentHashMap<>();
         this.snippetTemplateCache = EconomicMap.create(Equivalence.DEFAULT);
-        this.bytecodeProvider = bytecodeProvider;
+        this.defaultBytecodeProvider = bytecodeProvider;
     }
 
     private static final DebugTimer SnippetPreparationTime = Debug.timer("SnippetPreparationTime");
@@ -199,7 +206,7 @@
         StructuredGraph graph = UseSnippetGraphCache.getValue(options) ? graphs.get(method) : null;
         if (graph == null) {
             try (DebugCloseable a = SnippetPreparationTime.start()) {
-                StructuredGraph newGraph = makeGraph(method, args, recursiveEntry);
+                StructuredGraph newGraph = makeGraph(defaultBytecodeProvider, method, args, recursiveEntry);
                 Debug.counter("SnippetNodeCount[%#s]", method).add(newGraph.getNodeCount());
                 if (!UseSnippetGraphCache.getValue(options) || args != null) {
                     return newGraph;
@@ -223,16 +230,17 @@
     }
 
     @Override
-    public BytecodeProvider getReplacementBytecodeProvider() {
-        return bytecodeProvider;
+    public BytecodeProvider getDefaultReplacementBytecodeProvider() {
+        return defaultBytecodeProvider;
     }
 
     @Override
-    public ResolvedJavaMethod getSubstitutionMethod(ResolvedJavaMethod method) {
+    public Bytecode getSubstitutionBytecode(ResolvedJavaMethod method) {
         InvocationPlugin plugin = graphBuilderPlugins.getInvocationPlugins().lookupInvocation(method);
         if (plugin instanceof MethodSubstitutionPlugin) {
             MethodSubstitutionPlugin msPlugin = (MethodSubstitutionPlugin) plugin;
-            return msPlugin.getSubstitute(providers.getMetaAccess());
+            ResolvedJavaMethod substitute = msPlugin.getSubstitute(providers.getMetaAccess());
+            return msPlugin.getBytecodeProvider().getBytecode(substitute);
         }
         return null;
     }
@@ -248,7 +256,7 @@
                 ResolvedJavaMethod substitute = msPlugin.getSubstitute(metaAccess);
                 StructuredGraph graph = graphs.get(substitute);
                 if (graph == null) {
-                    graph = makeGraph(substitute, null, method);
+                    graph = makeGraph(msPlugin.getBytecodeProvider(), substitute, null, method);
                     graph.freeze();
                     graphs.putIfAbsent(substitute, graph);
                     graph = graphs.get(substitute);
@@ -256,7 +264,7 @@
                 assert graph.isFrozen();
                 result = graph;
             } else {
-                ResolvedJavaMethodBytecode code = new ResolvedJavaMethodBytecode(method);
+                Bytecode code = new ResolvedJavaMethodBytecode(method);
                 ConstantReflectionProvider constantReflection = providers.getConstantReflection();
                 ConstantFieldProvider constantFieldProvider = providers.getConstantFieldProvider();
                 StampProvider stampProvider = providers.getStampProvider();
@@ -271,14 +279,14 @@
     /**
      * Creates a preprocessed graph for a snippet or method substitution.
      *
+     * @param bytecodeProvider how to access the bytecode of {@code method}
      * @param method the snippet or method substitution for which a graph will be created
      * @param args
      * @param original the original method if {@code method} is a {@linkplain MethodSubstitution
      *            substitution} otherwise null
      */
-    @SuppressWarnings("try")
-    public StructuredGraph makeGraph(ResolvedJavaMethod method, Object[] args, ResolvedJavaMethod original) {
-        return createGraphMaker(method, original).makeGraph(args);
+    public StructuredGraph makeGraph(BytecodeProvider bytecodeProvider, ResolvedJavaMethod method, Object[] args, ResolvedJavaMethod original) {
+        return createGraphMaker(method, original).makeGraph(bytecodeProvider, args);
     }
 
     /**
@@ -315,10 +323,10 @@
         }
 
         @SuppressWarnings("try")
-        public StructuredGraph makeGraph(Object[] args) {
+        public StructuredGraph makeGraph(BytecodeProvider bytecodeProvider, Object[] args) {
             try (Scope s = Debug.scope("BuildSnippetGraph", method)) {
                 assert method.hasBytecodes() : method;
-                StructuredGraph graph = buildInitialGraph(method, args);
+                StructuredGraph graph = buildInitialGraph(bytecodeProvider, method, args);
 
                 finalizeGraph(graph);
 
@@ -379,10 +387,10 @@
         }
 
         /**
-         * Builds the initial graph for a snippet.
+         * Builds the initial graph for a replacement.
          */
         @SuppressWarnings("try")
-        protected StructuredGraph buildInitialGraph(final ResolvedJavaMethod methodToParse, Object[] args) {
+        protected StructuredGraph buildInitialGraph(BytecodeProvider bytecodeProvider, final ResolvedJavaMethod methodToParse, Object[] args) {
             // Replacements cannot have optimistic assumptions since they have
             // to be valid for the entire run of the VM.
 
@@ -403,11 +411,11 @@
                 IntrinsicContext initialIntrinsicContext = null;
                 if (method.getAnnotation(Snippet.class) == null) {
                     // Post-parse inlined intrinsic
-                    initialIntrinsicContext = new IntrinsicContext(substitutedMethod, method, replacements.bytecodeProvider, INLINE_AFTER_PARSING);
+                    initialIntrinsicContext = new IntrinsicContext(substitutedMethod, method, bytecodeProvider, INLINE_AFTER_PARSING);
                 } else {
                     // Snippet
                     ResolvedJavaMethod original = substitutedMethod != null ? substitutedMethod : method;
-                    initialIntrinsicContext = new IntrinsicContext(original, method, replacements.bytecodeProvider, INLINE_AFTER_PARSING);
+                    initialIntrinsicContext = new IntrinsicContext(original, method, bytecodeProvider, INLINE_AFTER_PARSING);
                 }
 
                 createGraphBuilder(metaAccess, replacements.providers.getStampProvider(), replacements.providers.getConstantReflection(), replacements.providers.getConstantFieldProvider(), config,