changeset 19413:91ffbc349e91

Merge.
author Doug Simon <doug.simon@oracle.com>
date Mon, 16 Feb 2015 15:36:32 +0100
parents a9ff83864e8c (diff) 47fcd91a38c5 (current diff)
children 5b93a11c535c
files
diffstat 15 files changed, 156 insertions(+), 68 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Mon Feb 16 15:00:15 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Mon Feb 16 15:36:32 2015 +0100
@@ -800,8 +800,10 @@
     protected PhaseSuite<HighTierContext> getCustomGraphBuilderSuite(GraphBuilderConfiguration gbConf) {
         PhaseSuite<HighTierContext> suite = getDefaultGraphBuilderSuite().copy();
         ListIterator<BasePhase<? super HighTierContext>> iterator = suite.findPhase(GraphBuilderPhase.class);
+        GraphBuilderPhase graphBuilderPhase = (GraphBuilderPhase) iterator.previous();
+        GraphBuilderConfiguration gbConfCopy = gbConf.copy().copyPluginsFrom(graphBuilderPhase.getGraphBuilderConfig());
         iterator.remove();
-        iterator.add(new GraphBuilderPhase(gbConf));
+        iterator.add(new GraphBuilderPhase(gbConfCopy));
         return suite;
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java	Mon Feb 16 15:00:15 2015 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java	Mon Feb 16 15:36:32 2015 +0100
@@ -69,7 +69,7 @@
         try (InitTimer st = timer("graphBuilderPlugins.initialize")) {
             GraphBuilderPhase phase = (GraphBuilderPhase) providers.getSuites().getDefaultGraphBuilderSuite().findPhase(GraphBuilderPhase.class).previous();
             InvocationPlugins plugins = phase.getGraphBuilderConfig().getInvocationPlugins();
-            registerGraphBuilderPlugins(providers.getMetaAccess(), plugins);
+            registerInvocationPlugins(providers.getMetaAccess(), plugins);
         }
 
         try (InitTimer st = timer("foreignCalls.initialize")) {
@@ -101,8 +101,8 @@
         }
     }
 
-    protected void registerGraphBuilderPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) {
-        StandardGraphBuilderPlugins.registerPlugins(metaAccess, plugins);
-        HotSpotGraphBuilderPlugins.registerPlugins(metaAccess, plugins);
+    protected void registerInvocationPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) {
+        StandardGraphBuilderPlugins.registerInvocationPlugins(metaAccess, plugins);
+        HotSpotGraphBuilderPlugins.registerInvocationPlugins(metaAccess, plugins);
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java	Mon Feb 16 15:00:15 2015 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java	Mon Feb 16 15:36:32 2015 +0100
@@ -39,10 +39,10 @@
 import com.oracle.graal.options.*;
 
 /**
- * Provider of HotSpot specific {@link GraphBuilderPlugin}s.
+ * Provides HotSpot specific {@link InvocationPlugin}s.
  */
 public class HotSpotGraphBuilderPlugins {
-    public static void registerPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) {
+    public static void registerInvocationPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) {
         // Object.class
         Registration r = new Registration(plugins, metaAccess, Object.class);
         r.register1("getClass", Receiver.class, new InvocationPlugin() {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java	Mon Feb 16 15:00:15 2015 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java	Mon Feb 16 15:36:32 2015 +0100
@@ -25,6 +25,7 @@
 import static com.oracle.graal.compiler.common.GraalOptions.*;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.bridge.*;
@@ -32,8 +33,10 @@
 import com.oracle.graal.java.*;
 import com.oracle.graal.java.GraphBuilderConfiguration.DebugInfoMode;
 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;
 import com.oracle.graal.phases.*;
@@ -115,6 +118,39 @@
                 return null;
             }
         });
+        config.setLoadFieldPlugin(new LoadFieldPlugin() {
+            public boolean apply(GraphBuilderContext builder, ValueNode receiver, ResolvedJavaField field) {
+                if (receiver.isConstant()) {
+                    JavaConstant asJavaConstant = receiver.asJavaConstant();
+                    return tryConstantFold(builder, runtime.getHostProviders().getMetaAccess(), runtime.getHostProviders().getConstantReflection(), field, asJavaConstant);
+                }
+                return false;
+            }
+
+            public boolean apply(GraphBuilderContext builder, ResolvedJavaField staticField) {
+                return tryConstantFold(builder, runtime.getHostProviders().getMetaAccess(), runtime.getHostProviders().getConstantReflection(), staticField, null);
+            }
+        });
+        config.setInlineInvokePlugin(new InlineInvokePlugin() {
+            public ResolvedJavaMethod getInlinedMethod(GraphBuilderContext builder, ResolvedJavaMethod method, ValueNode[] args, JavaType returnType, int depth) {
+                if (GraalOptions.InlineDuringParsing.getValue()) {
+                    if (builder.parsingReplacement()) {
+                        if (method.getAnnotation(MethodSubstitution.class) != null) {
+                            HotSpotProviders providers = runtime.getHostProviders();
+                            Replacements replacements = providers.getReplacements();
+                            ResolvedJavaMethod subst = replacements.getMethodSubstitutionMethod(method);
+                            if (subst != null) {
+                                return subst;
+                            }
+                        }
+                    }
+                    if (method.hasBytecodes() && method.getCode().length <= GraalOptions.TrivialInliningSize.getValue() && depth < GraalOptions.InlineDuringParsingMaxDepth.getValue()) {
+                        return method;
+                    }
+                }
+                return null;
+            }
+        });
         suite.appendPhase(new GraphBuilderPhase(config));
         return suite;
     }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java	Mon Feb 16 15:00:15 2015 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java	Mon Feb 16 15:36:32 2015 +0100
