Mercurial > hg > graal-compiler
changeset 19808:1e27e31aca11
fixed bug in managing replacement scope during bytecode parsing and improved API for querying replacement info from graph builder plugins
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Thu, 12 Mar 2015 15:25:43 +0100 |
parents | 0a3c6e786b40 |
children | 97a72dcdac8d |
files | graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInlineInvokePlugin.java graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderContext.java graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPlugin.java |
diffstat | 5 files changed, 73 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInlineInvokePlugin.java Thu Mar 12 15:20:29 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInlineInvokePlugin.java Thu Mar 12 15:25:43 2015 +0100 @@ -27,10 +27,10 @@ import static java.lang.String.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.replacements.*; import com.oracle.graal.graph.Node.NodeIntrinsic; import com.oracle.graal.hotspot.word.*; import com.oracle.graal.java.*; +import com.oracle.graal.java.GraphBuilderContext.Replacement; import com.oracle.graal.java.GraphBuilderPlugin.InlineInvokePlugin; import com.oracle.graal.nodes.*; import com.oracle.graal.replacements.*; @@ -69,8 +69,10 @@ public void notifyOfNoninlinedInvoke(GraphBuilderContext b, ResolvedJavaMethod method, Invoke invoke) { if (b.parsingReplacement()) { - boolean compilingSnippet = b.getRootMethod().getAnnotation(MethodSubstitution.class) == null; - assert compilingSnippet : format("All calls in the replacement %s must be inlined or intrinsified: found call to %s", b.getRootMethod().format("%H.%n(%p)"), method.format("%h.%n(%p)")); + boolean compilingSnippet = b.getRootMethod().getAnnotation(Snippet.class) != null; + Replacement replacement = b.getReplacement(); + assert compilingSnippet : format("All calls in the replacement %s must be inlined or intrinsified: found call to %s", replacement.getReplacementMethod().format("%H.%n(%p)"), + method.format("%h.%n(%p)")); } } }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java Thu Mar 12 15:20:29 2015 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java Thu Mar 12 15:25:43 2015 +0100 @@ -38,6 +38,7 @@ import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.debug.*; import com.oracle.graal.java.BciBlockMapping.BciBlock; +import com.oracle.graal.java.GraphBuilderContext.Replacement; import com.oracle.graal.java.GraphBuilderPhase.Instance.BytecodeParser; import com.oracle.graal.java.GraphBuilderPlugin.LoadFieldPlugin; import com.oracle.graal.java.GraphBuilderPlugin.LoadIndexedPlugin; @@ -81,7 +82,7 @@ * happen when a call to a {@link MethodSubstitution} is encountered or the root of compilation * is a {@link MethodSubstitution} or a snippet. */ - static class ReplacementContext { + static class ReplacementContext implements Replacement { /** * The method being replaced. */ @@ -97,6 +98,18 @@ this.replacement = substitute; } + public ResolvedJavaMethod getOriginalMethod() { + return method; + } + + public ResolvedJavaMethod getReplacementMethod() { + return replacement; + } + + public boolean isIntrinsic() { + return false; + } + /** * Determines if a call within the compilation scope of a replacement represents a call to * the original method. @@ -112,7 +125,7 @@ /** * Context for a replacement being inlined as a compiler intrinsic. Deoptimization within a - * compiler intrinic must replay the intrinsified call. This context object retains the + * compiler intrinsic must replay the intrinsified call. This context object retains the * information required to build a frame state denoting the JVM state just before the * intrinsified call. */ @@ -137,6 +150,11 @@ this.invokeBci = invokeBci; } + @Override + public boolean isIntrinsic() { + return true; + } + /** * Gets the frame state that will restart the interpreter just before the intrinsified * invocation.
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderContext.java Thu Mar 12 15:20:29 2015 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderContext.java Thu Mar 12 15:25:43 2015 +0100 @@ -34,6 +34,30 @@ */ public interface GraphBuilderContext { + /** + * Information about a snippet or method substitution currently being processed by the graph + * builder. + */ + public interface Replacement { + + /** + * Gets the method being replaced. + */ + ResolvedJavaMethod getOriginalMethod(); + + /** + * Gets the replacement method. + */ + ResolvedJavaMethod getReplacementMethod(); + + /** + * Determines if this replacement is being inlined as a compiler intrinsic. A compiler + * intrinsic is atomic with respect to deoptimization. Deoptimization within a compiler + * intrinsic will restart the interpreter at the intrinsified call. + */ + boolean isIntrinsic(); + } + <T extends ControlSinkNode> T append(T fixed); <T extends ControlSplitNode> T append(T fixed); @@ -87,7 +111,15 @@ /** * Determines if the current parsing context is a snippet or method substitution. */ - boolean parsingReplacement(); + default boolean parsingReplacement() { + return getReplacement() == null; + } + + /** + * Gets the replacement of the current parsing context or {@code null} if not + * {@link #parsingReplacement() parsing a replacement}. + */ + Replacement getReplacement(); /** * @see GuardingPiNode#nullCheckedValue(ValueNode)
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Thu Mar 12 15:20:29 2015 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Thu Mar 12 15:25:43 2015 +0100 @@ -1212,8 +1212,9 @@ if (context != null && context.isCallToOriginal(targetMethod)) { // Self recursive replacement means the original // method should be called. - if (targetMethod.hasBytecodes()) { - parseAndInlineCallee(context.method, args, null); + if (context.method.hasBytecodes()) { + IntrinsicContext intrinsic = context.asIntrinsic(); + parseAndInlineCallee(context.method, args, intrinsic); } else { return false; } @@ -1225,9 +1226,13 @@ context = new ReplacementContext(targetMethod, inlinedMethod); } } - parseAndInlineCallee(inlinedMethod, args, context); - if (plugin != null) { - plugin.postInline(inlinedMethod); + if (inlinedMethod.hasBytecodes()) { + parseAndInlineCallee(inlinedMethod, args, context); + if (plugin != null) { + plugin.postInline(inlinedMethod); + } + } else { + return false; } } return true; @@ -2350,6 +2355,10 @@ return parent == null ? 0 : 1 + parent.getDepth(); } + public Replacement getReplacement() { + return replacementContext; + } + public ResolvedJavaMethod getRootMethod() { return rootMethod; }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPlugin.java Thu Mar 12 15:20:29 2015 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPlugin.java Thu Mar 12 15:25:43 2015 +0100 @@ -77,7 +77,7 @@ /** * The method to be inlined. If this is not equal to the {@code method} argument passed * to {@link InlineInvokePlugin#getClass()}, the graph builder context interprets it as - * a {@linkplain GraphBuilderContext#parsingReplacement() replacement}. + * a {@linkplain GraphBuilderContext.Replacement replacement}. */ public final ResolvedJavaMethod methodToInline;