changeset 20935:30cbb666e512

expand API for retrieving method substitution graphs to indicate the BCI of the invoke being inlined or -1 if the request is not in the context of inlining
author Doug Simon <doug.simon@oracle.com>
date Tue, 14 Apr 2015 14:57:41 +0200
parents fb96fbd5acbd
children f41cd2c2916d
files graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotCryptoSubstitutionTest.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Replacements.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/elem/InlineableGraph.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/policy/AbstractInliningPolicy.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/policy/InlineMethodSubstitutionsPolicy.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/InliningData.java graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MethodSubstitutionTest.java graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/StandardMethodSubstitutionsTest.java graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/StringSubstitutionsTest.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/IntrinsicGraphBuilder.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java
diffstat 15 files changed, 63 insertions(+), 45 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotCryptoSubstitutionTest.java	Tue Apr 14 14:26:43 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotCryptoSubstitutionTest.java	Tue Apr 14 14:57:41 2015 +0200
@@ -126,7 +126,7 @@
             Method method = lookup(className, methodName);
             if (method != null) {
                 ResolvedJavaMethod installedCodeOwner = getMetaAccess().lookupJavaMethod(method);
-                StructuredGraph subst = getReplacements().getSubstitution(installedCodeOwner);
+                StructuredGraph subst = getReplacements().getSubstitution(installedCodeOwner, 0);
                 ResolvedJavaMethod substMethod = subst == null ? null : subst.method();
                 if (substMethod != null) {
                     StructuredGraph graph = new StructuredGraph(substMethod, AllowAssumptions.YES);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java	Tue Apr 14 14:26:43 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java	Tue Apr 14 14:57:41 2015 +0200
@@ -88,7 +88,7 @@
                 }
                 if (BootstrapReplacements.getValue()) {
                     for (ResolvedJavaMethod method : replacements.getAllReplacements()) {
-                        replacements.getSubstitution(method);
+                        replacements.getSubstitution(method, -1);
                     }
                 }
             } catch (Throwable e) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Replacements.java	Tue Apr 14 14:26:43 2015 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Replacements.java	Tue Apr 14 14:57:41 2015 +0200
@@ -70,39 +70,47 @@
     /**
      * Gets a graph that is a substitution for a given method.
      *
+     * @param invokeBci the call site BCI if this request is made for inlining a substitute
+     *            otherwise {@code -1}
      * @return the graph, if any, that is a substitution for {@code method}
      */