@@ -76,11 +76,17 @@
     protected final MetaAccessProvider metaAccess;
 
     /**
+     * Specifies if the {@linkplain #getMethod() method} being parsed implements the semantics of
+     * another method (i.e., an intrinsic) or bytecode instruction (i.e., a snippet). substitution.
+     */
+    protected final boolean parsingReplacement;
+
+    /**
      * Meters the number of actual bytecodes parsed.
      */
     public static final DebugMetric BytecodesParsed = Debug.metric("BytecodesParsed");
 
-    public AbstractBytecodeParser(MetaAccessProvider metaAccess, ResolvedJavaMethod method, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts) {
+    public AbstractBytecodeParser(MetaAccessProvider metaAccess, ResolvedJavaMethod method, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts, boolean isReplacement) {
         this.graphBuilderConfig = graphBuilderConfig;
         this.optimisticOpts = optimisticOpts;
         this.metaAccess = metaAccess;
@@ -88,6 +94,7 @@
         this.profilingInfo = method.getProfilingInfo();
         this.constantPool = method.getConstantPool();
         this.method = method;
+        this.parsingReplacement = isReplacement;
         assert metaAccess != null;
     }
 
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraalDirectivePlugins.java	Mon Feb 16 15:00:15 2015 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraalDirectivePlugins.java	Mon Feb 16 15:36:32 2015 +0100
@@ -32,7 +32,7 @@
 
 public class GraalDirectivePlugins {
 
-    public static void registerPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) {
+    public static void registerInvocationPlugins(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.java/src/com/oracle/graal/java/GraphBuilderConfiguration.java	Mon Feb 16 15:00:15 2015 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderConfiguration.java	Mon Feb 16 15:36:32 2015 +0100
@@ -80,7 +80,7 @@
 
     public GraphBuilderConfiguration copy() {
         GraphBuilderConfiguration result = new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, debugInfoMode, skippedExceptionTypes, doLivenessAnalysis);
-        result.loadFieldPlugin = loadFieldPlugin;
+        result.copyPluginsFrom(this);
         return result;
     }
 
@@ -185,4 +185,13 @@
     public void setLoopExplosionPlugin(LoopExplosionPlugin loopExplosionPlugin) {
         this.loopExplosionPlugin = loopExplosionPlugin;
     }
+
+    public GraphBuilderConfiguration copyPluginsFrom(GraphBuilderConfiguration other) {
+        this.invocationPlugins.updateFrom(other.getInvocationPlugins());
+        this.parameterPlugin = other.parameterPlugin;
+        this.loadFieldPlugin = other.loadFieldPlugin;
+        this.inlineInvokePlugin = other.inlineInvokePlugin;
+        this.loopExplosionPlugin = other.loopExplosionPlugin;
+        return this;
+    }
 }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderContext.java	Mon Feb 16 15:00:15 2015 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderContext.java	Mon Feb 16 15:36:32 2015 +0100
@@ -57,6 +57,11 @@
     void push(Kind kind, ValueNode value);
 
     /**
+     * Determines if the graph builder is parsing a snippet or method substitution.
+     */
+    boolean parsingReplacement();
+
+    /**
      * @see GuardingPiNode#nullCheckedValue(ValueNode)
      */
     static ValueNode nullCheckedValue(GraphBuilderContext builder, ValueNode value) {
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Mon Feb 16 15:00:15 2015 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Mon Feb 16 15:36:32 2015 +0100
@@ -26,6 +26,8 @@
 import static com.oracle.graal.api.meta.DeoptimizationReason.*;
 import static com.oracle.graal.bytecode.Bytecodes.*;
 import static com.oracle.graal.compiler.common.GraalOptions.*;
+import static com.oracle.graal.nodes.StructuredGraph.*;
+import static java.lang.String.*;
 
 import java.util.*;
 
@@ -72,7 +74,7 @@
 
     @Override
     protected void run(StructuredGraph graph, HighTierContext context) {
-        new Instance(context.getMetaAccess(), context.getStampProvider(), null, null, context.getConstantReflection(), graphBuilderConfig, context.getOptimisticOptimizations()).run(graph);
+        new Instance(context.getMetaAccess(), context.getStampProvider(), null, context.getConstantReflection(), graphBuilderConfig, context.getOptimisticOptimizations()).run(graph);
     }
 
     public GraphBuilderConfiguration getGraphBuilderConfig() {
@@ -93,8 +95,6 @@
         private final ConstantReflectionProvider constantReflection;
         private final SnippetReflectionProvider snippetReflectionProvider;
 
-        private final Replacements replacements;
-
         /**
          * Gets the graph being processed by this builder.
          */
@@ -102,21 +102,20 @@
             return currentGraph;
         }
 
-        public Instance(MetaAccessProvider metaAccess, StampProvider stampProvider, SnippetReflectionProvider snippetReflectionProvider, Replacements replacements,
-                        ConstantReflectionProvider constantReflection, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts) {
+        public Instance(MetaAccessProvider metaAccess, StampProvider stampProvider, SnippetReflectionProvider snippetReflectionProvider, ConstantReflectionProvider constantReflection,
+                        GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts) {
             this.graphBuilderConfig = graphBuilderConfig;
             this.optimisticOpts = optimisticOpts;
             this.metaAccess = metaAccess;
             this.stampProvider = stampProvider;
             this.constantReflection = constantReflection;
             this.snippetReflectionProvider = snippetReflectionProvider;
-            this.replacements = replacements;
             assert metaAccess != null;
         }
 
         public Instance(MetaAccessProvider metaAccess, StampProvider stampProvider, ConstantReflectionProvider constantReflection, GraphBuilderConfiguration graphBuilderConfig,
                         OptimisticOptimizations optimisticOpts) {
-            this(metaAccess, stampProvider, null, null, constantReflection, graphBuilderConfig, optimisticOpts);
+            this(metaAccess, stampProvider, null, constantReflection, graphBuilderConfig, optimisticOpts);
         }
 
         @Override
@@ -130,7 +129,7 @@
             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);
+                BytecodeParser parser = new BytecodeParser(metaAccess, method, graphBuilderConfig, optimisticOpts, entryBCI, false);
                 parser.build(0, graph.start(), frameState);
 
                 parser.connectLoopEndToBegin();
@@ -198,8 +197,14 @@
             private int returnCount;
             private boolean controlFlowSplit;
 
-            public BytecodeParser(MetaAccessProvider metaAccess, ResolvedJavaMethod method, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts, int entryBCI) {
-                super(metaAccess, method, graphBuilderConfig, optimisticOpts);
+            /**
+             * @param isReplacement specifies if this object is being used to parse a method that
+             *            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) {
+                super(metaAccess, method, graphBuilderConfig, optimisticOpts, isReplacement);
                 this.entryBCI = entryBCI;
 
                 if (graphBuilderConfig.insertNonSafepointDebugInfo()) {
@@ -854,7 +859,7 @@
                     }
                 }
 
-                if (tryUsingInvocationPlugin(args, targetMethod, resultType)) {
+                if (tryInvocationPlugin(args, targetMethod, resultType)) {
                     if (GraalOptions.TraceInlineDuringParsing.getValue()) {
                         for (int i = 0; i < this.currentDepth; ++i) {
                             TTY.print(' ');
@@ -864,28 +869,8 @@
                     return;
                 }
 
-                InlineInvokePlugin inlineInvokePlugin = graphBuilderConfig.getInlineInvokePlugin();
-                if (inlineInvokePlugin != null && invokeKind.isDirect() && targetMethod.canBeInlined() && targetMethod.hasBytecodes() &&
-                                (replacements == null || (replacements.getMethodSubstitution(targetMethod) == null && replacements.getMacroSubstitution(targetMethod) == null))) {
-
-                    ResolvedJavaMethod inlinedMethod = inlineInvokePlugin.getInlinedMethod(this, targetMethod, args, returnType, currentDepth);
-                    if (inlinedMethod != null) {
-                        if (GraalOptions.TraceInlineDuringParsing.getValue()) {
-                            int bci = this.bci();
-                            for (int i = 0; i < this.currentDepth; ++i) {
-                                TTY.print(' ');
-                            }
-                            StackTraceElement stackTraceElement = this.method.asStackTraceElement(bci);
-                            String s = String.format("%s (%s:%d)", method.getName(), stackTraceElement.getFileName(), stackTraceElement.getLineNumber());
-                            TTY.print(s);
-                            TTY.println(" inlining call " + targetMethod.getName());
-                        }
-
-                        ResolvedJavaMethod inlinedTargetMethod = inlinedMethod;
-                        parseAndInlineCallee(inlinedTargetMethod, args);
-                        inlineInvokePlugin.postInline(inlinedTargetMethod);
-                        return;
-                    }
+                if (tryInline(args, targetMethod, invokeKind, returnType)) {
+                    return;
                 }
 
                 MethodCallTargetNode callTarget = currentGraph.add(createMethodCallTarget(invokeKind, targetMethod, args, returnType));
@@ -902,7 +887,7 @@
                 }
             }
 
-            private boolean tryUsingInvocationPlugin(ValueNode[] args, ResolvedJavaMethod targetMethod, Kind resultType) {
+            private boolean tryInvocationPlugin(ValueNode[] args, ResolvedJavaMethod targetMethod, Kind resultType) {
                 InvocationPlugin plugin = graphBuilderConfig.getInvocationPlugins().lookupInvocation(targetMethod);
                 if (plugin != null) {
                     int beforeStackSize = frameState.stackSize;
@@ -932,8 +917,31 @@
                 return false;
             }
 
-            private void parseAndInlineCallee(ResolvedJavaMethod targetMethod, ValueNode[] args) {
-                BytecodeParser parser = new BytecodeParser(metaAccess, targetMethod, graphBuilderConfig, optimisticOpts, StructuredGraph.INVOCATION_ENTRY_BCI);
+            private boolean tryInline(ValueNode[] args, ResolvedJavaMethod targetMethod, InvokeKind invokeKind, JavaType returnType) {
+                InlineInvokePlugin plugin = graphBuilderConfig.getInlineInvokePlugin();
+                if (plugin == null || !invokeKind.isDirect() || !targetMethod.canBeInlined()) {
+                    return false;
+                }
+                ResolvedJavaMethod inlinedMethod = plugin.getInlinedMethod(this, targetMethod, args, returnType, currentDepth);
+                if (inlinedMethod != null) {
+                    if (inlinedMethod != null) {
+                        assert inlinedMethod.hasBytecodes();
+                        if (GraalOptions.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)")));
+                        }
+                        parseAndInlineCallee(inlinedMethod, args, parsingReplacement || inlinedMethod != targetMethod);
+                        plugin.postInline(inlinedMethod);
+                    }
+                    return true;
+                }
+
+                return false;
+            }
+
+            private void parseAndInlineCallee(ResolvedJavaMethod targetMethod, ValueNode[] args, boolean isReplacement) {
+                BytecodeParser parser = new BytecodeParser(metaAccess, targetMethod, graphBuilderConfig, optimisticOpts, INVOCATION_ENTRY_BCI, isReplacement);
                 final FrameState[] lazyFrameState = new FrameState[1];
                 HIRFrameStateBuilder startFrameState = new HIRFrameStateBuilder(targetMethod, currentGraph, () -> {
                     if (lazyFrameState[0] == null) {
@@ -1821,6 +1829,13 @@
                 return snippetReflectionProvider;
             }
 
+            public boolean parsingReplacement() {
+                return parsingReplacement;
+            }
         }
     }
+
+    static String nSpaces(int n) {
+        return n == 0 ? "" : format("%" + n + "s", "");
+    }
 }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/InvocationPlugins.java	Mon Feb 16 15:00:15 2015 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/InvocationPlugins.java	Mon Feb 16 15:36:32 2015 +0100
@@ -181,6 +181,13 @@
         return old;
     }
 
+    /**
+     * Adds all the plugins from {@code other} to this object.
+     */
+    public void updateFrom(InvocationPlugins other) {
+        this.plugins.putAll(other.plugins);
+    }
+
     @Override
     public String toString() {
         return plugins.keySet().stream().map(m -> m.format("%H.%n(%p)")).collect(Collectors.joining(", "));
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/StandardGraphBuilderPlugins.java	Mon Feb 16 15:00:15 2015 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/StandardGraphBuilderPlugins.java	Mon Feb 16 15:36:32 2015 +0100
@@ -34,10 +34,10 @@
 import com.oracle.graal.nodes.java.*;
 
 /**
- * Provider of non-runtime specific {@link GraphBuilderPlugin}s.
+ * Provides non-runtime specific {@link InvocationPlugin}s.
  */
 public class StandardGraphBuilderPlugins {
-    public static void registerPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) {
+    public static void registerInvocationPlugins(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) {
@@ -75,7 +75,7 @@
             }
         }
 
-        GraalDirectivePlugins.registerPlugins(metaAccess, plugins);
+        GraalDirectivePlugins.registerInvocationPlugins(metaAccess, plugins);
     }
 
     static class BoxPlugin implements InvocationPlugin {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Replacements.java	Mon Feb 16 15:00:15 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Replacements.java	Mon Feb 16 15:36:32 2015 +0100
@@ -73,6 +73,13 @@
     StructuredGraph getMethodSubstitution(ResolvedJavaMethod method);
 
     /**
+     * Gets the method that is a substitution for a given method.
+     *
+     * @return the method, if any, that is a substitution for {@code method}
+     */
+    ResolvedJavaMethod getMethodSubstitutionMethod(ResolvedJavaMethod method);
+
+    /**
      * Gets the node class with which a method invocation should be replaced.
      *
      * @param method target of an invocation
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Mon Feb 16 15:00:15 2015 +0100
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Mon Feb 16 15:36:32 2015 +0100
@@ -828,6 +828,12 @@
     }
 
     @Override
+    public ResolvedJavaMethod getMethodSubstitutionMethod(ResolvedJavaMethod original) {
+        ClassReplacements cr = getClassReplacements(original.getDeclaringClass().getName());
+        return cr == null ? null : cr.methodSubstitutions.get(original);
+    }
+
+    @Override
     public void registerSnippetTemplateCache(SnippetTemplateCache templates) {
         assert snippetTemplateCache.get(templates.getClass().getName()) == null;
         snippetTemplateCache.put(templates.getClass().getName(), templates);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Mon Feb 16 15:00:15 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Mon Feb 16 15:36:32 2015 +0100
@@ -152,17 +152,7 @@
         public boolean apply(GraphBuilderContext builder, ValueNode receiver, ResolvedJavaField field) {
             if (receiver.isConstant()) {
                 JavaConstant asJavaConstant = receiver.asJavaConstant();
-                return tryConstantFold(builder, field, asJavaConstant);
-            }
-            return false;
-        }
-
-        private boolean tryConstantFold(GraphBuilderContext builder, ResolvedJavaField field, JavaConstant asJavaConstant) {
-            JavaConstant result = providers.getConstantReflection().readConstantFieldValue(field, asJavaConstant);
-            if (result != null) {
-                ConstantNode constantNode = builder.append(ConstantNode.forConstant(result, providers.getMetaAccess()));
-                builder.push(constantNode.getKind().getStackKind(), constantNode);
-                return true;
+                return tryConstantFold(builder, providers.getMetaAccess(), providers.getConstantReflection(), field, asJavaConstant);
             }
             return false;
         }
@@ -173,7 +163,7 @@
                 builder.push(trueNode.getKind().getStackKind(), trueNode);
                 return true;
             }
-            return tryConstantFold(builder, staticField, null);
+            return tryConstantFold(builder, providers.getMetaAccess(), providers.getConstantReflection(), staticField, null);
         }
     }
 
@@ -197,16 +187,21 @@
 
         private Stack<TruffleInlining> inlining;
         private OptimizedDirectCallNode lastDirectCallNode;
+        private final Replacements replacements;
 
-        public InlineInvokePlugin(TruffleInlining inlining) {
+        public InlineInvokePlugin(TruffleInlining inlining, Replacements replacements) {
             this.inlining = new Stack<>();
             this.inlining.push(inlining);
+            this.replacements = replacements;
         }
 
         public ResolvedJavaMethod getInlinedMethod(GraphBuilderContext builder, ResolvedJavaMethod original, ValueNode[] arguments, JavaType returnType, int depth) {
             if (original.getAnnotation(TruffleBoundary.class) != null) {
                 return null;
             }
+            if (replacements != null && (replacements.getMethodSubstitutionMethod(original) != null || replacements.getMacroSubstitution(original) != null)) {
+                return null;
+            }
             if (original.equals(callSiteProxyMethod)) {
                 ValueNode arg1 = arguments[0];
                 if (!arg1.isConstant()) {
@@ -252,12 +247,11 @@
         newConfig.setLoadFieldPlugin(new InterceptLoadFieldPlugin());
         newConfig.setParameterPlugin(new InterceptReceiverPlugin(callTarget));
         callTarget.setInlining(new TruffleInlining(callTarget, new DefaultInliningPolicy()));
-        newConfig.setInlineInvokePlugin(new InlineInvokePlugin(callTarget.getInlining()));
+        newConfig.setInlineInvokePlugin(new InlineInvokePlugin(callTarget.getInlining(), providers.getReplacements()));
         newConfig.setLoopExplosionPlugin(new LoopExplosionPlugin());
-        TruffleGraphBuilderPlugins.registerPlugins(providers.getMetaAccess(), newConfig.getInvocationPlugins());
+        TruffleGraphBuilderPlugins.registerInvocationPlugins(providers.getMetaAccess(), newConfig.getInvocationPlugins());
         long ms = System.currentTimeMillis();
-        new GraphBuilderPhase.Instance(providers.getMetaAccess(), providers.getStampProvider(), this.snippetReflection, providers.getReplacements(), providers.getConstantReflection(), newConfig,
-                        TruffleCompilerImpl.Optimizations).apply(graph);
+        new GraphBuilderPhase.Instance(providers.getMetaAccess(), providers.getStampProvider(), this.snippetReflection, providers.getConstantReflection(), newConfig, TruffleCompilerImpl.Optimizations).apply(graph);
         System.out.println("# ms: " + (System.currentTimeMillis() - ms));
         Debug.dump(graph, "After FastPE");
 
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/TruffleGraphBuilderPlugins.java	Mon Feb 16 15:00:15 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/TruffleGraphBuilderPlugins.java	Mon Feb 16 15:36:32 2015 +0100
@@ -47,10 +47,10 @@
 import com.oracle.truffle.api.frame.*;
 
 /**
- * Provider of {@link GraphBuilderPlugin}s for Truffle classes.
+ * Provides {@link InvocationPlugin}s for Truffle classes.
  */
 public class TruffleGraphBuilderPlugins {
-    public static void registerPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) {
+    public static void registerInvocationPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) {
 
         // OptimizedAssumption.class
         Registration r = new Registration(plugins, metaAccess, OptimizedAssumption.class);