changeset 21341:3f31ab061d40

Merge LinearScan refactoring.
author Josef Eisl <josef.eisl@jku.at>
date Tue, 12 May 2015 14:27:35 +0200
parents dd013bfdccc3 (current diff) 710fc7216c56 (diff)
children 18042c0b9e88
files graal/com.oracle.graal.java/src/com/oracle/graal/java/ReplacementContext.java
diffstat 22 files changed, 213 insertions(+), 307 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderContext.java	Tue May 12 14:22:16 2015 +0200
+++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderContext.java	Tue May 12 14:27:35 2015 +0200
@@ -41,33 +41,30 @@
 public interface GraphBuilderContext {
 
     /**
-     * Information about a snippet or method substitution currently being processed by the graph
-     * builder. When in the scope of a replacement, the graph builder does not check the value kinds
-     * flowing through the JVM state since replacements can employ non-Java kinds to represent
-     * values such as raw machine words and pointers.
+     * An intrinsic is a substitute implementation of a Java method (or a bytecode in the case of
+     * snippets) that is itself implemented in Java. This interface provides information about the
+     * intrinsic currently being processed by the graph builder.
+     *
+     * When in the scope of an intrinsic, the graph builder does not check the value kinds flowing
+     * through the JVM state since intrinsics can employ non-Java kinds to represent values such as
+     * raw machine words and pointers.
      */
-    public interface Replacement {
+    public interface Intrinsic {
 
         /**
-         * Gets the method being replaced.
+         * Gets the method being intrinsified.
          */
         ResolvedJavaMethod getOriginalMethod();
 
         /**
-         * Gets the replacement method.
+         * Gets the method providing the intrinsic implementation.
          */
-        ResolvedJavaMethod getReplacementMethod();
+        ResolvedJavaMethod getIntrinsicMethod();
 
         /**
-         * 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();
-
-        /**
-         * Determines if a call within the compilation scope of this replacement represents a call
-         * to the {@linkplain #getOriginalMethod() original} method.
+         * Determines if a call within the compilation scope of this intrinsic represents a call to
+         * the {@linkplain #getOriginalMethod() original} method. This denotes the path where a
+         * partial intrinsification falls back to the original method.
          */
         boolean isCallToOriginal(ResolvedJavaMethod method);
     }
@@ -208,11 +205,11 @@
 
     /**
      * Gets the first ancestor parsing context that is not parsing a
-     * {@linkplain #parsingReplacement() replacement}.
+     * {@linkplain #parsingIntrinsic() intrinsic}.
      */
     default GraphBuilderContext getNonReplacementAncestor() {
         GraphBuilderContext ancestor = getParent();
-        while (ancestor != null && ancestor.parsingReplacement()) {
+        while (ancestor != null && ancestor.parsingIntrinsic()) {
             ancestor = ancestor.getParent();
         }
         return ancestor;
@@ -250,15 +247,15 @@
     /**
      * Determines if the current parsing context is a snippet or method substitution.
      */
-    default boolean parsingReplacement() {
-        return getReplacement() != null;
+    default boolean parsingIntrinsic() {
+        return getIntrinsic() != null;
     }
 
     /**
-     * Gets the replacement of the current parsing context or {@code null} if not
-     * {@link #parsingReplacement() parsing a replacement}.
+     * Gets the intrinsic of the current parsing context or {@code null} if not
+     * {@link #parsingIntrinsic() parsing an intrinsic}.
      */
-    Replacement getReplacement();
+    Intrinsic getIntrinsic();
 
     BailoutException bailout(String string);
 
--- a/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InlineInvokePlugin.java	Tue May 12 14:22:16 2015 +0200
+++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InlineInvokePlugin.java	Tue May 12 14:27:35 2015 +0200
@@ -40,22 +40,14 @@
         public final ResolvedJavaMethod methodToInline;
 
         /**
-         * Specifies if {@link #methodToInline} is to be considered a
-         * {@linkplain GraphBuilderContext.Replacement replacement} for the {@code method} passed to
-         * {@link InlineInvokePlugin#getInlineInfo}.
-         */
-        public final boolean isReplacement;
-
-        /**
-         * Specifies if {@link #methodToInline} is an intrinsic for the original method.
+         * Specifies if {@link #methodToInline} is an intrinsic for the original method (i.e., the
+         * {@code method} passed to {@link InlineInvokePlugin#getInlineInfo}).
          */
         public final boolean isIntrinsic;
 
-        public InlineInfo(ResolvedJavaMethod methodToInline, boolean isReplacement, boolean isIntrinsic) {
+        public InlineInfo(ResolvedJavaMethod methodToInline, boolean isIntrinsic) {
             this.methodToInline = methodToInline;
             this.isIntrinsic = isIntrinsic;
-            this.isReplacement = isReplacement;
-            assert !isIntrinsic || isReplacement : "cannot be an intrinsic without also being a replacement";
         }
     }
 
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotCryptoSubstitutionTest.java	Tue May 12 14:22:16 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotCryptoSubstitutionTest.java	Tue May 12 14:27:35 2015 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.hotspot.test;
 
-import static com.oracle.graal.java.IntrinsicContext.*;
+import static com.oracle.graal.java.IntrinsicContext.CompilationContext.*;
 
 import java.io.*;
 import java.lang.reflect.*;
@@ -132,7 +132,7 @@
                     StructuredGraph graph = new StructuredGraph(substMethod, AllowAssumptions.YES);
                     Plugins plugins = new Plugins(((HotSpotProviders) getProviders()).getGraphBuilderPlugins());
                     GraphBuilderConfiguration config = GraphBuilderConfiguration.getSnippetDefault(plugins);
-                    IntrinsicContext initialReplacementContext = new IntrinsicContext(installedCodeOwner, substMethod, ROOT_COMPILATION_BCI);
+                    IntrinsicContext initialReplacementContext = new IntrinsicContext(installedCodeOwner, substMethod, ROOT_COMPILATION);
                     new GraphBuilderPhase.Instance(getMetaAccess(), getProviders().getStampProvider(), getConstantReflection(), config, OptimisticOptimizations.NONE, initialReplacementContext).apply(graph);
                     Assert.assertNotNull(getCode(installedCodeOwner, graph, true));
                     atLeastOneCompiled = true;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoadFieldPlugin.java	Tue May 12 14:22:16 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoadFieldPlugin.java	Tue May 12 14:27:35 2015 +0200
@@ -41,7 +41,7 @@
     static final ThreadLocal<Boolean> FieldReadEnabledInImmutableCode = new ThreadLocal<>();
 
     public boolean apply(GraphBuilderContext b, ValueNode receiver, ResolvedJavaField field) {
-        if (!ImmutableCode.getValue() || b.parsingReplacement()) {
+        if (!ImmutableCode.getValue() || b.parsingIntrinsic()) {
             if (receiver.isConstant()) {
                 JavaConstant asJavaConstant = receiver.asJavaConstant();
                 return tryReadField(b, field, asJavaConstant);
@@ -64,10 +64,10 @@
     }
 
     public boolean apply(GraphBuilderContext b, ResolvedJavaField staticField) {
-        if (!ImmutableCode.getValue() || b.parsingReplacement()) {
+        if (!ImmutableCode.getValue() || b.parsingIntrinsic()) {
             // Javac does not allow use of "$assertionsDisabled" for a field name but
             // Eclipse does in which case a suffix is added to the generated field.
-            if (b.parsingReplacement() && staticField.isSynthetic() && staticField.getName().startsWith("$assertionsDisabled")) {
+            if (b.parsingIntrinsic() && staticField.isSynthetic() && staticField.getName().startsWith("$assertionsDisabled")) {
                 // For methods called indirectly from intrinsics, we (silently) disable
                 // assertions so that the parser won't see calls to the AssertionError
                 // constructor (all Invokes must be removed from intrinsics - see
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoadIndexedPlugin.java	Tue May 12 14:22:16 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoadIndexedPlugin.java	Tue May 12 14:27:35 2015 +0200
@@ -40,7 +40,7 @@
     }
 
     public boolean apply(GraphBuilderContext b, ValueNode array, ValueNode index, Kind elementKind) {
-        if (b.parsingReplacement()) {
+        if (b.parsingIntrinsic()) {
             ResolvedJavaType arrayType = StampTool.typeOrNull(array);
             /*
              * There are cases where the array does not have a known type yet, i.e., the type is
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotParameterPlugin.java	Tue May 12 14:22:16 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotParameterPlugin.java	Tue May 12 14:27:35 2015 +0200
@@ -38,7 +38,7 @@
     }
 
     public FloatingNode interceptParameter(GraphBuilderContext b, int index, Stamp stamp) {
-        if (b.parsingReplacement()) {
+        if (b.parsingIntrinsic()) {
             ResolvedJavaType type = StampTool.typeOrNull(stamp);
             if (wordTypes.isWord(type)) {
                 return new ParameterNode(index, wordTypes.getWordStamp(type));
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java	Tue May 12 14:22:16 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java	Tue May 12 14:27:35 2015 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.hotspot.stubs;
 
-import static com.oracle.graal.java.IntrinsicContext.*;
+import static com.oracle.graal.java.IntrinsicContext.CompilationContext.*;
 
 import java.lang.reflect.*;
 
@@ -96,8 +96,8 @@
 
         assert SnippetGraphUnderConstruction.get() == null;
         SnippetGraphUnderConstruction.set(graph);
-        ReplacementContext initialReplacementContext = new IntrinsicContext(method, method, POST_PARSE_INLINE_BCI);
-        new GraphBuilderPhase.Instance(metaAccess, providers.getStampProvider(), providers.getConstantReflection(), config, OptimisticOptimizations.NONE, initialReplacementContext).apply(graph);
+        IntrinsicContext initialIntrinsicContext = new IntrinsicContext(method, method, INLINE_AFTER_PARSING);
+        new GraphBuilderPhase.Instance(metaAccess, providers.getStampProvider(), providers.getConstantReflection(), config, OptimisticOptimizations.NONE, initialIntrinsicContext).apply(graph);
         SnippetGraphUnderConstruction.set(null);
 
         graph.setGuardsStage(GuardsStage.FLOATING_GUARDS);
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java	Tue May 12 14:22:16 2015 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java	Tue May 12 14:27:35 2015 +0200
@@ -102,7 +102,7 @@
     protected final ConstantPool constantPool;
     protected final MetaAccessProvider metaAccess;
 
-    protected final ReplacementContext replacementContext;
+    protected final IntrinsicContext intrinsicContext;
 
     /**
      * Meters the number of actual bytecodes parsed.
@@ -110,7 +110,7 @@
     public static final DebugMetric BytecodesParsed = Debug.metric("BytecodesParsed");
 
     public AbstractBytecodeParser(MetaAccessProvider metaAccess, ResolvedJavaMethod method, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts,
-                    ReplacementContext replacementContext) {
+                    IntrinsicContext intrinsicContext) {
         this.graphBuilderConfig = graphBuilderConfig;
         this.optimisticOpts = optimisticOpts;
         this.metaAccess = metaAccess;
@@ -118,7 +118,7 @@
         this.profilingInfo = (graphBuilderConfig.getUseProfiling() ? method.getProfilingInfo() : null);
         this.constantPool = method.getConstantPool();
         this.method = method;
-        this.replacementContext = replacementContext;
+        this.intrinsicContext = intrinsicContext;
         assert metaAccess != null;
     }
 
@@ -143,7 +143,7 @@
         if (kind == Kind.Object) {
             value = frameState.xpop();
             // astore and astore_<n> may be used to store a returnAddress (jsr)
-            assert parsingReplacement() || (value.getKind() == Kind.Object || value.getKind() == Kind.Int) : value + ":" + value.getKind();
+            assert parsingIntrinsic() || (value.getKind() == Kind.Object || value.getKind() == Kind.Int) : value + ":" + value.getKind();
         } else {
             value = frameState.pop(kind);
         }
@@ -587,13 +587,13 @@
     }
 
     private void maybeEagerlyResolve(int cpi, int bytecode) {
-        if (graphBuilderConfig.eagerResolving() || replacementContext instanceof IntrinsicContext) {
+        if (graphBuilderConfig.eagerResolving() || intrinsicContext != null) {
             constantPool.loadReferencedType(cpi, bytecode);
         }
     }
 
     private JavaTypeProfile getProfileForTypeCheck(ResolvedJavaType type) {
-        if (parsingReplacement() || profilingInfo == null || !optimisticOpts.useTypeCheckHints() || !canHaveSubtype(type)) {
+        if (parsingIntrinsic() || profilingInfo == null || !optimisticOpts.useTypeCheckHints() || !canHaveSubtype(type)) {
             return null;
         } else {
             return profilingInfo.getTypeProfile(bci());
@@ -1254,7 +1254,7 @@
         Debug.log("%s", sb);
     }
 
-    public boolean parsingReplacement() {
-        return replacementContext != null;
+    public boolean parsingIntrinsic() {
+        return intrinsicContext != null;
     }
 }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractFrameStateBuilder.java	Tue May 12 14:22:16 2015 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractFrameStateBuilder.java	Tue May 12 14:27:35 2015 +0200
@@ -176,8 +176,8 @@
     public T loadLocal(int i) {
         T x = locals[i];
         assert x != null : i;
-        assert parser.parsingReplacement() || (x.getKind().getSlotCount() == 1 || locals[i + 1] == null);
-        assert parser.parsingReplacement() || (i == 0 || locals[i - 1] == null || locals[i - 1].getKind().getSlotCount() == 1);
+        assert parser.parsingIntrinsic() || (x.getKind().getSlotCount() == 1 || locals[i + 1] == null);
+        assert parser.parsingIntrinsic() || (i == 0 || locals[i - 1] == null || locals[i - 1].getKind().getSlotCount() == 1);
         return x;
     }
 
@@ -193,14 +193,14 @@
      * @param x the instruction which produces the value for the local
      */
     public void storeLocal(int i, T x, Kind kind) {
-        assert x == null || parser.parsingReplacement() || (x.getKind() != Kind.Void && x.getKind() != Kind.Illegal) : "unexpected value: " + x;
+        assert x == null || parser.parsingIntrinsic() || (x.getKind() != Kind.Void && x.getKind() != Kind.Illegal) : "unexpected value: " + x;
         locals[i] = x;
         if (x != null) {
-            if (kind.needsTwoSlots() && !parser.parsingReplacement()) {
+            if (kind.needsTwoSlots() && !parser.parsingIntrinsic()) {
                 // if this is a double word, then kill i+1
                 locals[i + 1] = null;
             }
-            if (i > 0 && !parser.parsingReplacement()) {
+            if (i > 0 && !parser.parsingIntrinsic()) {
                 T p = locals[i - 1];
                 if (p != null && p.getKind().needsTwoSlots()) {
                     // if there was a double word at i - 1, then kill it
@@ -235,7 +235,7 @@
      * @param x the instruction to push onto the stack
      */
     public void xpush(T x) {
-        assert parser.parsingReplacement() || (x == null || (x.getKind() != Kind.Void && x.getKind() != Kind.Illegal));
+        assert parser.parsingIntrinsic() || (x == null || (x.getKind() != Kind.Void && x.getKind() != Kind.Illegal));
         stack[stackSize++] = x;
     }
 
@@ -379,7 +379,7 @@
                 newStackSize--;
                 assert stack[newStackSize].getKind().needsTwoSlots();
             } else {
-                assert parser.parsingReplacement() || (stack[newStackSize].getKind().getSlotCount() == 1);
+                assert parser.parsingIntrinsic() || (stack[newStackSize].getKind().getSlotCount() == 1);
             }
             result[i] = stack[newStackSize];
         }
@@ -415,7 +415,7 @@
     }
 
     private T assertKind(Kind kind, T x) {
-        assert x != null && (parser.parsingReplacement() || x.getKind() == kind) : "kind=" + kind + ", value=" + x + ((x == null) ? "" : ", value.kind=" + x.getKind());
+        assert x != null && (parser.parsingIntrinsic() || x.getKind() == kind) : "kind=" + kind + ", value=" + x + ((x == null) ? "" : ", value.kind=" + x.getKind());
         return x;
     }
 
@@ -435,7 +435,7 @@
     }
 
     private T assertObject(T x) {
-        assert x != null && (parser.parsingReplacement() || (x.getKind() == Kind.Object));
+        assert x != null && (parser.parsingIntrinsic() || (x.getKind() == Kind.Object));
         return x;
     }
 
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Tue May 12 14:22:16 2015 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Tue May 12 14:27:35 2015 +0200
@@ -29,6 +29,7 @@
 import static com.oracle.graal.compiler.common.GraalOptions.*;
 import static com.oracle.graal.compiler.common.type.StampFactory.*;
 import static com.oracle.graal.java.AbstractBytecodeParser.Options.*;
+import static com.oracle.graal.java.IntrinsicContext.CompilationContext.*;
 import static com.oracle.graal.nodes.StructuredGraph.*;
 import static com.oracle.graal.nodes.type.StampTool.*;
 import static java.lang.String.*;
@@ -85,19 +86,19 @@
         return graphBuilderConfig;
     }
 
-    static class ReplacementScope implements AutoCloseable {
+    static class IntrinsicScope implements AutoCloseable {
         FrameState stateBefore;
         final Mark mark;
         final BytecodeParser parser;
 
-        static ReplacementScope create(boolean enteringReplacement, BytecodeParser parser, HIRFrameStateBuilder currentFrameState, ValueNode[] args) {
-            if (enteringReplacement) {
-                return new ReplacementScope(parser, currentFrameState, args);
+        static IntrinsicScope create(boolean enteringIntrinsic, BytecodeParser parser, HIRFrameStateBuilder currentFrameState, ValueNode[] args) {
+            if (enteringIntrinsic) {
+                return new IntrinsicScope(parser, currentFrameState, args);
             }
             return null;
         }
 
-        public ReplacementScope(BytecodeParser parser, HIRFrameStateBuilder currentFrameState, ValueNode[] args) {
+        public IntrinsicScope(BytecodeParser parser, HIRFrameStateBuilder currentFrameState, ValueNode[] args) {
             this.parser = parser;
             if (args == null) {
                 assert parser.parent == null;
@@ -117,7 +118,7 @@
         }
 
         public void close() {
-            IntrinsicContext intrinsic = (IntrinsicContext) parser.replacementContext;
+            IntrinsicContext intrinsic = parser.intrinsicContext;
             if (intrinsic != null && intrinsic.isPostParseInlined()) {
                 return;
             }
@@ -173,7 +174,7 @@
 
         private final MetaAccessProvider metaAccess;
 
-        private final ReplacementContext initialReplacementContext;
+        private final IntrinsicContext initialIntrinsicContext;
 
         private final GraphBuilderConfiguration graphBuilderConfig;
         private final OptimisticOptimizations optimisticOpts;
@@ -181,13 +182,13 @@
         private final ConstantReflectionProvider constantReflection;
 
         public Instance(MetaAccessProvider metaAccess, StampProvider stampProvider, ConstantReflectionProvider constantReflection, GraphBuilderConfiguration graphBuilderConfig,
-                        OptimisticOptimizations optimisticOpts, ReplacementContext initialReplacementContext) {
+                        OptimisticOptimizations optimisticOpts, IntrinsicContext initialIntrinsicContext) {
             this.graphBuilderConfig = graphBuilderConfig;
             this.optimisticOpts = optimisticOpts;
             this.metaAccess = metaAccess;
             this.stampProvider = stampProvider;
             this.constantReflection = constantReflection;
-            this.initialReplacementContext = initialReplacementContext;
+            this.initialIntrinsicContext = initialIntrinsicContext;
 
             assert metaAccess != null;
         }
@@ -200,13 +201,13 @@
             this.graph = graph;
             TTY.Filter filter = new TTY.Filter(PrintFilter.getValue(), method);
             try {
-                ReplacementContext replacementContext = initialReplacementContext;
-                BytecodeParser parser = new BytecodeParser(null, metaAccess, method, graphBuilderConfig, optimisticOpts, entryBCI, replacementContext);
+                IntrinsicContext intrinsicContext = initialIntrinsicContext;
+                BytecodeParser parser = new BytecodeParser(null, metaAccess, method, graphBuilderConfig, optimisticOpts, entryBCI, intrinsicContext);
                 HIRFrameStateBuilder frameState = new HIRFrameStateBuilder(parser, method, graph);
 
-                frameState.initializeForMethodStart(graphBuilderConfig.eagerResolving() || replacementContext != null, graphBuilderConfig.getPlugins().getParameterPlugin());
+                frameState.initializeForMethodStart(graphBuilderConfig.eagerResolving() || intrinsicContext != null, graphBuilderConfig.getPlugins().getParameterPlugin());
 
-                try (ReplacementScope rs = ReplacementScope.create(replacementContext != null, parser, frameState, null)) {
+                try (IntrinsicScope s = IntrinsicScope.create(intrinsicContext != null, parser, frameState, null)) {
                     parser.build(graph.start(), frameState);
                 }
                 GraphUtil.normalizeLoops(graph);
@@ -337,8 +338,8 @@
             private HIRFrameStateBuilder[][] entryStateMatrix;
 
             public BytecodeParser(BytecodeParser parent, MetaAccessProvider metaAccess, ResolvedJavaMethod method, GraphBuilderConfiguration graphBuilderConfig,
-                            OptimisticOptimizations optimisticOpts, int entryBCI, ReplacementContext replacementContext) {
-                super(metaAccess, method, graphBuilderConfig, optimisticOpts, replacementContext);
+                            OptimisticOptimizations optimisticOpts, int entryBCI, IntrinsicContext intrinsicContext) {
+                super(metaAccess, method, graphBuilderConfig, optimisticOpts, intrinsicContext);
                 this.entryBCI = entryBCI;
                 this.parent = parent;
 
@@ -411,10 +412,10 @@
                     if (startInstruction == graph.start()) {
                         StartNode startNode = graph.start();
                         if (method.isSynchronized()) {
-                            assert !parsingReplacement();
+                            assert !parsingIntrinsic();
                             startNode.setStateAfter(createFrameState(BytecodeFrame.BEFORE_BCI, startNode));
                         } else {
-                            if (!parsingReplacement()) {
+                            if (!parsingIntrinsic()) {
                                 if (graph.method() != null && graph.method().isJavaLangObjectInit()) {
                                     /*
                                      * Don't clear the receiver when Object.<init> is the
@@ -474,20 +475,20 @@
             }
 
             /**
-             * Creates the frame state after the start node of a graph for a
-             * {@link ReplacementContext replacement} that is the parse root (either for root
-             * compiling or for post-parse inlining).
+             * Creates the frame state after the start node of a graph for an
+             * {@link IntrinsicContext intrinsic} that is the parse root (either for root compiling
+             * or for post-parse inlining).
              */
             private FrameState createStateAfterStartOfReplacementGraph() {
                 assert parent == null;
-                assert frameState.method.equals(replacementContext.replacement);
+                assert frameState.method.equals(intrinsicContext.intrinsic);
                 assert bci() == 0;
                 assert frameState.stackSize == 0;
                 FrameState stateAfterStart;
-                if (replacementContext.isIntrinsic() && replacementContext.asIntrinsic().isPostParseInlined()) {
+                if (intrinsicContext.isPostParseInlined()) {
                     stateAfterStart = graph.add(new FrameState(BytecodeFrame.BEFORE_BCI));
                 } else {
-                    ResolvedJavaMethod original = replacementContext.method;
+                    ResolvedJavaMethod original = intrinsicContext.method;
                     ValueNode[] locals;
                     if (original.getMaxLocals() == frameState.localsSize() || original.isNative()) {
                         locals = frameState.locals;
@@ -541,7 +542,7 @@
                                 }
                                 LoopBeginNode loopBegin = (LoopBeginNode) ((EndNode) merge.next()).merge();
                                 LoopEndNode loopEnd = graph.add(new LoopEndNode(loopBegin));
-                                if (parsingReplacement()) {
+                                if (parsingIntrinsic()) {
                                     loopEnd.disableSafepoint();
                                 }
                                 endNode.replaceAndDelete(loopEnd);
@@ -1241,7 +1242,7 @@
                 }
 
                 JavaType returnType = targetMethod.getSignature().getReturnType(method.getDeclaringClass());
-                if (graphBuilderConfig.eagerResolving() || parsingReplacement()) {
+                if (graphBuilderConfig.eagerResolving() || parsingIntrinsic()) {
                     returnType = returnType.resolve(targetMethod.getDeclaringClass());
                 }
                 if (invokeKind.hasReceiver()) {
@@ -1368,9 +1369,8 @@
                 InvocationPlugin plugin = graphBuilderConfig.getPlugins().getInvocationPlugins().lookupInvocation(targetMethod);
                 if (plugin != null) {
 
-                    ReplacementContext context = this.replacementContext;
-                    if (context != null && context.isCallToOriginal(targetMethod)) {
-                        // Self recursive replacement means the original
+                    if (intrinsicContext != null && intrinsicContext.isCallToOriginal(targetMethod)) {
+                        // Self recursive intrinsic means the original
                         // method should be called.
                         assert !targetMethod.hasBytecodes() : "TODO: when does this happen?";
                         return false;
@@ -1393,74 +1393,56 @@
 
             private boolean tryInline(ValueNode[] args, ResolvedJavaMethod targetMethod, JavaType returnType) {
                 InlineInvokePlugin plugin = graphBuilderConfig.getPlugins().getInlineInvokePlugin();
-                boolean canBeInlined = parsingReplacement() || targetMethod.canBeInlined();
+                boolean canBeInlined = parsingIntrinsic() || targetMethod.canBeInlined();
                 if (plugin == null || !canBeInlined) {
                     return false;
                 }
                 InlineInfo inlineInfo = plugin.getInlineInfo(this, targetMethod, args, returnType);
                 if (inlineInfo != null) {
-                    return inline(plugin, targetMethod, inlineInfo.methodToInline, inlineInfo.isReplacement, inlineInfo.isIntrinsic, args);
+                    return inline(plugin, targetMethod, inlineInfo.methodToInline, inlineInfo.isIntrinsic, args);
                 }
                 return false;
             }
 
             public void intrinsify(ResolvedJavaMethod targetMethod, ResolvedJavaMethod substitute, ValueNode[] args) {
-                boolean res = inline(null, targetMethod, substitute, true, true, args);
+                boolean res = inline(null, targetMethod, substitute, true, args);
                 assert res : "failed to inline " + substitute;
             }
 
-            private boolean inline(InlineInvokePlugin plugin, ResolvedJavaMethod targetMethod, ResolvedJavaMethod inlinedMethod, boolean isReplacement, boolean isIntrinsic, ValueNode[] args) {
-                int bci = bci();
+            private boolean inline(InlineInvokePlugin plugin, ResolvedJavaMethod targetMethod, ResolvedJavaMethod inlinedMethod, boolean isIntrinsic, ValueNode[] args) {
                 if (TraceInlineDuringParsing.getValue() || TraceParserPlugins.getValue()) {
                     if (targetMethod.equals(inlinedMethod)) {
                         traceWithContext("inlining call to %s", inlinedMethod.format("%h.%n(%p)"));
                     } else {
-                        traceWithContext("inlining call to %s as replacement for %s", inlinedMethod.format("%h.%n(%p)"), targetMethod.format("%h.%n(%p)"));
+                        traceWithContext("inlining call to %s as intrinsic for %s", inlinedMethod.format("%h.%n(%p)"), targetMethod.format("%h.%n(%p)"));
                     }
                 }
-                ReplacementContext context = this.replacementContext;
-                if (context != null && context.isCallToOriginal(targetMethod)) {
-                    IntrinsicContext intrinsic = context.asIntrinsic();
-                    if (intrinsic != null) {
-                        if (intrinsic.isCompilationRoot()) {
-                            // A root compiled intrinsic needs to deoptimize
-                            // if the slow path is taken. During frame state
-                            // assignment, the deopt node will get its stateBefore
-                            // from the start node of the intrinsic
-                            append(new DeoptimizeNode(InvalidateRecompile, RuntimeConstraint));
-                            return true;
-                        } else {
-                            // Otherwise inline the original method. Any frame state created
-                            // during the inlining will exclude frame(s) in the
-                            // intrinsic method (see HIRFrameStateBuilder.create(int bci)).
-                            if (context.method.isNative()) {
-                                return false;
-                            }
-                            parseAndInlineCallee(context.method, args, null);
-                            return true;
-                        }
+                IntrinsicContext intrinsic = this.intrinsicContext;
+                if (intrinsic != null && intrinsic.isCallToOriginal(targetMethod)) {
+                    if (intrinsic.isCompilationRoot()) {
+                        // A root compiled intrinsic needs to deoptimize
+                        // if the slow path is taken. During frame state
+                        // assignment, the deopt node will get its stateBefore
+                        // from the start node of the intrinsic
+                        append(new DeoptimizeNode(InvalidateRecompile, RuntimeConstraint));
+                        return true;
                     } else {
-                        // Self recursive replacement means the original
-                        // method should be called.
-                        if (context.method.hasBytecodes()) {
-                            parseAndInlineCallee(context.method, args, null);
-                            return true;
-                        } else {
+                        // Otherwise inline the original method. Any frame state created
+                        // during the inlining will exclude frame(s) in the
+                        // intrinsic method (see HIRFrameStateBuilder.create(int bci)).
+                        if (intrinsic.method.isNative()) {
                             return false;
                         }
+                        parseAndInlineCallee(intrinsic.method, args, null);
+                        return true;
                     }
                 } else {
-                    if (context == null && isReplacement) {
+                    if (intrinsic == null && isIntrinsic) {
                         assert !inlinedMethod.equals(targetMethod);
-                        if (isIntrinsic) {
-                            context = new IntrinsicContext(targetMethod, inlinedMethod, bci);
-                        } else {
-                            assert false;
-                            context = new ReplacementContext(targetMethod, inlinedMethod);
-                        }
+                        intrinsic = new IntrinsicContext(targetMethod, inlinedMethod, INLINE_DURING_PARSING);
                     }
                     if (inlinedMethod.hasBytecodes()) {
-                        parseAndInlineCallee(inlinedMethod, args, context);
+                        parseAndInlineCallee(inlinedMethod, args, intrinsic);
                         if (plugin != null) {
                             plugin.postInline(inlinedMethod);
                         }
@@ -1504,10 +1486,10 @@
                 return res;
             }
 
-            private void parseAndInlineCallee(ResolvedJavaMethod targetMethod, ValueNode[] args, ReplacementContext calleeReplacementContext) {
-                try (ReplacementScope rs = ReplacementScope.create(calleeReplacementContext != null && !parsingReplacement(), this, frameState, args)) {
+            private void parseAndInlineCallee(ResolvedJavaMethod targetMethod, ValueNode[] args, IntrinsicContext calleeIntrinsicContext) {
+                try (IntrinsicScope s = IntrinsicScope.create(calleeIntrinsicContext != null && !parsingIntrinsic(), this, frameState, args)) {
 
-                    BytecodeParser parser = new BytecodeParser(this, metaAccess, targetMethod, graphBuilderConfig, optimisticOpts, INVOCATION_ENTRY_BCI, calleeReplacementContext);
+                    BytecodeParser parser = new BytecodeParser(this, metaAccess, targetMethod, graphBuilderConfig, optimisticOpts, INVOCATION_ENTRY_BCI, calleeIntrinsicContext);
                     HIRFrameStateBuilder startFrameState = new HIRFrameStateBuilder(parser, targetMethod, graph);
                     if (!targetMethod.isStatic()) {
                         args[0] = nullCheckedValue(args[0]);
@@ -1560,7 +1542,7 @@
 
             @Override
             protected void genReturn(ValueNode returnVal, Kind returnKind) {
-                if (parsingReplacement() && returnVal != null) {
+                if (parsingIntrinsic() && returnVal != null) {
                     if (returnVal instanceof StateSplit) {
                         StateSplit stateSplit = (StateSplit) returnVal;
                         FrameState stateAfter = stateSplit.stateAfter();
@@ -1947,7 +1929,7 @@
                      */
                     LoopBeginNode loopBegin = (LoopBeginNode) getFirstInstruction(block, operatingDimension);
                     LoopEndNode loopEnd = graph.add(new LoopEndNode(loopBegin));
-                    if (parsingReplacement()) {
+                    if (parsingIntrinsic()) {
                         loopEnd.disableSafepoint();
                     }
                     Target target = checkLoopExit(loopEnd, block, state);
@@ -2444,7 +2426,7 @@
                     FixedNode falseSuccessor = createTarget(falseBlock, frameState, false, true);
                     ValueNode ifNode = genIfNode(condition, trueSuccessor, falseSuccessor, probability);
                     append(ifNode);
-                    if (parsingReplacement()) {
+                    if (parsingIntrinsic()) {
                         if (x instanceof BranchProbabilityNode) {
                             ((BranchProbabilityNode) x).simplify(null);
                         } else if (y instanceof BranchProbabilityNode) {
@@ -2574,8 +2556,8 @@
                 return parent;
             }
 
-            public Replacement getReplacement() {
-                return replacementContext;
+            public Intrinsic getIntrinsic() {
+                return intrinsicContext;
             }
 
             @Override
@@ -2587,7 +2569,7 @@
                     if (bp != this) {
                         fmt.format("%n%s", indent);
                     }
-                    fmt.format("%s [bci: %d, replacement: %s]", bp.method.asStackTraceElement(bp.bci()), bp.bci(), bp.parsingReplacement());
+                    fmt.format("%s [bci: %d, intrinsic: %s]", bp.method.asStackTraceElement(bp.bci()), bp.bci(), bp.parsingIntrinsic());
                     fmt.format("%n%s", new BytecodeDisassembler().disassemble(bp.method, bp.bci(), bp.bci() + 10));
                     bp = bp.parent;
                     indent += " ";
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/HIRFrameStateBuilder.java	Tue May 12 14:22:16 2015 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/HIRFrameStateBuilder.java	Tue May 12 14:27:35 2015 +0200
@@ -201,11 +201,8 @@
     }
 
     public FrameState create(int bci, StateSplit forStateSplit) {
-        if (parser.parsingReplacement()) {
-            IntrinsicContext intrinsic = parser.replacementContext.asIntrinsic();
-            if (intrinsic != null) {
-                return intrinsic.createFrameState(parser.getGraph(), this, forStateSplit);
-            }
+        if (parser.parsingIntrinsic()) {
+            return parser.intrinsicContext.createFrameState(parser.getGraph(), this, forStateSplit);
         }
 
         // Skip intrinsic frames
@@ -223,7 +220,6 @@
         }
         if (bci == BytecodeFrame.INVALID_FRAMESTATE_BCI) {
             throw GraalInternalError.shouldNotReachHere();
-            // return graph.add(new FrameState(bci));
         }
         return graph.add(new FrameState(outerFrameState, method, bci, locals, stack, stackSize, lockedObjects, Arrays.asList(monitorIds), rethrowException, duringCall));
     }
@@ -231,18 +227,12 @@
     public BytecodePosition createBytecodePosition(int bci) {
         BytecodeParser parent = parser.getParent();
         if (AbstractBytecodeParser.Options.HideSubstitutionStates.getValue()) {
-            if (parser.parsingReplacement()) {
-                IntrinsicContext intrinsic = parser.replacementContext.asIntrinsic();
-                if (intrinsic != null) {
-                    // Attribute to the method being replaced
-                    return new BytecodePosition(parent.getFrameState().createBytecodePosition(parent.bci()), intrinsic.method, -1);
-                }
+            if (parser.parsingIntrinsic()) {
+                // Attribute to the method being replaced
+                return new BytecodePosition(parent.getFrameState().createBytecodePosition(parent.bci()), parser.intrinsicContext.method, -1);
             }
-            // If this is the recursive call in a partial intrinsification
-            // the frame(s) of the intrinsic method are omitted
-            while (parent != null && parent.parsingReplacement() && parent.replacementContext.asIntrinsic() != null) {
-                parent = parent.getParent();
-            }
+            // Skip intrinsic frames
+            parent = (BytecodeParser) parser.getNonReplacementAncestor();
         }
         return create(null, bci, parent);
     }
@@ -612,8 +602,8 @@
 
     private boolean assertLoadLocal(int i, ValueNode x) {
         assert x != null : i;
-        assert parser.parsingReplacement() || (x.getKind().getSlotCount() == 1 || locals[i + 1] == null);
-        assert parser.parsingReplacement() || (i == 0 || locals[i - 1] == null || locals[i - 1].getKind().getSlotCount() == 1);
+        assert parser.parsingIntrinsic() || (x.getKind().getSlotCount() == 1 || locals[i + 1] == null);
+        assert parser.parsingIntrinsic() || (i == 0 || locals[i - 1] == null || locals[i - 1].getKind().getSlotCount() == 1);
         return true;
     }
 
@@ -632,11 +622,11 @@
         assert assertStoreLocal(x);
         locals[i] = x;
         if (x != null) {
-            if (kind.needsTwoSlots() && !parser.parsingReplacement()) {
+            if (kind.needsTwoSlots() && !parser.parsingIntrinsic()) {
                 // if this is a double word, then kill i+1
                 locals[i + 1] = null;
             }
-            if (i > 0 && !parser.parsingReplacement()) {
+            if (i > 0 && !parser.parsingIntrinsic()) {
                 ValueNode p = locals[i - 1];
                 if (p != null && p.getKind().needsTwoSlots()) {
                     // if there was a double word at i - 1, then kill it
@@ -647,7 +637,7 @@
     }
 
     private boolean assertStoreLocal(ValueNode x) {
-        assert x == null || parser.parsingReplacement() || (x.getKind() != Kind.Void && x.getKind() != Kind.Illegal) : "unexpected value: " + x;
+        assert x == null || parser.parsingIntrinsic() || (x.getKind() != Kind.Void && x.getKind() != Kind.Illegal) : "unexpected value: " + x;
         return true;
     }
 
@@ -676,8 +666,8 @@
     }
 
     private boolean assertPush(Kind kind, ValueNode x) {
-        assert parser.parsingReplacement() || (x.getKind() != Kind.Void && x.getKind() != Kind.Illegal);
-        assert x != null && (parser.parsingReplacement() || x.getKind() == kind);
+        assert parser.parsingIntrinsic() || (x.getKind() != Kind.Void && x.getKind() != Kind.Illegal);
+        assert x != null && (parser.parsingIntrinsic() || x.getKind() == kind);
         return true;
     }
 
@@ -692,7 +682,7 @@
     }
 
     private boolean assertXpush(ValueNode x) {
-        assert parser.parsingReplacement() || (x == null || (x.getKind() != Kind.Void && x.getKind() != Kind.Illegal));
+        assert parser.parsingIntrinsic() || (x == null || (x.getKind() != Kind.Void && x.getKind() != Kind.Illegal));
         return true;
     }
 
@@ -771,7 +761,7 @@
     private boolean assertPop(Kind kind) {
         assert kind != Kind.Void;
         ValueNode x = xpeek();
-        assert x != null && (parser.parsingReplacement() || x.getKind() == kind);
+        assert x != null && (parser.parsingIntrinsic() || x.getKind() == kind);
         return true;
     }
 
@@ -858,7 +848,7 @@
                 newStackSize--;
                 assert stack[newStackSize].getKind().needsTwoSlots();
             } else {
-                assert parser.parsingReplacement() || (stack[newStackSize].getKind().getSlotCount() == 1);
+                assert parser.parsingIntrinsic() || (stack[newStackSize].getKind().getSlotCount() == 1);
             }
             result[i] = stack[newStackSize];
         }
@@ -925,7 +915,7 @@
     }
 
     private boolean assertObject(ValueNode x) {
-        assert x != null && (parser.parsingReplacement() || (x.getKind() == Kind.Object));
+        assert x != null && (parser.parsingIntrinsic() || (x.getKind() == Kind.Object));
         return true;
     }
 
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/IntrinsicContext.java	Tue May 12 14:22:16 2015 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/IntrinsicContext.java	Tue May 12 14:27:35 2015 +0200
@@ -23,49 +23,76 @@
 package com.oracle.graal.java;
 
 import static com.oracle.graal.api.code.BytecodeFrame.*;
+import static com.oracle.graal.java.IntrinsicContext.CompilationContext.*;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graphbuilderconf.GraphBuilderContext.Intrinsic;
 import com.oracle.graal.nodes.*;
 
-/**
- * Context for a replacement being inlined as a compiler intrinsic.
- */
-public class IntrinsicContext extends ReplacementContext {
+public class IntrinsicContext implements Intrinsic {
+
+    /**
+     * The method being replaced.
+     */
+    final ResolvedJavaMethod method;
 
     /**
-     * BCI denoting an intrinsic is being parsed for inlining after the graph of the caller has been
-     * built.
+     * The intrinsic implementation method.
      */
-    public static final int POST_PARSE_INLINE_BCI = -1;
+    final ResolvedJavaMethod intrinsic;
+
+    public ResolvedJavaMethod getOriginalMethod() {
+        return method;
+    }
+
+    public ResolvedJavaMethod getIntrinsicMethod() {
+        return intrinsic;
+    }
 
     /**
-     * BCI denoting an intrinsic is the compilation root.
+     * Determines if a call within the compilation scope of a replacement represents a call to the
+     * original method.
      */
-    public static final int ROOT_COMPILATION_BCI = -2;
+    public boolean isCallToOriginal(ResolvedJavaMethod targetMethod) {
+        return method.equals(targetMethod) || intrinsic.equals(targetMethod);
+    }
 
-    /**
-     * The BCI of the intrinsified invocation, {@link #POST_PARSE_INLINE_BCI} or
-     * {@link #ROOT_COMPILATION_BCI}.
-     */
-    final int bci;
+    final CompilationContext compilationContext;
 
-    public IntrinsicContext(ResolvedJavaMethod method, ResolvedJavaMethod substitute, int bci) {
-        super(method, substitute);
-        this.bci = bci;
+    public IntrinsicContext(ResolvedJavaMethod method, ResolvedJavaMethod intrinsic, CompilationContext compilationContext) {
+        this.method = method;
+        this.intrinsic = intrinsic;
+        this.compilationContext = compilationContext;
         assert !isCompilationRoot() || method.hasBytecodes() : "Cannot root compile intrinsic for native or abstract method " + method.format("%H.%n(%p)");
     }
 
-    @Override
-    public boolean isIntrinsic() {
-        return true;
-    }
-
     public boolean isPostParseInlined() {
-        return bci == POST_PARSE_INLINE_BCI;
+        return compilationContext.equals(INLINE_AFTER_PARSING);
     }
 
     public boolean isCompilationRoot() {
-        return bci == ROOT_COMPILATION_BCI;
+        return compilationContext.equals(ROOT_COMPILATION);
+    }
+
+    /**
+     * Denotes the compilation context in which an intrinsic is being parsed.
+     */
+    public enum CompilationContext {
+        /**
+         * An intrinsic is being processed when parsing an invoke bytecode that calls the
+         * intrinsified method.
+         */
+        INLINE_DURING_PARSING,
+
+        /**
+         * An intrinsic is being processed when inlining an {@link Invoke} in an existing graph.
+         */
+        INLINE_AFTER_PARSING,
+
+        /**
+         * An intrinsic is the root of compilation.
+         */
+        ROOT_COMPILATION
     }
 
     public FrameState createFrameState(StructuredGraph graph, HIRFrameStateBuilder frameState, StateSplit forStateSplit) {
@@ -99,12 +126,7 @@
     }
 
     @Override
-    IntrinsicContext asIntrinsic() {
-        return this;
-    }
-
-    @Override
     public String toString() {
-        return "Intrinsic{original: " + method.format("%H.%n(%p)") + ", replacement: " + replacement.format("%H.%n(%p)") + ", bci: " + bci + "}";
+        return "Intrinsic{original: " + method.format("%H.%n(%p)") + ", intrinsic: " + intrinsic.format("%H.%n(%p)") + ", context: " + compilationContext + "}";
     }
 }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/ReplacementContext.java	Tue May 12 14:22:16 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-/*
- * 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.java;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.api.replacements.*;
-import com.oracle.graal.graphbuilderconf.GraphBuilderContext.Replacement;
-
-/**
- * Information about a substitute method being parsed in lieu of an original method. This can happen
- * when a call to a {@link MethodSubstitution} is encountered or the root of compilation is a
- * {@link MethodSubstitution} or a snippet.
- */
-public class ReplacementContext implements Replacement {
-    /**
-     * The method being replaced.
-     */
-    final ResolvedJavaMethod method;
-
-    /**
-     * The replacement method.
-     */
-    final ResolvedJavaMethod replacement;
-
-    public ReplacementContext(ResolvedJavaMethod method, ResolvedJavaMethod substitute) {
-        this.method = method;
-        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.
-     */
-    public boolean isCallToOriginal(ResolvedJavaMethod targetMethod) {
-        return method.equals(targetMethod) || replacement.equals(targetMethod);
-    }
-
-    IntrinsicContext asIntrinsic() {
-        return null;
-    }
-
-    @Override
-    public String toString() {
-        return "Replacement{original: " + method.format("%H.%n(%p)") + ", replacement: " + replacement.format("%H.%n(%p)") + "}";
-    }
-}
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultGenericInvocationPlugin.java	Tue May 12 14:22:16 2015 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultGenericInvocationPlugin.java	Tue May 12 14:27:35 2015 +0200
@@ -73,9 +73,9 @@
     }
 
     public boolean apply(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args) {
-        if (b.parsingReplacement() && wordOperationPlugin.apply(b, method, args)) {
+        if (b.parsingIntrinsic() && wordOperationPlugin.apply(b, method, args)) {
             return true;
-        } else if (b.parsingReplacement()) {
+        } else if (b.parsingIntrinsic()) {
             NodeIntrinsic intrinsic = nodeIntrinsification.getIntrinsic(method);
             if (intrinsic != null) {
                 Signature sig = method.getSignature();
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultInlineInvokePlugin.java	Tue May 12 14:22:16 2015 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultInlineInvokePlugin.java	Tue May 12 14:27:35 2015 +0200
@@ -40,7 +40,7 @@
         InlineInfo inlineInfo = replacements.getInlineInfo(b, method, args, returnType);
         if (inlineInfo == null) {
             if (InlineDuringParsing.getValue() && method.hasBytecodes() && method.getCode().length <= TrivialInliningSize.getValue() && b.getDepth() < InlineDuringParsingMaxDepth.getValue()) {
-                return new InlineInfo(method, false, false);
+                return new InlineInfo(method, false);
             }
         }
         return inlineInfo;
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraphKit.java	Tue May 12 14:22:16 2015 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraphKit.java	Tue May 12 14:27:35 2015 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.replacements;
 
+import static com.oracle.graal.java.IntrinsicContext.CompilationContext.*;
+
 import java.lang.reflect.*;
 import java.util.*;
 
@@ -219,7 +221,7 @@
         GraphBuilderConfiguration config = GraphBuilderConfiguration.getSnippetDefault(plugins);
 
         StructuredGraph calleeGraph = new StructuredGraph(method, AllowAssumptions.NO);
-        IntrinsicContext initialReplacementContext = new IntrinsicContext(method, method, IntrinsicContext.POST_PARSE_INLINE_BCI);
+        IntrinsicContext initialReplacementContext = new IntrinsicContext(method, method, INLINE_AFTER_PARSING);
         new GraphBuilderPhase.Instance(metaAccess, providers.getStampProvider(), providers.getConstantReflection(), config, OptimisticOptimizations.NONE, initialReplacementContext).apply(calleeGraph);
 
         // Remove all frame states from inlinee
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/IntrinsicGraphBuilder.java	Tue May 12 14:22:16 2015 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/IntrinsicGraphBuilder.java	Tue May 12 14:27:35 2015 +0200
@@ -182,11 +182,11 @@
         return 0;
     }
 
-    public boolean parsingReplacement() {
+    public boolean parsingIntrinsic() {
         return true;
     }
 
-    public Replacement getReplacement() {
+    public Intrinsic getIntrinsic() {
         throw GraalInternalError.shouldNotReachHere();
     }
 
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/PEGraphDecoder.java	Tue May 12 14:22:16 2015 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/PEGraphDecoder.java	Tue May 12 14:27:35 2015 +0200
@@ -148,7 +148,7 @@
         }
 
         @Override
-        public Replacement getReplacement() {
+        public Intrinsic getIntrinsic() {
             return null;
         }
 
@@ -421,7 +421,7 @@
         if (inlineInfo == null) {
             return false;
         }
-        assert !inlineInfo.isIntrinsic && !inlineInfo.isReplacement : "not supported";
+        assert !inlineInfo.isIntrinsic : "not supported";
 
         ResolvedJavaMethod inlineMethod = inlineInfo.methodToInline;
         EncodedGraph graphToInline = lookupEncodedGraph(inlineMethod);
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Tue May 12 14:22:16 2015 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Tue May 12 14:27:35 2015 +0200
@@ -25,7 +25,7 @@
 import static com.oracle.graal.api.meta.MetaUtil.*;
 import static com.oracle.graal.compiler.common.GraalOptions.*;
 import static com.oracle.graal.java.AbstractBytecodeParser.Options.*;
-import static com.oracle.graal.java.IntrinsicContext.*;
+import static com.oracle.graal.java.IntrinsicContext.CompilationContext.*;
 import static com.oracle.graal.phases.common.DeadCodeEliminationPhase.Optionality.*;
 import static java.lang.String.*;
 
@@ -46,7 +46,7 @@
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.graphbuilderconf.*;
 import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.Plugins;
-import com.oracle.graal.graphbuilderconf.GraphBuilderContext.Replacement;
+import com.oracle.graal.graphbuilderconf.GraphBuilderContext.Intrinsic;
 import com.oracle.graal.java.*;
 import com.oracle.graal.java.GraphBuilderPhase.Instance;
 import com.oracle.graal.nodes.*;
@@ -94,13 +94,13 @@
     public InlineInfo getInlineInfo(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args, JavaType returnType) {
         ResolvedJavaMethod subst = getSubstitutionMethod(method);
         if (subst != null) {
-            if (b.parsingReplacement() || InlineDuringParsing.getValue() || InlineIntrinsicsDuringParsing.getValue()) {
+            if (b.parsingIntrinsic() || InlineDuringParsing.getValue() || InlineIntrinsicsDuringParsing.getValue()) {
                 // Forced inlining of intrinsics
-                return new InlineInfo(subst, true, true);
+                return new InlineInfo(subst, true);
             }
             return null;
         }
-        if (b.parsingReplacement()) {
+        if (b.parsingIntrinsic()) {
             assert !hasGenericInvocationPluginAnnotation(method) : format("%s should have been handled by %s", method.format("%H.%n(%p)"), DefaultGenericInvocationPlugin.class.getName());
 
             assert b.getDepth() < MAX_GRAPH_INLINING_DEPTH : "inlining limit exceeded";
@@ -111,7 +111,7 @@
             }
 
             // Force inlining when parsing replacements
-            return new InlineInfo(method, true, true);
+            return new InlineInfo(method, true);
         } else {
             assert method.getAnnotation(NodeIntrinsic.class) == null : String.format("@%s method %s must only be called from within a replacement%n%s", NodeIntrinsic.class.getSimpleName(),
                             method.format("%h.%n"), b);
@@ -120,10 +120,10 @@
     }
 
     public void notifyOfNoninlinedInvoke(GraphBuilderContext b, ResolvedJavaMethod method, Invoke invoke) {
-        if (b.parsingReplacement()) {
-            Replacement replacement = b.getReplacement();
-            assert replacement.isCallToOriginal(method) : format("All non-recursive 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)"));
+        if (b.parsingIntrinsic()) {
+            Intrinsic intrinsic = b.getIntrinsic();
+            assert intrinsic.isCallToOriginal(method) : format("All non-recursive calls in the intrinsic %s must be inlined or intrinsified: found call to %s",
+                            intrinsic.getIntrinsicMethod().format("%H.%n(%p)"), method.format("%h.%n(%p)"));
         }
     }
 
@@ -595,17 +595,16 @@
 
         protected Instance createGraphBuilder(MetaAccessProvider metaAccess, StampProvider stampProvider, ConstantReflectionProvider constantReflection, GraphBuilderConfiguration graphBuilderConfig,
                         OptimisticOptimizations optimisticOpts) {
-            ReplacementContext initialReplacementContext = null;
+            IntrinsicContext initialIntrinsicContext = null;
             if (method.getAnnotation(Snippet.class) == null) {
                 // Post-parse inlined intrinsic
-                initialReplacementContext = new IntrinsicContext(substitutedMethod, method, POST_PARSE_INLINE_BCI);
+                initialIntrinsicContext = new IntrinsicContext(substitutedMethod, method, INLINE_AFTER_PARSING);
             } else {
                 // Snippet
                 ResolvedJavaMethod original = substitutedMethod != null ? substitutedMethod : method;
-                // initialReplacementContext = new ReplacementContext(original, method);
-                initialReplacementContext = new IntrinsicContext(original, method, POST_PARSE_INLINE_BCI);
+                initialIntrinsicContext = new IntrinsicContext(original, method, INLINE_AFTER_PARSING);
             }
-            return new GraphBuilderPhase.Instance(metaAccess, stampProvider, constantReflection, graphBuilderConfig, optimisticOpts, initialReplacementContext);
+            return new GraphBuilderPhase.Instance(metaAccess, stampProvider, constantReflection, graphBuilderConfig, optimisticOpts, initialIntrinsicContext);
         }
     }
 
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java	Tue May 12 14:22:16 2015 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java	Tue May 12 14:27:35 2015 +0200
@@ -460,7 +460,7 @@
         }
 
         public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
-            if (b.parsingReplacement()) {
+            if (b.parsingIntrinsic()) {
                 ResolvedJavaMethod rootMethod = b.getGraph().method();
                 if (b.getMetaAccess().lookupJavaType(BoxingSnippets.class).isAssignableFrom(rootMethod.getDeclaringClass())) {
                     // Disable invocation plugins for boxing snippets so that the
@@ -487,7 +487,7 @@
         }
 
         public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
-            if (b.parsingReplacement()) {
+            if (b.parsingIntrinsic()) {
                 ResolvedJavaMethod rootMethod = b.getGraph().method();
                 if (b.getMetaAccess().lookupJavaType(BoxingSnippets.class).isAssignableFrom(rootMethod.getDeclaringClass())) {
                     // Disable invocation plugins for unboxing snippets so that the
--- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/ConditionAnchoringTest.java	Tue May 12 14:22:16 2015 +0200
+++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/ConditionAnchoringTest.java	Tue May 12 14:27:35 2015 +0200
@@ -147,7 +147,7 @@
     private static final class InlineEverythingPlugin implements InlineInvokePlugin {
         public InlineInfo getInlineInfo(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args, JavaType returnType) {
             assert method.hasBytecodes();
-            return new InlineInfo(method, false, false);
+            return new InlineInfo(method, false);
         }
     }
 
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Tue May 12 14:22:16 2015 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Tue May 12 14:27:35 2015 +0200
@@ -190,7 +190,7 @@
             if (replacements.hasSubstitution(original, builder.bci())) {
                 return null;
             }
-            assert !builder.parsingReplacement();
+            assert !builder.parsingIntrinsic();
 
             if (TruffleCompilerOptions.TruffleFunctionInlining.getValue()) {
                 if (original.equals(callSiteProxyMethod)) {
@@ -210,12 +210,12 @@
                     if (decision != null && decision.isInline()) {
                         inlining.push(decision);
                         builder.getAssumptions().record(new AssumptionValidAssumption((OptimizedAssumption) decision.getTarget().getNodeRewritingAssumption()));
-                        return new InlineInfo(callInlinedMethod, false, false);
+                        return new InlineInfo(callInlinedMethod, false);
                     }
                 }
             }
 
-            return new InlineInfo(original, false, false);
+            return new InlineInfo(original, false);
         }
 
         @Override
@@ -277,10 +277,10 @@
                  * We want to inline invokes that have a constant MethodHandle parameter to remove
                  * invokedynamic related calls as early as possible.
                  */
-                return new InlineInfo(original, false, false);
+                return new InlineInfo(original, false);
             }
             if (inlineDuringParsing && original.hasBytecodes() && original.getCode().length < TrivialInliningSize.getValue() && builder.getDepth() < InlineDuringParsingMaxDepth.getValue()) {
-                return new InlineInfo(original, false, false);
+                return new InlineInfo(original, false);
             }
             return null;
         }