-    default StructuredGraph getSubstitution(ResolvedJavaMethod method) {
-        return getSubstitution(method, false);
+    default StructuredGraph getSubstitution(ResolvedJavaMethod method, int invokeBci) {
+        return getSubstitution(method, false, invokeBci);
     }
 
     /**
      * Gets a graph that is a substitution for a given method.
      *
      * @param fromBytecodeOnly only return a graph created by parsing the bytecode of another method
+     * @param invokeBci the call site BCI if this request is made for inlining a substitute
+     *            otherwise {@code -1}
      * @return the graph, if any, that is a substitution for {@code method}
      */
-    StructuredGraph getSubstitution(ResolvedJavaMethod method, boolean fromBytecodeOnly);
+    StructuredGraph getSubstitution(ResolvedJavaMethod method, boolean fromBytecodeOnly, int invokeBci);
 
     /**
-     * Determines if there is a {@linkplain #getSubstitution(ResolvedJavaMethod) substitution graph}
-     * for a given method.
+     * Determines if there is a {@linkplain #getSubstitution(ResolvedJavaMethod, int) substitution
+     * graph} for a given method.
      *
+     * @param invokeBci the call site BCI if this request is made for inlining a substitute
+     *            otherwise {@code -1}
      * @return true iff there is a substitution graph available for {@code method}
      */
-    default boolean hasSubstitution(ResolvedJavaMethod method) {
-        return hasSubstitution(method, false);
+    default boolean hasSubstitution(ResolvedJavaMethod method, int invokeBci) {
+        return hasSubstitution(method, false, invokeBci);
     }
 
     /**
-     * Determines if there is a {@linkplain #getSubstitution(ResolvedJavaMethod) substitution graph}
-     * for a given method.
+     * Determines if there is a {@linkplain #getSubstitution(ResolvedJavaMethod, int) substitution
+     * graph} for a given method.
      *
      * @param fromBytecodeOnly only consider graphs created by parsing the bytecode of another
      *            method
+     * @param invokeBci the call site BCI if this request is made for inlining a substitute
+     *            otherwise {@code -1}
      * @return true iff there is a substitution graph available for {@code method}
      */
-    boolean hasSubstitution(ResolvedJavaMethod method, boolean fromBytecodeOnly);
+    boolean hasSubstitution(ResolvedJavaMethod method, boolean fromBytecodeOnly, int invokeBci);
 
     /**
      * Registers all the {@linkplain MethodSubstitution method} substitutions defined by a given
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java	Tue Apr 14 14:26:43 2015 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java	Tue Apr 14 14:57:41 2015 +0200
@@ -646,12 +646,12 @@
         return firstParam;
     }
 
-    public static boolean canIntrinsify(Replacements replacements, ResolvedJavaMethod target) {
-        return replacements.hasSubstitution(target, false);
+    public static boolean canIntrinsify(Replacements replacements, ResolvedJavaMethod target, int invokeBci) {
+        return replacements.hasSubstitution(target, false, invokeBci);
     }
 
-    public static StructuredGraph getIntrinsicGraph(Replacements replacements, ResolvedJavaMethod target) {
-        return replacements.getSubstitution(target);
+    public static StructuredGraph getIntrinsicGraph(Replacements replacements, ResolvedJavaMethod target, int invokeBci) {
+        return replacements.getSubstitution(target, invokeBci);
     }
 
     public static FixedWithNextNode inlineMacroNode(Invoke invoke, ResolvedJavaMethod concrete, Class<? extends FixedWithNextNode> macroNodeClass) throws GraalInternalError {
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/elem/InlineableGraph.java	Tue Apr 14 14:26:43 2015 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/elem/InlineableGraph.java	Tue Apr 14 14:57:41 2015 +0200
@@ -59,7 +59,7 @@
     private FixedNodeProbabilityCache probabilites = new FixedNodeProbabilityCache();
 
     public InlineableGraph(final ResolvedJavaMethod method, final Invoke invoke, final HighTierContext context, CanonicalizerPhase canonicalizer) {
-        StructuredGraph original = getOriginalGraph(method, context, canonicalizer, invoke.asNode().graph());
+        StructuredGraph original = getOriginalGraph(method, context, canonicalizer, invoke.asNode().graph(), invoke.bci());
         // TODO copying the graph is only necessary if it is modified or if it contains any invokes
         this.graph = original.copy();
         specializeGraphToArguments(invoke, context, canonicalizer);
@@ -70,8 +70,8 @@
      * The graph thus obtained is returned, ie the caller is responsible for cloning before
      * modification.
      */
-    private static StructuredGraph getOriginalGraph(final ResolvedJavaMethod method, final HighTierContext context, CanonicalizerPhase canonicalizer, StructuredGraph caller) {
-        StructuredGraph result = InliningUtil.getIntrinsicGraph(context.getReplacements(), method);
+    private static StructuredGraph getOriginalGraph(final ResolvedJavaMethod method, final HighTierContext context, CanonicalizerPhase canonicalizer, StructuredGraph caller, int callerBci) {
+        StructuredGraph result = InliningUtil.getIntrinsicGraph(context.getReplacements(), method, callerBci);
         if (result != null) {
             return result;
         }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/policy/AbstractInliningPolicy.java	Tue Apr 14 14:26:43 2015 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/policy/AbstractInliningPolicy.java	Tue Apr 14 14:57:41 2015 +0200
@@ -66,7 +66,7 @@
 
     private static boolean onlyIntrinsics(Replacements replacements, InlineInfo info) {
         for (int i = 0; i < info.numberOfMethods(); i++) {
-            if (!InliningUtil.canIntrinsify(replacements, info.methodAt(i))) {
+            if (!InliningUtil.canIntrinsify(replacements, info.methodAt(i), info.invoke().bci())) {
                 return false;
             }
         }
@@ -75,7 +75,7 @@
 
     private static boolean onlyForcedIntrinsics(Replacements replacements, InlineInfo info) {
         for (int i = 0; i < info.numberOfMethods(); i++) {
-            if (!InliningUtil.canIntrinsify(replacements, info.methodAt(i))) {
+            if (!InliningUtil.canIntrinsify(replacements, info.methodAt(i), info.invoke().bci())) {
                 return false;
             }
             if (!replacements.isForcedSubstitution(info.methodAt(i))) {
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/policy/InlineMethodSubstitutionsPolicy.java	Tue Apr 14 14:26:43 2015 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/policy/InlineMethodSubstitutionsPolicy.java	Tue Apr 14 14:57:41 2015 +0200
@@ -38,7 +38,7 @@
         CallTargetNode callTarget = invocation.callee().invoke().callTarget();
         if (callTarget instanceof MethodCallTargetNode) {
             ResolvedJavaMethod calleeMethod = ((MethodCallTargetNode) callTarget).targetMethod();
-            if (replacements.getSubstitution(calleeMethod) != null) {
+            if (replacements.getSubstitution(calleeMethod, invocation.callee().invoke().bci()) != null) {
                 return true;
             }
         }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/InliningData.java	Tue Apr 14 14:26:43 2015 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/InliningData.java	Tue Apr 14 14:57:41 2015 +0200
@@ -108,10 +108,10 @@
         return (arg instanceof AbstractNewObjectNode) || (arg instanceof AllocatedObjectNode) || (arg instanceof VirtualObjectNode);
     }
 
-    private String checkTargetConditionsHelper(ResolvedJavaMethod method) {
+    private String checkTargetConditionsHelper(ResolvedJavaMethod method, int invokeBci) {
         if (method == null) {
             return "the method is not resolved";
-        } else if (method.isNative() && (!Intrinsify.getValue() || !InliningUtil.canIntrinsify(context.getReplacements(), method))) {
+        } else if (method.isNative() && (!Intrinsify.getValue() || !InliningUtil.canIntrinsify(context.getReplacements(), method, invokeBci))) {
             return "it is a non-intrinsic native method";
         } else if (method.isAbstract()) {
             return "it is an abstract method";
@@ -129,7 +129,7 @@
     }
 
     private boolean checkTargetConditions(Invoke invoke, ResolvedJavaMethod method) {
-        final String failureMessage = checkTargetConditionsHelper(method);
+        final String failureMessage = checkTargetConditionsHelper(method, invoke.bci());
         if (failureMessage == null) {
             return true;
         } else {
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MethodSubstitutionTest.java	Tue Apr 14 14:26:43 2015 +0200
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MethodSubstitutionTest.java	Tue Apr 14 14:57:41 2015 +0200
@@ -76,7 +76,7 @@
         StructuredGraph graph = testGraph(testMethodName);
 
         // Check to see if the resulting graph contains the expected node
-        StructuredGraph replacement = getReplacements().getSubstitution(realMethod);
+        StructuredGraph replacement = getReplacements().getSubstitution(realMethod, -1);
         if (replacement == null && !optional) {
             assertInGraph(graph, intrinsicClass);
         }
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/StandardMethodSubstitutionsTest.java	Tue Apr 14 14:26:43 2015 +0200
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/StandardMethodSubstitutionsTest.java	Tue Apr 14 14:57:41 2015 +0200
@@ -131,7 +131,7 @@
         StructuredGraph graph = testGraph(testMethodName);
 
         // Check to see if the resulting graph contains the expected node
-        StructuredGraph replacement = getReplacements().getSubstitution(realJavaMethod);
+        StructuredGraph replacement = getReplacements().getSubstitution(realJavaMethod, -1);
         if (replacement == null && !optional) {
             assertInGraph(graph, intrinsicClass);
         }
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/StringSubstitutionsTest.java	Tue Apr 14 14:26:43 2015 +0200
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/StringSubstitutionsTest.java	Tue Apr 14 14:57:41 2015 +0200
@@ -41,7 +41,7 @@
         StructuredGraph graph = testGraph(testMethodName);
 
         // Check to see if the resulting graph contains the expected node
-        StructuredGraph replacement = getReplacements().getSubstitution(realMethod);
+        StructuredGraph replacement = getReplacements().getSubstitution(realMethod, -1);
         if (replacement == null && !optional) {
             assertInGraph(graph, intrinsicClass);
         }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/IntrinsicGraphBuilder.java	Tue Apr 14 14:26:43 2015 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/IntrinsicGraphBuilder.java	Tue Apr 14 14:57:41 2015 +0200
@@ -45,16 +45,18 @@
     private final StampProvider stampProvider;
     private final StructuredGraph graph;
     private final ResolvedJavaMethod method;
+    private final int invokeBci;
     private FixedWithNextNode lastInstr;
     private ValueNode[] arguments;
     private ValueNode returnValue;
 
-    public IntrinsicGraphBuilder(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, StampProvider stampProvider, ResolvedJavaMethod method) {
+    public IntrinsicGraphBuilder(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, StampProvider stampProvider, ResolvedJavaMethod method, int invokeBci) {
         this.metaAccess = metaAccess;
         this.constantReflection = constantReflection;
         this.stampProvider = stampProvider;
         this.graph = new StructuredGraph(method, AllowAssumptions.YES);
         this.method = method;
+        this.invokeBci = invokeBci;
         this.lastInstr = graph.start();
 
         Signature sig = method.getSignature();
@@ -163,7 +165,7 @@
     }
 
     public int bci() {
-        return -1;
+        return invokeBci;
     }
 
     public InvokeKind getInvokeKind() {
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Tue Apr 14 14:26:43 2015 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Tue Apr 14 14:57:41 2015 +0200
@@ -334,17 +334,21 @@
     }
 
     @Override
-    public StructuredGraph getSubstitution(ResolvedJavaMethod original, boolean fromBytecodeOnly) {
+    public StructuredGraph getSubstitution(ResolvedJavaMethod original, boolean fromBytecodeOnly, int invokeBci) {
         ResolvedJavaMethod substitute = null;
         if (!fromBytecodeOnly) {
             InvocationPlugin plugin = graphBuilderPlugins.getInvocationPlugins().lookupInvocation(original);
-            if (plugin instanceof MethodSubstitutionPlugin) {
-                MethodSubstitutionPlugin msplugin = (MethodSubstitutionPlugin) plugin;
-                substitute = msplugin.getSubstitute(providers.getMetaAccess());
-            } else if (plugin != null) {
-                StructuredGraph graph = new IntrinsicGraphBuilder(providers.getMetaAccess(), providers.getConstantReflection(), providers.getStampProvider(), original).buildGraph(plugin);
-                if (graph != null) {
-                    return graph;
+            if (plugin != null) {
+                if (!plugin.inlineOnly() || invokeBci >= 0) {
+                    if (plugin instanceof MethodSubstitutionPlugin) {
+                        MethodSubstitutionPlugin msplugin = (MethodSubstitutionPlugin) plugin;
+                        substitute = msplugin.getSubstitute(providers.getMetaAccess());
+                    } else {
+                        StructuredGraph graph = new IntrinsicGraphBuilder(providers.getMetaAccess(), providers.getConstantReflection(), providers.getStampProvider(), original, invokeBci).buildGraph(plugin);
+                        if (graph != null) {
+                            return graph;
+                        }
+                    }
                 }
             }
         }
@@ -806,10 +810,13 @@
         return cr != null && cr.forcedSubstitutions.contains(method);
     }
 
-    public boolean hasSubstitution(ResolvedJavaMethod method, boolean fromBytecodeOnly) {
+    public boolean hasSubstitution(ResolvedJavaMethod method, boolean fromBytecodeOnly, int callerBci) {
         if (!fromBytecodeOnly) {
-            if (graphBuilderPlugins.getInvocationPlugins().lookupInvocation(method) != null) {
-                return true;
+            InvocationPlugin plugin = graphBuilderPlugins.getInvocationPlugins().lookupInvocation(method);
+            if (plugin != null) {
+                if (!plugin.inlineOnly() || callerBci >= 0) {
+                    return true;
+                }
             }
         }
         return getSubstitutionMethod(method) != null;
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java	Tue Apr 14 14:26:43 2015 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java	Tue Apr 14 14:57:41 2015 +0200
@@ -74,6 +74,7 @@
         this.targetMethod = targetMethod;
         this.returnType = returnType;
         this.invokeKind = invokeKind;
+        assert bci >= 0;
     }
 
     public int getBci() {
@@ -108,7 +109,7 @@
      * lowered}.
      */
     protected StructuredGraph getLoweredSubstitutionGraph(LoweringTool tool) {
-        StructuredGraph methodSubstitution = tool.getReplacements().getSubstitution(getTargetMethod(), true);
+        StructuredGraph methodSubstitution = tool.getReplacements().getSubstitution(getTargetMethod(), true, bci);
         if (methodSubstitution != null) {
             methodSubstitution = methodSubstitution.copy();
             if (stateAfter() == null || stateAfter().bci == BytecodeFrame.AFTER_BCI) {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Tue Apr 14 14:26:43 2015 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Tue Apr 14 14:57:41 2015 +0200
@@ -184,7 +184,7 @@
             if (original.getAnnotation(TruffleBoundary.class) != null) {
                 return null;
             }
-            assert !replacements.hasSubstitution(original) : "Replacements must have been processed by now";
+            assert !replacements.hasSubstitution(original, builder.bci()) : "Replacements must have been processed by now";
             assert !builder.parsingReplacement();
 
             if (TruffleCompilerOptions.TruffleFunctionInlining.getValue()) {
@@ -260,7 +260,7 @@
             if (original.getAnnotation(TruffleBoundary.class) != null) {
                 return null;
             }
-            assert !replacements.hasSubstitution(original) : "Replacements must have been processed by now";
+            assert !replacements.hasSubstitution(original, builder.bci()) : "Replacements must have been processed by now";
 
             if (original.equals(callSiteProxyMethod) || original.equals(callDirectMethod)) {
                 return null;
@@ -366,7 +366,7 @@
         new ConvertDeoptimizeToGuardPhase().apply(graph, tierContext);
 
         for (MethodCallTargetNode methodCallTargetNode : graph.getNodes(MethodCallTargetNode.TYPE)) {
-            StructuredGraph inlineGraph = providers.getReplacements().getSubstitution(methodCallTargetNode.targetMethod());
+            StructuredGraph inlineGraph = providers.getReplacements().getSubstitution(methodCallTargetNode.targetMethod(), methodCallTargetNode.invoke().bci());
             if (inlineGraph != null) {
                 InliningUtil.inline(methodCallTargetNode.invoke(), inlineGraph, true, null);
             }