changeset 19767:69b7ad0a3fda

Merge.
author Doug Simon <doug.simon@oracle.com>
date Tue, 10 Mar 2015 21:26:02 +0100
parents 86f2cb32cd64 (diff) 39315508f1b6 (current diff)
children e968986402dc
files graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/BytecodeFrame.java graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/AbstractBlock.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EATestBase.java graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/TimerCloseable.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRFrameState.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMonitorValue.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CompositeValueClassSubstitutions.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 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionBase.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/CompilationConstantNode.java graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/internal/RewriteEvent.java
diffstat 18 files changed, 303 insertions(+), 140 deletions(-) [+]
line wrap: on
line diff
--- 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.
--- 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);
--- 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);
--- 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);
--- /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;
+    }
+}
--- /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;
+    }
+}
--- /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);
+    }
+}
--- 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<HighTierContext> createGraphBuilderSuite(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, Replacements replacements) {
         PhaseSuite<HighTierContext> 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;
     }
--- 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();
--- 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) {
--- 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 {
--- 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);
         }
     }
--- 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) {
--- 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<StateSplit> curSideEffectNodes = new ArrayList<>();
         ArrayList<DeoptimizingNode> curDeoptNodes = new ArrayList<>();
         ArrayList<ValueNode> curStampNodes = new ArrayList<>();
--- 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("<init>", 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) {
--- 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<HighTierContext> graphBuilderSuite = getGraphBuilderSuite(suitesProvider);
         CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, graph.method(), false);
         Backend backend = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend();
--- 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;
     }
 
--- 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;
     }