# HG changeset patch # User Doug Simon # Date 1426019162 -3600 # Node ID 69b7ad0a3fda2a87015bb327acb10bbdd82695ff # Parent 86f2cb32cd643bafdb5d0961e2f108652415f482# Parent 39315508f1b6d6e4b05d6e98205ec6f31b7d50c7 Merge. diff -r 39315508f1b6 -r 69b7ad0a3fda graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/BytecodeFrame.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/BytecodeFrame.java Tue Mar 10 19:44:56 2015 +0100 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/BytecodeFrame.java Tue Mar 10 21:26:02 2015 +0100 @@ -85,7 +85,7 @@ /** * True if this is a position inside an exception handler before the exception object has been - * consumed. In this case, {@link #numStack == 1} and {@link #getStackValue(int) + * consumed. In this case, {@link #numStack} {@code == 1} and {@link #getStackValue(int) * getStackValue(0)} is the location of the exception object. If deoptimization happens at this * position, the interpreter will rethrow the exception instead of executing the bytecode * instruction at this position. diff -r 39315508f1b6 -r 69b7ad0a3fda graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java Tue Mar 10 19:44:56 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -68,7 +68,7 @@ StructuredGraph graph = new StructuredGraph(javaMethod, allowAssumptions); GraphBuilderConfiguration conf = GraphBuilderConfiguration.getSnippetDefault(); - new GraphBuilderPhase.Instance(getMetaAccess(), getProviders().getStampProvider(), getProviders().getConstantReflection(), conf, OptimisticOptimizations.ALL).apply(graph); + new GraphBuilderPhase.Instance(getMetaAccess(), getProviders().getStampProvider(), getProviders().getConstantReflection(), conf, OptimisticOptimizations.ALL, false).apply(graph); HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); new InliningPhase(new CanonicalizerPhase()).apply(graph, context); new CanonicalizerPhase().apply(graph, context); diff -r 39315508f1b6 -r 69b7ad0a3fda graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EATestBase.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EATestBase.java Tue Mar 10 19:44:56 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EATestBase.java Tue Mar 10 21:26:02 2015 +0100 @@ -152,7 +152,7 @@ graph = new StructuredGraph(method, AllowAssumptions.NO); try (Scope s = Debug.scope(getClass(), graph, method, getCodeCache())) { new GraphBuilderPhase.Instance(getMetaAccess(), getProviders().getStampProvider(), getProviders().getConstantReflection(), GraphBuilderConfiguration.getEagerDefault(), - OptimisticOptimizations.ALL).apply(graph); + OptimisticOptimizations.ALL, false).apply(graph); context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); new InliningPhase(new CanonicalizerPhase()).apply(graph, context); new DeadCodeEliminationPhase().apply(graph); diff -r 39315508f1b6 -r 69b7ad0a3fda graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/tutorial/StaticAnalysis.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/tutorial/StaticAnalysis.java Tue Mar 10 19:44:56 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/tutorial/StaticAnalysis.java Tue Mar 10 21:26:02 2015 +0100 @@ -237,7 +237,7 @@ */ OptimisticOptimizations optimisticOpts = OptimisticOptimizations.NONE; - GraphBuilderPhase.Instance graphBuilder = new GraphBuilderPhase.Instance(metaAccess, stampProvider, null, graphBuilderConfig, optimisticOpts); + GraphBuilderPhase.Instance graphBuilder = new GraphBuilderPhase.Instance(metaAccess, stampProvider, null, graphBuilderConfig, optimisticOpts, false); graphBuilder.apply(graph); } catch (Throwable ex) { Debug.handle(ex); diff -r 39315508f1b6 -r 69b7ad0a3fda graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotAnnotatedInvocationPlugin.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotAnnotatedInvocationPlugin.java Tue Mar 10 21:26:02 2015 +0100 @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2015, 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 com.oracle.graal.hotspot.meta; + +import static com.oracle.graal.api.meta.MetaUtil.*; +import static com.oracle.graal.replacements.NodeIntrinsificationPhase.*; + +import java.util.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.type.*; +import com.oracle.graal.graph.Node.*; +import com.oracle.graal.java.*; +import com.oracle.graal.java.GraphBuilderPlugin.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.replacements.*; + +final class HotSpotAnnotatedInvocationPlugin implements AnnotatedInvocationPlugin { + private final HotSpotSuitesProvider suites; + + public HotSpotAnnotatedInvocationPlugin(HotSpotSuitesProvider suites) { + this.suites = suites; + } + + public boolean apply(GraphBuilderContext builder, ResolvedJavaMethod method, ValueNode[] args) { + if (builder.parsingReplacement()) { + NodeIntrinsificationPhase intrins = suites.getNodeIntrinsification(); + NodeIntrinsic intrinsic = intrins.getIntrinsic(method); + if (intrinsic != null) { + Signature sig = method.getSignature(); + Kind returnKind = sig.getReturnKind(); + Stamp stamp = StampFactory.forKind(returnKind); + if (returnKind == Kind.Object) { + JavaType returnType = sig.getReturnType(method.getDeclaringClass()); + if (returnType instanceof ResolvedJavaType) { + stamp = StampFactory.declared((ResolvedJavaType) returnType); + } + } + + ValueNode res = intrins.createIntrinsicNode(Arrays.asList(args), stamp, method, builder.getGraph(), intrinsic); + res = builder.append(res); + if (res.getKind().getStackKind() != Kind.Void) { + builder.push(returnKind.getStackKind(), res); + } + return true; + } else if (intrins.isFoldable(method)) { + ResolvedJavaType[] parameterTypes = resolveJavaTypes(method.toParameterTypes(), method.getDeclaringClass()); + JavaConstant constant = intrins.tryFold(Arrays.asList(args), parameterTypes, method); + if (!COULD_NOT_FOLD.equals(constant)) { + if (constant != null) { + // Replace the invoke with the result of the call + ConstantNode res = builder.append(ConstantNode.forConstant(constant, suites.getMetaAccess())); + builder.push(res.getKind().getStackKind(), builder.append(res)); + } else { + // This must be a void invoke + assert method.getSignature().getReturnKind() == Kind.Void; + } + return true; + } + } + } + return false; + } +} diff -r 39315508f1b6 -r 69b7ad0a3fda graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInlineInvokePlugin.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInlineInvokePlugin.java Tue Mar 10 21:26:02 2015 +0100 @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2013, 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 com.oracle.graal.hotspot.meta; + +import static com.oracle.graal.compiler.common.GraalOptions.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.Node.*; +import com.oracle.graal.java.*; +import com.oracle.graal.java.GraphBuilderPlugin.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; + +final class HotSpotInlineInvokePlugin implements InlineInvokePlugin { + private final Replacements replacements; + private final HotSpotSuitesProvider suites; + + public HotSpotInlineInvokePlugin(HotSpotSuitesProvider suites, Replacements replacements) { + this.suites = suites; + this.replacements = replacements; + } + + public ResolvedJavaMethod getInlinedMethod(GraphBuilderContext builder, ResolvedJavaMethod method, ValueNode[] args, JavaType returnType) { + ResolvedJavaMethod subst = replacements.getMethodSubstitutionMethod(method); + if (subst != null) { + // Forced inlining of intrinsics + return subst; + } + if (builder.parsingReplacement()) { + if (suites.getNodeIntrinsification().getIntrinsic(method) != null) { + // @NodeIntrinsic methods are handled by HotSpotAnnotatedInvocationPlugin + return null; + } + // Force inlining when parsing replacements + return method; + } else { + assert suites.getNodeIntrinsification().getIntrinsic(method) == null : String.format("@%s method %s must only be called from within a replacement%n%s", + NodeIntrinsic.class.getSimpleName(), method.format("%h.%n"), builder); + if (InlineDuringParsing.getValue() && method.hasBytecodes() && method.getCode().length <= TrivialInliningSize.getValue() && builder.getDepth() < InlineDuringParsingMaxDepth.getValue()) { + return method; + } + } + return null; + } +} diff -r 39315508f1b6 -r 69b7ad0a3fda graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoadFieldPlugin.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoadFieldPlugin.java Tue Mar 10 21:26:02 2015 +0100 @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2015, 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 com.oracle.graal.hotspot.meta; + +import static com.oracle.graal.compiler.common.GraalOptions.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.java.*; +import com.oracle.graal.java.GraphBuilderPlugin.*; +import com.oracle.graal.nodes.*; + +final class HotSpotLoadFieldPlugin implements LoadFieldPlugin { + private final MetaAccessProvider metaAccess; + private final ConstantReflectionProvider constantReflection; + + public HotSpotLoadFieldPlugin(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection) { + this.metaAccess = metaAccess; + this.constantReflection = constantReflection; + } + + public boolean apply(GraphBuilderContext builder, ValueNode receiver, ResolvedJavaField field) { + if (InlineDuringParsing.getValue() || builder.parsingReplacement()) { + if (receiver.isConstant()) { + JavaConstant asJavaConstant = receiver.asJavaConstant(); + return tryConstantFold(builder, metaAccess, constantReflection, field, asJavaConstant); + } + } + return false; + } + + public boolean apply(GraphBuilderContext builder, ResolvedJavaField staticField) { + return tryConstantFold(builder, metaAccess, constantReflection, staticField, null); + } +} diff -r 39315508f1b6 -r 69b7ad0a3fda graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java Tue Mar 10 19:44:56 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java Tue Mar 10 21:26:02 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -22,25 +22,15 @@ */ package com.oracle.graal.hotspot.meta; -import static com.oracle.graal.api.meta.MetaUtil.*; import static com.oracle.graal.compiler.common.GraalOptions.*; -import static com.oracle.graal.replacements.NodeIntrinsificationPhase.*; - -import java.util.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.graph.Node.NodeIntrinsic; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.hotspot.phases.*; import com.oracle.graal.java.*; import com.oracle.graal.java.GraphBuilderConfiguration.DebugInfoMode; -import com.oracle.graal.java.GraphBuilderPlugin.AnnotatedInvocationPlugin; -import com.oracle.graal.java.GraphBuilderPlugin.InlineInvokePlugin; -import com.oracle.graal.java.GraphBuilderPlugin.LoadFieldPlugin; import com.oracle.graal.lir.phases.*; -import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.options.*; import com.oracle.graal.options.DerivedOptionValue.OptionSupplier; @@ -114,7 +104,7 @@ NodeIntrinsificationPhase intrinsifier; - NodeIntrinsificationPhase getIntrinsifier() { + NodeIntrinsificationPhase getNodeIntrinsification() { if (intrinsifier == null) { HotSpotProviders providers = runtime.getHostProviders(); intrinsifier = new NodeIntrinsificationPhase(providers, providers.getSnippetReflection()); @@ -129,78 +119,9 @@ protected PhaseSuite createGraphBuilderSuite(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, Replacements replacements) { PhaseSuite suite = new PhaseSuite<>(); GraphBuilderConfiguration config = GraphBuilderConfiguration.getDefault(); - if (InlineDuringParsing.getValue()) { - config.setLoadFieldPlugin(new LoadFieldPlugin() { - public boolean apply(GraphBuilderContext builder, ValueNode receiver, ResolvedJavaField field) { - if (receiver.isConstant()) { - JavaConstant asJavaConstant = receiver.asJavaConstant(); - return tryConstantFold(builder, metaAccess, constantReflection, field, asJavaConstant); - } - return false; - } - - public boolean apply(GraphBuilderContext builder, ResolvedJavaField staticField) { - return tryConstantFold(builder, metaAccess, constantReflection, staticField, null); - } - }); - config.setInlineInvokePlugin(new InlineInvokePlugin() { - public ResolvedJavaMethod getInlinedMethod(GraphBuilderContext builder, ResolvedJavaMethod method, ValueNode[] args, JavaType returnType, int depth) { - ResolvedJavaMethod subst = replacements.getMethodSubstitutionMethod(method); - if (subst != null) { - return subst; - } - if (builder.parsingReplacement() && method.getAnnotation(NodeIntrinsic.class) == null) { - return method; - } - if (method.hasBytecodes() && method.getCode().length <= TrivialInliningSize.getValue() && depth < InlineDuringParsingMaxDepth.getValue()) { - return method; - } - return null; - } - }); - config.setAnnotatedInvocationPlugin(new AnnotatedInvocationPlugin() { - public boolean apply(GraphBuilderContext builder, ResolvedJavaMethod method, ValueNode[] args) { - if (builder.parsingReplacement()) { - @SuppressWarnings("hiding") - NodeIntrinsificationPhase intrinsifier = getIntrinsifier(); - NodeIntrinsic intrinsic = intrinsifier.getIntrinsic(method); - if (intrinsic != null) { - Signature sig = method.getSignature(); - Kind returnKind = sig.getReturnKind(); - Stamp stamp = StampFactory.forKind(returnKind); - if (returnKind == Kind.Object) { - JavaType returnType = sig.getReturnType(method.getDeclaringClass()); - if (returnType instanceof ResolvedJavaType) { - stamp = StampFactory.declared((ResolvedJavaType) returnType); - } - } - - ValueNode res = intrinsifier.createIntrinsicNode(Arrays.asList(args), stamp, method, builder.getGraph(), intrinsic); - res = builder.append(res); - if (res.getKind().getStackKind() != Kind.Void) { - builder.push(returnKind.getStackKind(), res); - } - return true; - } else if (intrinsifier.isFoldable(method)) { - ResolvedJavaType[] parameterTypes = resolveJavaTypes(method.toParameterTypes(), method.getDeclaringClass()); - JavaConstant constant = intrinsifier.tryFold(Arrays.asList(args), parameterTypes, method); - if (!COULD_NOT_FOLD.equals(constant)) { - if (constant != null) { - // Replace the invoke with the result of the call - ConstantNode res = builder.append(ConstantNode.forConstant(constant, getMetaAccess())); - builder.push(res.getKind().getStackKind(), builder.append(res)); - } else { - // This must be a void invoke - assert method.getSignature().getReturnKind() == Kind.Void; - } - return true; - } - } - } - return false; - } - }); - } + config.setLoadFieldPlugin(new HotSpotLoadFieldPlugin(metaAccess, constantReflection)); + config.setInlineInvokePlugin(new HotSpotInlineInvokePlugin(this, replacements)); + config.setAnnotatedInvocationPlugin(new HotSpotAnnotatedInvocationPlugin(this)); suite.appendPhase(new GraphBuilderPhase(config)); return suite; } diff -r 39315508f1b6 -r 69b7ad0a3fda graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderContext.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderContext.java Tue Mar 10 19:44:56 2015 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderContext.java Tue Mar 10 21:26:02 2015 +0100 @@ -60,6 +60,16 @@ StructuredGraph getGraph(); /** + * Gets the parsing context for the method that inlines the method being parsed by this context. + */ + GraphBuilderContext getParent(); + + /** + * Gets the inline depth of this context. 0 implies this is the context for the root method. + */ + int getDepth(); + + /** * Determines if the graph builder is parsing a snippet or method substitution. */ boolean parsingReplacement(); diff -r 39315508f1b6 -r 69b7ad0a3fda graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Tue Mar 10 19:44:56 2015 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Tue Mar 10 21:26:02 2015 +0100 @@ -75,7 +75,7 @@ @Override protected void run(StructuredGraph graph, HighTierContext context) { - new Instance(context.getMetaAccess(), context.getStampProvider(), null, context.getConstantReflection(), graphBuilderConfig, context.getOptimisticOptimizations()).run(graph); + new Instance(context.getMetaAccess(), context.getStampProvider(), null, context.getConstantReflection(), graphBuilderConfig, context.getOptimisticOptimizations(), false).run(graph); } public GraphBuilderConfiguration getGraphBuilderConfig() { @@ -89,6 +89,7 @@ private final MetaAccessProvider metaAccess; private ResolvedJavaMethod rootMethod; + private final boolean rootMethodIsReplacement; private final GraphBuilderConfiguration graphBuilderConfig; private final OptimisticOptimizations optimisticOpts; @@ -104,19 +105,20 @@ } public Instance(MetaAccessProvider metaAccess, StampProvider stampProvider, SnippetReflectionProvider snippetReflectionProvider, ConstantReflectionProvider constantReflection, - GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts) { + GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts, boolean rootMethodIsReplacement) { this.graphBuilderConfig = graphBuilderConfig; this.optimisticOpts = optimisticOpts; this.metaAccess = metaAccess; this.stampProvider = stampProvider; this.constantReflection = constantReflection; this.snippetReflectionProvider = snippetReflectionProvider; + this.rootMethodIsReplacement = rootMethodIsReplacement; assert metaAccess != null; } public Instance(MetaAccessProvider metaAccess, StampProvider stampProvider, ConstantReflectionProvider constantReflection, GraphBuilderConfiguration graphBuilderConfig, - OptimisticOptimizations optimisticOpts) { - this(metaAccess, stampProvider, null, constantReflection, graphBuilderConfig, optimisticOpts); + OptimisticOptimizations optimisticOpts, boolean rootMethodIsReplacement) { + this(metaAccess, stampProvider, null, constantReflection, graphBuilderConfig, optimisticOpts, rootMethodIsReplacement); } @Override @@ -130,8 +132,8 @@ frameState.initializeForMethodStart(graphBuilderConfig.eagerResolving(), this.graphBuilderConfig.getParameterPlugin()); TTY.Filter filter = new TTY.Filter(PrintFilter.getValue(), method); try { - BytecodeParser parser = new BytecodeParser(metaAccess, method, graphBuilderConfig, optimisticOpts, entryBCI, false); - parser.build(0, graph.start(), frameState); + BytecodeParser parser = new BytecodeParser(null, metaAccess, method, graphBuilderConfig, optimisticOpts, entryBCI, rootMethodIsReplacement); + parser.build(graph.start(), frameState); parser.connectLoopEndToBegin(); @@ -187,7 +189,7 @@ private BciBlockMapping blockMap; private LocalLiveness liveness; protected final int entryBCI; - private int currentDepth; + private final BytecodeParser parent; private LineNumberTable lnt; private int previousLineNumber; @@ -218,10 +220,11 @@ * implements the semantics of another method (i.e., an intrinsic) or * bytecode instruction (i.e., a snippet) */ - public BytecodeParser(MetaAccessProvider metaAccess, ResolvedJavaMethod method, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts, int entryBCI, - boolean isReplacement) { + public BytecodeParser(BytecodeParser parent, MetaAccessProvider metaAccess, ResolvedJavaMethod method, GraphBuilderConfiguration graphBuilderConfig, + OptimisticOptimizations optimisticOpts, int entryBCI, boolean isReplacement) { super(metaAccess, method, graphBuilderConfig, optimisticOpts, isReplacement); this.entryBCI = entryBCI; + this.parent = parent; if (graphBuilderConfig.insertNonSafepointDebugInfo()) { lnt = method.getLineNumberTable(); @@ -261,8 +264,7 @@ return this.beforeUnwindNode; } - protected void build(int depth, FixedWithNextNode startInstruction, HIRFrameStateBuilder startFrameState) { - this.currentDepth = depth; + protected void build(FixedWithNextNode startInstruction, HIRFrameStateBuilder startFrameState) { if (PrintProfilingInformation.getValue() && profilingInfo != null) { TTY.println("Profiling info for " + method.format("%H.%n(%p)")); TTY.println(MetaUtil.indent(profilingInfo.toString(method, CodeUtil.NEW_LINE), " ")); @@ -1060,14 +1062,14 @@ if (tryInvocationPlugin(args, targetMethod, resultType)) { if (GraalOptions.TraceInlineDuringParsing.getValue()) { - TTY.println(format("%sUsed invocation plugin for %s", nSpaces(currentDepth), targetMethod)); + TTY.println(format("%sUsed invocation plugin for %s", nSpaces(getDepth()), targetMethod)); } return; } if (tryAnnotatedInvocationPlugin(args, targetMethod)) { if (GraalOptions.TraceInlineDuringParsing.getValue()) { - TTY.println(format("%sUsed annotated invocation plugin for %s", nSpaces(currentDepth), targetMethod)); + TTY.println(format("%sUsed annotated invocation plugin for %s", nSpaces(getDepth()), targetMethod)); } return; } @@ -1131,14 +1133,14 @@ if (plugin == null || !invokeKind.isDirect() || !targetMethod.canBeInlined()) { return false; } - ResolvedJavaMethod inlinedMethod = plugin.getInlinedMethod(this, targetMethod, args, returnType, currentDepth); - if (inlinedMethod != null && inlinedMethod.hasBytecodes()) { + ResolvedJavaMethod inlinedMethod = plugin.getInlinedMethod(this, targetMethod, args, returnType); + if (inlinedMethod != null) { if (TraceInlineDuringParsing.getValue()) { int bci = this.bci(); StackTraceElement ste = this.method.asStackTraceElement(bci); - TTY.println(format("%s%s (%s:%d) inlining call to %s", nSpaces(currentDepth), method.getName(), ste.getFileName(), ste.getLineNumber(), inlinedMethod.format("%h.%n(%p)"))); + TTY.println(format("%s%s (%s:%d) inlining call to %s", nSpaces(getDepth()), method.getName(), ste.getFileName(), ste.getLineNumber(), inlinedMethod.format("%h.%n(%p)"))); } - parseAndInlineCallee(inlinedMethod, args, parsingReplacement || !inlinedMethod.equals(targetMethod)); + parseAndInlineCallee(inlinedMethod, args, parsingReplacement || inlinedMethod != targetMethod); plugin.postInline(inlinedMethod); return true; } @@ -1147,7 +1149,7 @@ } private void parseAndInlineCallee(ResolvedJavaMethod targetMethod, ValueNode[] args, boolean isReplacement) { - BytecodeParser parser = new BytecodeParser(metaAccess, targetMethod, graphBuilderConfig, optimisticOpts, INVOCATION_ENTRY_BCI, isReplacement); + BytecodeParser parser = new BytecodeParser(this, metaAccess, targetMethod, graphBuilderConfig, optimisticOpts, INVOCATION_ENTRY_BCI, isReplacement); final FrameState[] lazyFrameState = new FrameState[1]; // Replacements often produce nodes with an illegal kind (e.g., pointer stamps) @@ -1162,7 +1164,7 @@ return lazyFrameState[0]; }); startFrameState.initializeFromArgumentsArray(args); - parser.build(currentDepth + 1, this.lastInstr, startFrameState); + parser.build(this.lastInstr, startFrameState); FixedWithNextNode calleeBeforeReturnNode = parser.getBeforeReturnNode(); this.lastInstr = calleeBeforeReturnNode; @@ -1207,7 +1209,7 @@ @Override protected void genReturn(ValueNode x) { - if (this.currentDepth == 0) { + if (parent == null) { frameState.setRethrowException(false); frameState.clearStack(); beforeReturn(x); @@ -1746,7 +1748,7 @@ } private void handleUnwindBlock() { - if (currentDepth == 0) { + if (parent == null) { frameState.setRethrowException(false); createUnwind(); } else { @@ -1926,7 +1928,7 @@ int opcode = stream.currentBC(); assert traceState(); assert traceInstruction(bci, opcode, bci == block.startBci); - if (currentDepth == 0 && bci == entryBCI) { + if (parent == null && bci == entryBCI) { if (block.getJsrScope() != JsrScope.EMPTY_SCOPE) { throw new BailoutException("OSR into a JSR scope is not supported"); } @@ -2099,7 +2101,7 @@ if (gotoOrFallThroughAfterConstant(trueBlock) && gotoOrFallThroughAfterConstant(falseBlock) && trueBlock.getSuccessor(0) == falseBlock.getSuccessor(0)) { genConditionalForIf(trueBlock, condition, oldBci, trueBlockInt, falseBlockInt, false); return true; - } else if (this.currentDepth != 0 && returnAfterConstant(trueBlock) && returnAfterConstant(falseBlock)) { + } else if (this.parent != null && returnAfterConstant(trueBlock) && returnAfterConstant(falseBlock)) { genConditionalForIf(trueBlock, condition, oldBci, trueBlockInt, falseBlockInt, true); return true; } @@ -2215,6 +2217,7 @@ } public StructuredGraph getGraph() { + return currentGraph; } @@ -2222,9 +2225,28 @@ return (GuardingNode) getFirstInstruction(currentBlock, getCurrentDimension()); } + public GraphBuilderContext getParent() { + return parent; + } + + public int getDepth() { + return parent == null ? 0 : 1 + parent.getDepth(); + } + @Override public String toString() { - return method.format("%H.%n(%p)@") + bci(); + Formatter fmt = new Formatter(); + BytecodeParser bp = this; + String indent = ""; + while (bp != null) { + if (bp != this) { + fmt.format("%n%s", indent); + } + fmt.format("%s replacement=%s", bp.method.asStackTraceElement(bp.bci()), parsingReplacement); + bp = bp.parent; + indent += " "; + } + return fmt.toString(); } public BailoutException bailout(String string) { diff -r 39315508f1b6 -r 69b7ad0a3fda graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPlugin.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPlugin.java Tue Mar 10 19:44:56 2015 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPlugin.java Tue Mar 10 21:26:02 2015 +0100 @@ -55,20 +55,27 @@ } /** - * Plugin for customizing how the graph builder handles a CHECKCAST instruction in the context - * of the instruction that consumes it from the stack. + * Plugin for specifying what is inlined during graph parsing. */ - public interface CheckCastPlugin extends GraphBuilderPlugin { - boolean apply(GraphBuilderContext builder, ResolvedJavaType type, ValueNode object, JavaTypeProfile profileForTypeCheck); - } + public interface InlineInvokePlugin extends GraphBuilderPlugin { - public interface InlineInvokePlugin extends GraphBuilderPlugin { + /** + * Gets the method to be inlined for a call to a given method. A non-null return value other + * than {@code method} is interpreted as a + * {@linkplain GraphBuilderContext#parsingReplacement() replacement} by the graph builder + * context used for inlining it. + * + * @param method the target method of an invoke + * @param args the arguments to the invoke + * @param returnType the return type derived from {@code method}'s signature + * @return the method to inline for a call to {@code method} or null if the call should not + * be inlined + */ + ResolvedJavaMethod getInlinedMethod(GraphBuilderContext builder, ResolvedJavaMethod method, ValueNode[] args, JavaType returnType); default void postInline(@SuppressWarnings("unused") ResolvedJavaMethod inlinedTargetMethod) { } - - ResolvedJavaMethod getInlinedMethod(GraphBuilderContext builder, ResolvedJavaMethod method, ValueNode[] args, JavaType returnType, int depth); } public interface LoopExplosionPlugin extends GraphBuilderPlugin { diff -r 39315508f1b6 -r 69b7ad0a3fda graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ReplacementsParseTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ReplacementsParseTest.java Tue Mar 10 19:44:56 2015 +0100 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ReplacementsParseTest.java Tue Mar 10 21:26:02 2015 +0100 @@ -63,7 +63,6 @@ @MethodSubstitution(isStatic = true) static double nextAfter(double x, double d) { double xx = (x == -0.0 ? 0.0 : x); - assert !Double.isNaN(xx); return Math.nextAfter(xx, d); } } diff -r 39315508f1b6 -r 69b7ad0a3fda graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Tue Mar 10 19:44:56 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Tue Mar 10 21:26:02 2015 +0100 @@ -113,12 +113,14 @@ } String originalName = originalName(substituteMethod, methodSubstitution.value()); JavaSignature originalSignature = originalSignature(substituteMethod, methodSubstitution.signature(), methodSubstitution.isStatic()); - Executable[] originalMethods = originalMethods(classSubstitution, methodSubstitution.optional(), originalName, originalSignature); - for (Executable originalMethod : originalMethods) { - if (originalMethod != null && (guard == null || guard.execute())) { - ResolvedJavaMethod original = registerMethodSubstitution(this, originalMethod, substituteMethod); - if (original != null && methodSubstitution.forced() && shouldIntrinsify(original)) { - forcedSubstitutions.add(original); + Executable[] originalMethods = originalMethods(classSubstitution, classSubstitution.optional(), originalName, originalSignature); + if (originalMethods != null) { + for (Executable originalMethod : originalMethods) { + if (originalMethod != null && (guard == null || guard.execute())) { + ResolvedJavaMethod original = registerMethodSubstitution(this, originalMethod, substituteMethod); + if (original != null && methodSubstitution.forced() && shouldIntrinsify(original)) { + forcedSubstitutions.add(original); + } } } } @@ -637,7 +639,7 @@ protected Instance createGraphBuilder(MetaAccessProvider metaAccess, StampProvider stampProvider, ConstantReflectionProvider constantReflection, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts) { - return new GraphBuilderPhase.Instance(metaAccess, stampProvider, constantReflection, graphBuilderConfig, optimisticOpts); + return new GraphBuilderPhase.Instance(metaAccess, stampProvider, constantReflection, graphBuilderConfig, optimisticOpts, true); } protected void afterParsing(StructuredGraph graph) { diff -r 39315508f1b6 -r 69b7ad0a3fda graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Tue Mar 10 19:44:56 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Tue Mar 10 21:26:02 2015 +0100 @@ -691,8 +691,6 @@ throw Debug.handle(e); } - // Remove all frame states from snippet graph. Snippets must be atomic (i.e. free - // of side-effects that prevent deoptimizing to a point before the snippet). ArrayList curSideEffectNodes = new ArrayList<>(); ArrayList curDeoptNodes = new ArrayList<>(); ArrayList curStampNodes = new ArrayList<>(); diff -r 39315508f1b6 -r 69b7ad0a3fda graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java Tue Mar 10 19:44:56 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java Tue Mar 10 21:26:02 2015 +0100 @@ -52,7 +52,7 @@ registerGraalDirectivesPlugins(metaAccess, plugins); } - public static void registerUnsafePlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { + private static void registerUnsafePlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { Registration r = new Registration(plugins, metaAccess, Unsafe.class); for (Kind kind : Kind.values()) { if ((kind.isPrimitive() && kind != Kind.Void) || kind == Kind.Object) { @@ -72,7 +72,7 @@ } } - public static void registerMathPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { + private static void registerMathPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { Registration r = new Registration(plugins, metaAccess, Math.class); r.register1("abs", Float.TYPE, new InvocationPlugin() { public boolean apply(GraphBuilderContext builder, ValueNode value) { @@ -101,7 +101,7 @@ } } - public static void registerObjectPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { + private static void registerObjectPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { Registration r = new Registration(plugins, metaAccess, Object.class); r.register1("", Receiver.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext builder, ValueNode object) { @@ -208,7 +208,7 @@ } } - public static void registerGraalDirectivesPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { + private static void registerGraalDirectivesPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { Registration r = new Registration(plugins, metaAccess, GraalDirectives.class); r.register0("deoptimize", new InvocationPlugin() { public boolean apply(GraphBuilderContext builder) { diff -r 39315508f1b6 -r 69b7ad0a3fda graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java --- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java Tue Mar 10 19:44:56 2015 +0100 +++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java Tue Mar 10 21:26:02 2015 +0100 @@ -192,7 +192,7 @@ LIRSuites lirSuites = suitesProvider.createLIRSuites(); removeInliningPhase(suites); StructuredGraph graph = new StructuredGraph(javaMethod, AllowAssumptions.NO); - new GraphBuilderPhase.Instance(metaAccess, providers.getStampProvider(), providers.getConstantReflection(), GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph); + new GraphBuilderPhase.Instance(metaAccess, providers.getStampProvider(), providers.getConstantReflection(), GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL, false).apply(graph); PhaseSuite graphBuilderSuite = getGraphBuilderSuite(suitesProvider); CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, graph.method(), false); Backend backend = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend(); diff -r 39315508f1b6 -r 69b7ad0a3fda graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Tue Mar 10 19:44:56 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Tue Mar 10 21:26:02 2015 +0100 @@ -195,7 +195,7 @@ this.replacements = replacements; } - public ResolvedJavaMethod getInlinedMethod(GraphBuilderContext builder, ResolvedJavaMethod original, ValueNode[] arguments, JavaType returnType, int depth) { + public ResolvedJavaMethod getInlinedMethod(GraphBuilderContext builder, ResolvedJavaMethod original, ValueNode[] arguments, JavaType returnType) { if (original.getAnnotation(TruffleBoundary.class) != null) { return null; } @@ -258,7 +258,8 @@ newConfig.setInlineInvokePlugin(new InlineInvokePlugin(callTarget.getInlining(), providers.getReplacements())); newConfig.setLoopExplosionPlugin(new LoopExplosionPlugin()); TruffleGraphBuilderPlugins.registerInvocationPlugins(providers.getMetaAccess(), newConfig.getInvocationPlugins()); - new GraphBuilderPhase.Instance(providers.getMetaAccess(), providers.getStampProvider(), this.snippetReflection, providers.getConstantReflection(), newConfig, TruffleCompilerImpl.Optimizations).apply(graph); + new GraphBuilderPhase.Instance(providers.getMetaAccess(), providers.getStampProvider(), this.snippetReflection, providers.getConstantReflection(), newConfig, + TruffleCompilerImpl.Optimizations, false).apply(graph); Debug.dump(graph, "After FastPE"); // Perform deoptimize to guard conversion. @@ -332,13 +333,13 @@ } public StructuredGraph createRootGraph(StructuredGraph graph) { - new GraphBuilderPhase.Instance(providers.getMetaAccess(), providers.getStampProvider(), providers.getConstantReflection(), configForRoot, TruffleCompilerImpl.Optimizations).apply(graph); + new GraphBuilderPhase.Instance(providers.getMetaAccess(), providers.getStampProvider(), providers.getConstantReflection(), configForRoot, TruffleCompilerImpl.Optimizations, false).apply(graph); return graph; } public StructuredGraph createInlineGraph(String name, StructuredGraph caller) { StructuredGraph graph = new StructuredGraph(name, callInlinedMethod, AllowAssumptions.from(caller.getAssumptions() != null)); - new GraphBuilderPhase.Instance(providers.getMetaAccess(), providers.getStampProvider(), providers.getConstantReflection(), configForRoot, TruffleCompilerImpl.Optimizations).apply(graph); + new GraphBuilderPhase.Instance(providers.getMetaAccess(), providers.getStampProvider(), providers.getConstantReflection(), configForRoot, TruffleCompilerImpl.Optimizations, false).apply(graph); return graph; } diff -r 39315508f1b6 -r 69b7ad0a3fda graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java Tue Mar 10 19:44:56 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java Tue Mar 10 21:26:02 2015 +0100 @@ -269,7 +269,7 @@ } protected StructuredGraph parseGraph(StructuredGraph graph, final PhaseContext phaseContext) { - new GraphBuilderPhase.Instance(phaseContext.getMetaAccess(), phaseContext.getStampProvider(), null, config, optimisticOptimizations).apply(graph); + new GraphBuilderPhase.Instance(phaseContext.getMetaAccess(), phaseContext.getStampProvider(), null, config, optimisticOptimizations, false).apply(graph); return graph; }