changeset 19062:a8bcda325946

Merge
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Sun, 01 Feb 2015 20:57:56 -0800
parents c370e6f39575 (current diff) 9544b5f67626 (diff)
children c3ea07277cf6
files graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java
diffstat 28 files changed, 696 insertions(+), 232 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/Services.java	Fri Jan 30 11:56:24 2015 -0800
+++ b/graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/Services.java	Sun Feb 01 20:57:56 2015 -0800
@@ -38,7 +38,9 @@
         protected List<Service> computeValue(Class<?> type) {
             Service[] names = getServiceImpls(type);
             if (names == null || names.length == 0) {
-                throw new InternalError(format("No implementations for %s found (ensure %s extends %s)", type.getSimpleName(), type.getSimpleName(), Service.class));
+                throw new InternalError(
+                                format("No implementations for %s found (ensure %s extends %s and that in suite.py the \"annotationProcessors\" attribute for the project enclosing %s includes \"com.oracle.graal.service.processor\")",
+                                                type.getSimpleName(), type.getSimpleName(), Service.class, type.getSimpleName()));
             }
             return Arrays.asList(names);
         }
--- a/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineCompiler.java	Fri Jan 30 11:56:24 2015 -0800
+++ b/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineCompiler.java	Sun Feb 01 20:57:56 2015 -0800
@@ -32,6 +32,7 @@
 import com.oracle.graal.debug.*;
 import com.oracle.graal.java.*;
 import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.phases.*;
 
 /**
@@ -50,7 +51,7 @@
     private final GraphBuilderConfiguration graphBuilderConfig;
 
     public CompilationResult generate(ResolvedJavaMethod method, int entryBCI, Backend backend, CompilationResult compilationResult, ResolvedJavaMethod installedCodeOwner,
-                    CompilationResultBuilderFactory factory, OptimisticOptimizations optimisticOpts) {
+                    CompilationResultBuilderFactory factory, OptimisticOptimizations optimisticOpts, Replacements replacements) {
         assert method.getCode() != null : "method must contain bytecodes: " + method;
         TTY.Filter filter = new TTY.Filter(PrintFilter.getValue(), method);
 
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/ArithmeticStamp.java	Fri Jan 30 11:56:24 2015 -0800
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/ArithmeticStamp.java	Sun Feb 01 20:57:56 2015 -0800
@@ -23,6 +23,7 @@
 package com.oracle.graal.compiler.common.type;
 
 import java.nio.*;
+import java.util.*;
 
 import com.oracle.graal.api.meta.*;
 
@@ -59,7 +60,7 @@
         if (!(obj instanceof ArithmeticStamp)) {
             return false;
         }
-        assert this.ops.toString().equals(((ArithmeticStamp) obj).ops.toString());
+        assert Objects.equals(ops, ((ArithmeticStamp) obj).ops);
         return true;
     }
 }
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java	Fri Jan 30 11:56:24 2015 -0800
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java	Sun Feb 01 20:57:56 2015 -0800
@@ -256,9 +256,6 @@
         if (!(otherStamp instanceof IntegerStamp)) {
             return StampFactory.illegal(Kind.Illegal);
         }
-        if (equals(otherStamp)) {
-            return this;
-        }
         IntegerStamp other = (IntegerStamp) otherStamp;
         return createStamp(other, Math.max(upperBound, other.upperBound), Math.min(lowerBound, other.lowerBound), downMask & other.downMask, upMask | other.upMask);
     }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java	Fri Jan 30 11:56:24 2015 -0800
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java	Sun Feb 01 20:57:56 2015 -0800
@@ -67,7 +67,7 @@
         StructuredGraph graph = new StructuredGraph(javaMethod);
 
         GraphBuilderConfiguration conf = GraphBuilderConfiguration.getSnippetDefault();
-        new GraphBuilderPhase.Instance(getMetaAccess(), conf, OptimisticOptimizations.ALL).apply(graph);
+        new GraphBuilderPhase.Instance(getMetaAccess(), getProviders().getStampProvider(), assumptions, conf, OptimisticOptimizations.ALL).apply(graph);
         HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
         new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
         new CanonicalizerPhase(true).apply(graph, context);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Fri Jan 30 11:56:24 2015 -0800
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Sun Feb 01 20:57:56 2015 -0800
@@ -525,7 +525,7 @@
         try (Scope bds = Debug.scope("CompileBaseline", javaMethod, providers.getCodeCache())) {
             BaselineCompiler baselineCompiler = new BaselineCompiler(GraphBuilderConfiguration.getDefault(), providers.getMetaAccess());
             OptimisticOptimizations optimisticOpts = OptimisticOptimizations.ALL;
-            return baselineCompiler.generate(javaMethod, -1, getBackend(), new CompilationResult(), javaMethod, CompilationResultBuilderFactory.Default, optimisticOpts);
+            return baselineCompiler.generate(javaMethod, -1, getBackend(), new CompilationResult(), javaMethod, CompilationResultBuilderFactory.Default, optimisticOpts, getReplacements());
         } catch (Throwable e) {
             throw Debug.handle(e);
         }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EATestBase.java	Fri Jan 30 11:56:24 2015 -0800
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EATestBase.java	Sun Feb 01 20:57:56 2015 -0800
@@ -151,8 +151,8 @@
         ResolvedJavaMethod method = getResolvedJavaMethod(snippet);
         graph = new StructuredGraph(method);
         try (Scope s = Debug.scope(getClass(), graph, method, getCodeCache())) {
-            new GraphBuilderPhase.Instance(getMetaAccess(), GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph);
             Assumptions assumptions = new Assumptions(false);
+            new GraphBuilderPhase.Instance(getMetaAccess(), getProviders().getStampProvider(), assumptions, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph);
             context = new HighTierContext(getProviders(), assumptions, null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
             new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
             new DeadCodeEliminationPhase().apply(graph);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/tutorial/StaticAnalysis.java	Fri Jan 30 11:56:24 2015 -0800
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/tutorial/StaticAnalysis.java	Sun Feb 01 20:57:56 2015 -0800
@@ -24,6 +24,7 @@
 
 import java.util.*;
 
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.debug.*;
@@ -33,6 +34,7 @@
 import com.oracle.graal.nodes.CallTargetNode.InvokeKind;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.util.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.graph.*;
@@ -57,13 +59,16 @@
 public class StaticAnalysis {
     /** Access to type, method, and fields using the Graal API. */
     private final MetaAccessProvider metaAccess;
+    /** Access to platform dependent stamps. */
+    private final StampProvider stampProvider;
     /** The results of the static analysis. */
     private final Results results;
     /** Worklist for fixpoint iteration. */
     private final Deque<WorklistEntry> worklist;
 
-    public StaticAnalysis(MetaAccessProvider metaAccess) {
+    public StaticAnalysis(MetaAccessProvider metaAccess, StampProvider stampProvider) {
         this.metaAccess = metaAccess;
+        this.stampProvider = stampProvider;
         this.results = new Results();
         this.worklist = new ArrayDeque<>();
     }
@@ -231,8 +236,9 @@
                      * wrong.
                      */
                     OptimisticOptimizations optimisticOpts = OptimisticOptimizations.NONE;
+                    Assumptions assumptions = new Assumptions(false);
 
-                    GraphBuilderPhase.Instance graphBuilder = new GraphBuilderPhase.Instance(metaAccess, graphBuilderConfig, optimisticOpts);
+                    GraphBuilderPhase.Instance graphBuilder = new GraphBuilderPhase.Instance(metaAccess, stampProvider, assumptions, graphBuilderConfig, optimisticOpts);
                     graphBuilder.apply(graph);
                 } catch (Throwable ex) {
                     Debug.handle(ex);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/tutorial/StaticAnalysisTests.java	Fri Jan 30 11:56:24 2015 -0800
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/tutorial/StaticAnalysisTests.java	Sun Feb 01 20:57:56 2015 -0800
@@ -32,6 +32,7 @@
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.compiler.test.tutorial.StaticAnalysis.MethodState;
 import com.oracle.graal.compiler.test.tutorial.StaticAnalysis.TypeFlow;
+import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.phases.util.*;
 import com.oracle.graal.runtime.*;
 
@@ -58,12 +59,14 @@
         Object f;
     }
 
-    private MetaAccessProvider metaAccess;
+    private final MetaAccessProvider metaAccess;
+    private final StampProvider stampProvider;
 
     public StaticAnalysisTests() {
         Backend backend = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend();
         Providers providers = backend.getProviders();
         this.metaAccess = providers.getMetaAccess();
+        this.stampProvider = providers.getStampProvider();
     }
 
     static void test01Entry() {
@@ -73,7 +76,7 @@
 
     @Test
     public void test01() {
-        StaticAnalysis sa = new StaticAnalysis(metaAccess);
+        StaticAnalysis sa = new StaticAnalysis(metaAccess, stampProvider);
         sa.addMethod(findMethod(StaticAnalysisTests.class, "test01Entry"));
         sa.finish();
 
@@ -94,7 +97,7 @@
 
     @Test
     public void test02() {
-        StaticAnalysis sa = new StaticAnalysis(metaAccess);
+        StaticAnalysis sa = new StaticAnalysis(metaAccess, stampProvider);
         sa.addMethod(findMethod(StaticAnalysisTests.class, "test02Entry"));
         sa.finish();
 
@@ -121,7 +124,7 @@
 
     @Test
     public void test03() {
-        StaticAnalysis sa = new StaticAnalysis(metaAccess);
+        StaticAnalysis sa = new StaticAnalysis(metaAccess, stampProvider);
         sa.addMethod(findMethod(StaticAnalysisTests.class, "test03Entry"));
         sa.finish();
 
@@ -151,7 +154,7 @@
 
     @Test
     public void test04() {
-        StaticAnalysis sa = new StaticAnalysis(metaAccess);
+        StaticAnalysis sa = new StaticAnalysis(metaAccess, stampProvider);
         sa.addMethod(findMethod(StaticAnalysisTests.class, "test04Entry"));
         sa.finish();
 
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Edges.java	Fri Jan 30 11:56:24 2015 -0800
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Edges.java	Sun Feb 01 20:57:56 2015 -0800
@@ -331,7 +331,13 @@
             } else {
                 subIndex++;
             }
-            while (index < edges.getCount()) {
+            if (index < edges.getCount()) {
+                forwardNodeList();
+            }
+        }
+
+        private void forwardNodeList() {
+            do {
                 if (subIndex == 0) {
                     list = edges.getNodeList(node, index);
                 }
@@ -346,7 +352,7 @@
                 }
                 subIndex = 0;
                 index++;
-            }
+            } while (index < edges.getCount());
         }
 
         private Node nextElement() {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Fri Jan 30 11:56:24 2015 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Sun Feb 01 20:57:56 2015 -0800
@@ -197,7 +197,7 @@
                     HotSpotProviders providers = backend.getProviders();
                     BaselineCompiler baselineCompiler = new BaselineCompiler(GraphBuilderConfiguration.getDefault(), providers.getMetaAccess());
                     OptimisticOptimizations optimisticOpts = OptimisticOptimizations.ALL;
-                    result = baselineCompiler.generate(method, -1, backend, new CompilationResult(), method, CompilationResultBuilderFactory.Default, optimisticOpts);
+                    result = baselineCompiler.generate(method, -1, backend, new CompilationResult(), method, CompilationResultBuilderFactory.Default, optimisticOpts, providers.getReplacements());
                 } else {
                     Map<ResolvedJavaMethod, StructuredGraph> graphCache = null;
                     if (GraalOptions.CacheGraphs.getValue()) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java	Fri Jan 30 11:56:24 2015 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java	Sun Feb 01 20:57:56 2015 -0800
@@ -31,6 +31,7 @@
 import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.stubs.*;
+import com.oracle.graal.java.*;
 import com.oracle.graal.nodes.spi.*;
 
 /**
@@ -65,6 +66,15 @@
         HotSpotHostForeignCallsProvider foreignCalls = (HotSpotHostForeignCallsProvider) providers.getForeignCalls();
         final HotSpotLoweringProvider lowerer = (HotSpotLoweringProvider) providers.getLowerer();
 
+        try (InitTimer st = timer("graphBuilderPlugins.initialize")) {
+            GraphBuilderPhase phase = (GraphBuilderPhase) providers.getSuites().getDefaultGraphBuilderSuite().findPhase(GraphBuilderPhase.class).previous();
+            GraphBuilderPlugins plugins = phase.getGraphBuilderPlugins();
+            Iterable<GraphBuilderPluginsProvider> sl = Services.load(GraphBuilderPluginsProvider.class);
+            for (GraphBuilderPluginsProvider p : sl) {
+                p.registerPlugins(providers.getMetaAccess(), plugins);
+            }
+        }
+
         try (InitTimer st = timer("foreignCalls.initialize")) {
             foreignCalls.initialize(providers, config);
         }
@@ -92,6 +102,5 @@
                 throw Debug.handle(e);
             }
         }
-
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java	Fri Jan 30 11:56:24 2015 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java	Sun Feb 01 20:57:56 2015 -0800
@@ -30,7 +30,7 @@
 import com.oracle.graal.hotspot.bridge.*;
 import com.oracle.graal.hotspot.phases.*;
 import com.oracle.graal.java.*;
-import com.oracle.graal.java.GraphBuilderConfiguration.*;
+import com.oracle.graal.java.GraphBuilderConfiguration.DebugInfoMode;
 import com.oracle.graal.options.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.tiers.*;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotGraphBuilderPluginsProvider.java	Sun Feb 01 20:57:56 2015 -0800
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.replacements;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.runtime.*;
+import com.oracle.graal.java.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.spi.*;
+
+@ServiceProvider(GraphBuilderPluginsProvider.class)
+public class HotSpotGraphBuilderPluginsProvider implements GraphBuilderPluginsProvider {
+    public void registerPlugins(MetaAccessProvider metaAccess, GraphBuilderPlugins plugins) {
+        plugins.register(metaAccess, ObjectPlugin.class);
+    }
+
+    enum ObjectPlugin implements GraphBuilderPlugin {
+        getClass() {
+            public boolean handleInvocation(GraphBuilderContext builder, ValueNode[] args) {
+                assert args.length == 1;
+                ValueNode rcvr = args[0];
+                GuardingPiNode pi = builder.append(new GuardingPiNode(rcvr));
+                StampProvider stampProvider = builder.getStampProvider();
+                LoadHubNode hub = builder.append(new LoadHubNode(stampProvider, pi));
+                HubGetClassNode mirror = builder.append(new HubGetClassNode(builder.getMetaAccess(), hub));
+                builder.push(Kind.Object, mirror);
+                return true;
+            }
+        };
+
+        public ResolvedJavaMethod getInvocationTarget(MetaAccessProvider metaAccess) {
+            return GraphBuilderPlugin.resolveTarget(metaAccess, Object.class, name());
+        }
+
+        @Override
+        public String toString() {
+            return Object.class.getName() + "." + name() + "()";
+        }
+    }
+}
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java	Fri Jan 30 11:56:24 2015 -0800
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java	Sun Feb 01 20:57:56 2015 -0800
@@ -1153,5 +1153,4 @@
         }
         Debug.log("%s", sb);
     }
-
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/DefaultGraphBuilderPluginsProvider.java	Sun Feb 01 20:57:56 2015 -0800
@@ -0,0 +1,74 @@
+/*
+ * 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.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.runtime.*;
+import com.oracle.graal.compiler.common.type.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.*;
+
+@ServiceProvider(GraphBuilderPluginsProvider.class)
+public class DefaultGraphBuilderPluginsProvider implements GraphBuilderPluginsProvider {
+    public void registerPlugins(MetaAccessProvider metaAccess, GraphBuilderPlugins plugins) {
+        plugins.register(metaAccess, ObjectPlugin.class);
+    }
+
+    enum ObjectPlugin implements GraphBuilderPlugin {
+        init() {
+            public boolean handleInvocation(GraphBuilderContext builder, ValueNode[] args) {
+                assert args.length == 1;
+                ValueNode rcvr = args[0];
+                ObjectStamp objectStamp = (ObjectStamp) rcvr.stamp();
+
+                boolean needsCheck = true;
+                if (objectStamp.isExactType()) {
+                    needsCheck = objectStamp.type().hasFinalizer();
+                } else if (objectStamp.type() != null && !objectStamp.type().hasFinalizableSubclass()) {
+                    // if either the declared type of receiver or the holder
+                    // can be assumed to have no finalizers
+                    Assumptions assumptions = builder.getAssumptions();
+                    if (assumptions.useOptimisticAssumptions()) {
+                        assumptions.recordNoFinalizableSubclassAssumption(objectStamp.type());
+                        needsCheck = false;
+                    }
+                }
+
+                if (needsCheck) {
+                    builder.append(new RegisterFinalizerNode(rcvr));
+                }
+                return true;
+            }
+
+            public ResolvedJavaMethod getInvocationTarget(MetaAccessProvider metaAccess) {
+                return GraphBuilderPlugin.resolveTarget(metaAccess, Object.class, "<init>");
+            }
+        };
+
+        @Override
+        public String toString() {
+            return Object.class.getName() + "." + name() + "()";
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderContext.java	Sun Feb 01 20:57:56 2015 -0800
@@ -0,0 +1,51 @@
+/*
+ * 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.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.spi.*;
+
+/**
+ * Used by a {@link GraphBuilderPlugin} to interface with a graph builder object.
+ */
+public interface GraphBuilderContext {
+
+    <T extends ControlSinkNode> T append(T fixed);
+
+    <T extends ControlSplitNode> T append(T fixed);
+
+    <T extends FixedWithNextNode> T append(T fixed);
+
+    <T extends FloatingNode> T append(T v);
+
+    StampProvider getStampProvider();
+
+    MetaAccessProvider getMetaAccess();
+
+    Assumptions getAssumptions();
+
+    void push(Kind kind, ValueNode value);
+}
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Fri Jan 30 11:56:24 2015 -0800
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Sun Feb 01 20:57:56 2015 -0800
@@ -47,6 +47,7 @@
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.util.*;
 import com.oracle.graal.phases.*;
@@ -58,20 +59,26 @@
 public class GraphBuilderPhase extends BasePhase<HighTierContext> {
 
     private final GraphBuilderConfiguration graphBuilderConfig;
+    private final GraphBuilderPlugins graphBuilderPlugins;
 
-    public GraphBuilderPhase(GraphBuilderConfiguration graphBuilderConfig) {
-        this.graphBuilderConfig = graphBuilderConfig;
+    public GraphBuilderPhase(GraphBuilderConfiguration config) {
+        this.graphBuilderConfig = config;
+        this.graphBuilderPlugins = new GraphBuilderPlugins();
     }
 
     @Override
     protected void run(StructuredGraph graph, HighTierContext context) {
-        new Instance(context.getMetaAccess(), graphBuilderConfig, context.getOptimisticOptimizations()).run(graph);
+        new Instance(context.getMetaAccess(), context.getStampProvider(), context.getAssumptions(), graphBuilderConfig, graphBuilderPlugins, context.getOptimisticOptimizations()).run(graph);
     }
 
     public GraphBuilderConfiguration getGraphBuilderConfig() {
         return graphBuilderConfig;
     }
 
+    public GraphBuilderPlugins getGraphBuilderPlugins() {
+        return graphBuilderPlugins;
+    }
+
     public static class Instance extends Phase {
 
         protected StructuredGraph currentGraph;
@@ -81,7 +88,10 @@
         private ResolvedJavaMethod rootMethod;
 
         private final GraphBuilderConfiguration graphBuilderConfig;
+        private final GraphBuilderPlugins graphBuilderPlugins;
         private final OptimisticOptimizations optimisticOpts;
+        private final StampProvider stampProvider;
+        private final Assumptions assumptions;
 
         /**
          * Gets the graph being processed by this builder.
@@ -90,13 +100,21 @@
             return currentGraph;
         }
 
-        public Instance(MetaAccessProvider metaAccess, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts) {
+        public Instance(MetaAccessProvider metaAccess, StampProvider stampProvider, Assumptions assumptions, GraphBuilderConfiguration graphBuilderConfig, GraphBuilderPlugins graphBuilderPlugins,
+                        OptimisticOptimizations optimisticOpts) {
             this.graphBuilderConfig = graphBuilderConfig;
             this.optimisticOpts = optimisticOpts;
             this.metaAccess = metaAccess;
+            this.stampProvider = stampProvider;
+            this.assumptions = assumptions;
+            this.graphBuilderPlugins = graphBuilderPlugins;
             assert metaAccess != null;
         }
 
+        public Instance(MetaAccessProvider metaAccess, StampProvider stampProvider, Assumptions assumptions, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts) {
+            this(metaAccess, stampProvider, assumptions, graphBuilderConfig, null, optimisticOpts);
+        }
+
         @Override
         protected void run(StructuredGraph graph) {
             ResolvedJavaMethod method = graph.method();
@@ -143,7 +161,7 @@
             }
         }
 
-        public class BytecodeParser extends AbstractBytecodeParser<ValueNode, HIRFrameStateBuilder> {
+        public class BytecodeParser extends AbstractBytecodeParser<ValueNode, HIRFrameStateBuilder> implements GraphBuilderContext {
 
             private BciBlock[] loopHeaders;
             private LocalLiveness liveness;
@@ -752,38 +770,49 @@
                         args[0] = TypeProfileProxyNode.proxify(args[0], profile);
                     }
                 }
+                if (GraalOptions.InlineDuringParsing.getValue() && invokeKind.isDirect()) {
 
-                if (GraalOptions.InlineDuringParsing.getValue() && invokeKind.isDirect() && targetMethod.canBeInlined() && targetMethod.hasBytecodes()) {
-                    if (targetMethod.getCode().length <= GraalOptions.TrivialInliningSize.getValue() && currentDepth < GraalOptions.InlineDuringParsingMaxDepth.getValue() &&
-                                    graphBuilderConfig.shouldInlineTrivial()) {
-                        BytecodeParser parser = new BytecodeParser(metaAccess, targetMethod, graphBuilderConfig, optimisticOpts, StructuredGraph.INVOCATION_ENTRY_BCI);
-                        final FrameState[] lazyFrameState = new FrameState[1];
-                        HIRFrameStateBuilder startFrameState = new HIRFrameStateBuilder(targetMethod, currentGraph, () -> {
-                            if (lazyFrameState[0] == null) {
-                                lazyFrameState[0] = frameState.create(bci());
-                            }
-                            return lazyFrameState[0];
-                        });
-                        startFrameState.initializeFromArgumentsArray(args);
-                        parser.build(currentDepth + 1, this.lastInstr, startFrameState);
-
-                        FixedWithNextNode calleeBeforeReturnNode = parser.getBeforeReturnNode();
-                        this.lastInstr = calleeBeforeReturnNode;
-                        if (calleeBeforeReturnNode != null) {
-                            ValueNode calleeReturnValue = parser.getReturnValue();
-                            if (calleeReturnValue != null) {
-                                frameState.push(calleeReturnValue.getKind().getStackKind(), calleeReturnValue);
+                    if (graphBuilderPlugins != null) {
+                        GraphBuilderPlugin plugin = graphBuilderPlugins.getPlugin(targetMethod);
+                        if (plugin != null) {
+                            if (plugin.handleInvocation(this, args)) {
+                                return;
                             }
                         }
+                    }
 
-                        FixedWithNextNode calleeBeforeUnwindNode = parser.getBeforeUnwindNode();
-                        if (calleeBeforeUnwindNode != null) {
-                            ValueNode calleeUnwindValue = parser.getUnwindValue();
-                            assert calleeUnwindValue != null;
-                            calleeBeforeUnwindNode.setNext(handleException(calleeUnwindValue, bci()));
+                    if (targetMethod.canBeInlined() && targetMethod.hasBytecodes()) {
+                        if (targetMethod.getCode().length <= GraalOptions.TrivialInliningSize.getValue() && currentDepth < GraalOptions.InlineDuringParsingMaxDepth.getValue() &&
+                                        graphBuilderConfig.shouldInlineTrivial()) {
+                            BytecodeParser parser = new BytecodeParser(metaAccess, targetMethod, graphBuilderConfig, optimisticOpts, StructuredGraph.INVOCATION_ENTRY_BCI);
+                            final FrameState[] lazyFrameState = new FrameState[1];
+                            HIRFrameStateBuilder startFrameState = new HIRFrameStateBuilder(targetMethod, currentGraph, () -> {
+                                if (lazyFrameState[0] == null) {
+                                    lazyFrameState[0] = frameState.create(bci());
+                                }
+                                return lazyFrameState[0];
+                            });
+                            startFrameState.initializeFromArgumentsArray(args);
+                            parser.build(currentDepth + 1, this.lastInstr, startFrameState);
+
+                            FixedWithNextNode calleeBeforeReturnNode = parser.getBeforeReturnNode();
+                            this.lastInstr = calleeBeforeReturnNode;
+                            if (calleeBeforeReturnNode != null) {
+                                ValueNode calleeReturnValue = parser.getReturnValue();
+                                if (calleeReturnValue != null) {
+                                    frameState.push(calleeReturnValue.getKind().getStackKind(), calleeReturnValue);
+                                }
+                            }
+
+                            FixedWithNextNode calleeBeforeUnwindNode = parser.getBeforeUnwindNode();
+                            if (calleeBeforeUnwindNode != null) {
+                                ValueNode calleeUnwindValue = parser.getUnwindValue();
+                                assert calleeUnwindValue != null;
+                                calleeBeforeUnwindNode.setNext(handleException(calleeUnwindValue, bci()));
+                            }
+
+                            return;
                         }
-
-                        return;
                     }
                 }
 
@@ -937,7 +966,7 @@
                 throw GraalInternalError.shouldNotReachHere("Can not append Node of type: " + v.getClass().getName());
             }
 
-            private <T extends ControlSinkNode> T append(T fixed) {
+            public <T extends ControlSinkNode> T append(T fixed) {
                 assert !fixed.isAlive() && !fixed.isDeleted() : "instruction should not have been appended yet";
                 assert lastInstr.next() == null : "cannot append instruction to instruction which isn't end (" + lastInstr + "->" + lastInstr.next() + ")";
                 T added = currentGraph.add(fixed);
@@ -946,7 +975,7 @@
                 return added;
             }
 
-            private <T extends ControlSplitNode> T append(T fixed) {
+            public <T extends ControlSplitNode> T append(T fixed) {
                 assert !fixed.isAlive() && !fixed.isDeleted() : "instruction should not have been appended yet";
                 assert lastInstr.next() == null : "cannot append instruction to instruction which isn't end (" + lastInstr + "->" + lastInstr.next() + ")";
                 T added = currentGraph.add(fixed);
@@ -955,7 +984,7 @@
                 return added;
             }
 
-            protected <T extends FixedWithNextNode> T append(T fixed) {
+            public <T extends FixedWithNextNode> T append(T fixed) {
                 assert !fixed.isAlive() && !fixed.isDeleted() : "instruction should not have been appended yet";
                 assert lastInstr.next() == null : "cannot append instruction to instruction which isn't end (" + lastInstr + "->" + lastInstr.next() + ")";
                 T added = currentGraph.add(fixed);
@@ -964,7 +993,7 @@
                 return added;
             }
 
-            private <T extends FloatingNode> T append(T v) {
+            public <T extends FloatingNode> T append(T v) {
                 assert !(v instanceof ConstantNode);
                 T added = currentGraph.unique(v);
                 return added;
@@ -1456,6 +1485,22 @@
                 append(ifNode);
             }
 
+            public StampProvider getStampProvider() {
+                return stampProvider;
+            }
+
+            public MetaAccessProvider getMetaAccess() {
+                return metaAccess;
+            }
+
+            public Assumptions getAssumptions() {
+                return assumptions;
+            }
+
+            public void push(Kind kind, ValueNode value) {
+                frameState.push(kind, value);
+            }
+
         }
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPlugin.java	Sun Feb 01 20:57:56 2015 -0800
@@ -0,0 +1,57 @@
+/*
+ * 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.compiler.common.*;
+import com.oracle.graal.nodes.*;
+
+/**
+ * Extensions for handling certain bytecode instructions while building a
+ * {@linkplain StructuredGraph graph} from a bytecode stream.
+ */
+public interface GraphBuilderPlugin {
+
+    /**
+     * Processes an invocation parsed in a bytecode stream and add nodes to a graph being
+     * constructed that implement the semantics of the invocation.
+     *
+     * @param builder object being used to build a graph
+     * @param args the arguments to the invocation
+     */
+    boolean handleInvocation(GraphBuilderContext builder, ValueNode[] args);
+
+    /**
+     * Gets the target method handled by {@link #handleInvocation(GraphBuilderContext, ValueNode[])}
+     * .
+     */
+    ResolvedJavaMethod getInvocationTarget(MetaAccessProvider metaAccess);
+
+    static ResolvedJavaMethod resolveTarget(MetaAccessProvider metaAccess, Class<?> clazz, String methodName, Class<?>... parameterTypes) {
+        try {
+            return metaAccess.lookupJavaMethod(methodName.equals("<init>") ? clazz.getDeclaredConstructor(parameterTypes) : clazz.getDeclaredMethod(methodName, parameterTypes));
+        } catch (NoSuchMethodException | SecurityException e) {
+            throw new GraalInternalError(e);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPlugins.java	Sun Feb 01 20:57:56 2015 -0800
@@ -0,0 +1,65 @@
+/*
+ * 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 java.util.*;
+import java.util.stream.*;
+
+import com.oracle.graal.api.meta.*;
+
+/**
+ * A repository of {@link GraphBuilderPlugin}s.
+ */
+public class GraphBuilderPlugins {
+
+    private final Map<ResolvedJavaMethod, GraphBuilderPlugin> map = new HashMap<>();
+
+    /**
+     * Registers all the constants of an enum that implements {@link GraphBuilderPlugin}.
+     */
+    public <T extends Enum<T> & GraphBuilderPlugin> void register(MetaAccessProvider metaAccess, Class<T> enumClass) {
+        assert Enum.class.isAssignableFrom(enumClass);
+        Object[] enumConstants = enumClass.getEnumConstants();
+        for (Object o : enumConstants) {
+            GraphBuilderPlugin gbp = (GraphBuilderPlugin) o;
+            ResolvedJavaMethod target = gbp.getInvocationTarget(metaAccess);
+            GraphBuilderPlugin oldValue = map.put(target, gbp);
+            assert oldValue == null;
+        }
+    }
+
+    /**
+     * Gets the plugin for a given method registered in the object.
+     *
+     * @param method the method to lookup
+     * @return the plugin associated with {@code method} or {@code null} if none exists
+     */
+    public GraphBuilderPlugin getPlugin(ResolvedJavaMethod method) {
+        return map.get(method);
+    }
+
+    @Override
+    public String toString() {
+        return map.keySet().stream().map(m -> m.format("%H.%n(%p)")).collect(Collectors.joining(", "));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPluginsProvider.java	Sun Feb 01 20:57:56 2015 -0800
@@ -0,0 +1,38 @@
+/*
+ * 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.runtime.*;
+
+/**
+ * Interface for providers of {@link GraphBuilderPlugin}s.
+ */
+public interface GraphBuilderPluginsProvider extends Service {
+    /**
+     * Registers the plugins provided by this object with a plugins registry.
+     *
+     * @param plugins registry of plugins
+     */
+    void registerPlugins(MetaAccessProvider metaAccess, GraphBuilderPlugins plugins);
+}
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInsertionBuffer.java	Fri Jan 30 11:56:24 2015 -0800
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInsertionBuffer.java	Sun Feb 01 20:57:56 2015 -0800
@@ -48,7 +48,8 @@
      * index into lir list where "count" ops should be inserted indexAndCount[i * 2 + 1]: the number
      * of ops to be inserted at index
      */
-    private final List<Integer> indexAndCount;
+    private int[] indexAndCount;
+    private int indexAndCountSize;
 
     /**
      * The LIROps to be inserted.
@@ -56,8 +57,8 @@
     private final List<LIRInstruction> ops;
 
     public LIRInsertionBuffer() {
-        indexAndCount = new ArrayList<>(8);
-        ops = new ArrayList<>(8);
+        indexAndCount = new int[8];
+        ops = new ArrayList<>(4);
     }
 
     /**
@@ -65,7 +66,7 @@
      */
     public void init(List<LIRInstruction> newLir) {
         assert !initialized() : "already initialized";
-        assert indexAndCount.size() == 0 && ops.size() == 0;
+        assert indexAndCountSize == 0 && ops.size() == 0;
         this.lir = newLir;
     }
 
@@ -126,32 +127,38 @@
                 }
                 ipIndex--;
             }
-            indexAndCount.clear();
+            indexAndCountSize = 0;
             ops.clear();
         }
         lir = null;
     }
 
     private void appendNew(int index, int count) {
-        indexAndCount.add(index);
-        indexAndCount.add(count);
+        int oldSize = indexAndCountSize;
+        int newSize = oldSize + 2;
+        if (newSize > this.indexAndCount.length) {
+            indexAndCount = Arrays.copyOf(indexAndCount, newSize * 2);
+        }
+        indexAndCount[oldSize] = index;
+        indexAndCount[oldSize + 1] = count;
+        this.indexAndCountSize = newSize;
     }
 
     private void setCountAt(int i, int value) {
-        indexAndCount.set((i << 1) + 1, value);
+        indexAndCount[(i << 1) + 1] = value;
     }
 
     private int numberOfInsertionPoints() {
-        assert indexAndCount.size() % 2 == 0 : "must have a count for each index";
-        return indexAndCount.size() >> 1;
+        assert indexAndCount.length % 2 == 0 : "must have a count for each index";
+        return indexAndCountSize >> 1;
     }
 
     private int indexAt(int i) {
-        return indexAndCount.get((i << 1));
+        return indexAndCount[(i << 1)];
     }
 
     private int countAt(int i) {
-        return indexAndCount.get((i << 1) + 1);
+        return indexAndCount[(i << 1) + 1];
     }
 
     private boolean verify() {
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java	Fri Jan 30 11:56:24 2015 -0800
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java	Sun Feb 01 20:57:56 2015 -0800
@@ -641,177 +641,210 @@
         @Override
         protected void node(FixedNode node) {
             if (node instanceof AbstractBeginNode) {
-                AbstractBeginNode begin = (AbstractBeginNode) node;
-                Node pred = node.predecessor();
+                processAbstractBegin((AbstractBeginNode) node);
+            } else if (node instanceof FixedGuardNode) {
+                processFixedGuard((FixedGuardNode) node);
+            } else if (node instanceof CheckCastNode) {
+                processCheckCast((CheckCastNode) node);
+            } else if (node instanceof ConditionAnchorNode) {
+                processConditionAnchor((ConditionAnchorNode) node);
+            } else if (node instanceof IfNode) {
+                processIf((IfNode) node);
+            } else if (node instanceof AbstractEndNode) {
+                processAbstractEnd((AbstractEndNode) node);
+            } else if (node instanceof Invoke) {
+                processInvoke((Invoke) node);
+            }
+        }
 
-                if (pred != null) {
-                    registerControlSplitInfo(pred, begin);
-                }
-
-                // First eliminate any guards which can be trivially removed and register any
-                // type constraints the guards produce.
-                for (GuardNode guard : begin.guards().snapshot()) {
-                    eliminateTrivialGuardOrRegisterStamp(guard);
-                }
+        private void processIf(IfNode ifNode) {
+            LogicNode compare = ifNode.condition();
 
-                // Collect the guards which have produced conditional stamps.
-                // XXX (gd) IdentityHashMap.values().contains performs a linear search
-                // so we prefer to build a set
-                Set<GuardNode> provers = Node.newSet();
-                for (GuardedStamp e : state.valueConstraints.values()) {
-                    provers.add(e.getGuard());
-                }
-
-                // Process the remaining guards. Guards which produced some type constraint should
-                // just be registered since they aren't trivially deleteable. Test the other guards
-                // to see if they can be deleted using type constraints.
-                for (GuardNode guard : begin.guards().snapshot()) {
-                    if (provers.contains(guard) || !(tryReplaceWithExistingGuard(guard) || testImpliedGuard(guard))) {
-                        registerCondition(!guard.isNegated(), guard.condition(), guard);
+            LogicNode replacement = null;
+            GuardingNode replacementAnchor = null;
+            AbstractBeginNode survivingSuccessor = null;
+            if (state.trueConditions.containsKey(compare)) {
+                replacement = trueConstant;
+                replacementAnchor = state.trueConditions.get(compare);
+                survivingSuccessor = ifNode.trueSuccessor();
+            } else if (state.falseConditions.containsKey(compare)) {
+                replacement = falseConstant;
+                replacementAnchor = state.falseConditions.get(compare);
+                survivingSuccessor = ifNode.falseSuccessor();
+            } else {
+                replacement = evaluateCondition(compare, trueConstant, falseConstant);
+                if (replacement != null) {
+                    if (replacement == trueConstant) {
+                        survivingSuccessor = ifNode.trueSuccessor();
+                    } else {
+                        assert replacement == falseConstant;
+                        survivingSuccessor = ifNode.falseSuccessor();
                     }
                 }
-                for (GuardNode guard : provers) {
-                    assert !testImpliedGuard(guard) : "provers shouldn't be trivially eliminatable";
-                }
-            } else if (node instanceof FixedGuardNode) {
-                FixedGuardNode guard = (FixedGuardNode) node;
-                GuardingNode existingGuard = guard.isNegated() ? state.falseConditions.get(guard.condition()) : state.trueConditions.get(guard.condition());
-                if (existingGuard != null && existingGuard instanceof FixedGuardNode) {
-                    guard.replaceAtUsages(existingGuard.asNode());
-                    guard.graph().removeFixed(guard);
-                } else {
-                    registerCondition(!guard.isNegated(), guard.condition(), guard);
-                }
-            } else if (node instanceof CheckCastNode) {
-                CheckCastNode checkCast = (CheckCastNode) node;
-                ValueNode object = checkCast.object();
-                boolean isNull = state.isNull(object);
-                ResolvedJavaType type = state.getNodeType(object);
-                if (isNull || (type != null && checkCast.type().isAssignableFrom(type))) {
-                    boolean nonNull = state.isNonNull(object);
-                    GuardingNode replacementAnchor = null;
-                    if (nonNull) {
-                        replacementAnchor = searchAnchor(GraphUtil.unproxify(object), type);
-                    }
-                    if (replacementAnchor == null) {
-                        replacementAnchor = AbstractBeginNode.prevBegin(checkCast);
-                    }
-                    PiNode piNode;
-                    if (isNull) {
-                        ConstantNode nullObject = ConstantNode.defaultForKind(Kind.Object, graph);
-                        piNode = graph.unique(new PiNode(nullObject, nullObject.stamp(), replacementAnchor.asNode()));
-                    } else {
-                        piNode = graph.unique(new PiNode(object, StampFactory.declaredTrusted(type, nonNull), replacementAnchor.asNode()));
-                    }
-                    checkCast.replaceAtUsages(piNode);
-                    graph.removeFixed(checkCast);
-                    metricCheckCastRemoved.increment();
-                }
-            } else if (node instanceof ConditionAnchorNode) {
-                ConditionAnchorNode conditionAnchorNode = (ConditionAnchorNode) node;
-                LogicNode condition = conditionAnchorNode.condition();
-                GuardingNode replacementAnchor = null;
-                if (conditionAnchorNode.isNegated()) {
-                    if (state.falseConditions.containsKey(condition)) {
-                        replacementAnchor = state.falseConditions.get(condition);
-                    }
-                } else {
-                    if (state.trueConditions.containsKey(condition)) {
-                        replacementAnchor = state.trueConditions.get(condition);
-                    }
-                }
-                if (replacementAnchor != null) {
-                    conditionAnchorNode.replaceAtUsages(replacementAnchor.asNode());
-                    conditionAnchorNode.graph().removeFixed(conditionAnchorNode);
-                }
-            } else if (node instanceof IfNode) {
-                IfNode ifNode = (IfNode) node;
-                LogicNode compare = ifNode.condition();
+            }
+
+            if (replacement != null) {
+                trySimplify(ifNode, compare, replacement, replacementAnchor, survivingSuccessor);
+            }
+        }
 
-                LogicNode replacement = null;
-                GuardingNode replacementAnchor = null;
-                AbstractBeginNode survivingSuccessor = null;
-                if (state.trueConditions.containsKey(compare)) {
-                    replacement = trueConstant;
-                    replacementAnchor = state.trueConditions.get(compare);
-                    survivingSuccessor = ifNode.trueSuccessor();
-                } else if (state.falseConditions.containsKey(compare)) {
-                    replacement = falseConstant;
-                    replacementAnchor = state.falseConditions.get(compare);
-                    survivingSuccessor = ifNode.falseSuccessor();
+        private void trySimplify(IfNode ifNode, LogicNode compare, LogicNode replacement, GuardingNode replacementAnchor, AbstractBeginNode survivingSuccessor) {
+            if (replacementAnchor != null && !(replacementAnchor instanceof AbstractBeginNode)) {
+                ValueAnchorNode anchor = graph.add(new ValueAnchorNode(replacementAnchor.asNode()));
+                graph.addBeforeFixed(ifNode, anchor);
+            }
+            boolean canSimplify = true;
+            for (Node n : survivingSuccessor.usages().snapshot()) {
+                if (n instanceof GuardNode || n instanceof ProxyNode) {
+                    // Keep wired to the begin node.
                 } else {
-                    replacement = evaluateCondition(compare, trueConstant, falseConstant);
-                    if (replacement != null) {
-                        if (replacement == trueConstant) {
-                            survivingSuccessor = ifNode.trueSuccessor();
-                        } else {
-                            assert replacement == falseConstant;
-                            survivingSuccessor = ifNode.falseSuccessor();
-                        }
-                    }
-                }
-
-                if (replacement != null) {
-                    if (replacementAnchor != null && !(replacementAnchor instanceof AbstractBeginNode)) {
-                        ValueAnchorNode anchor = graph.add(new ValueAnchorNode(replacementAnchor.asNode()));
-                        graph.addBeforeFixed(ifNode, anchor);
+                    if (replacementAnchor == null) {
+                        // Cannot simplify this IfNode as there is no anchor.
+                        canSimplify = false;
+                        break;
                     }
-                    for (Node n : survivingSuccessor.usages().snapshot()) {
-                        if (n instanceof GuardNode || n instanceof ProxyNode) {
-                            // Keep wired to the begin node.
-                        } else {
-                            if (replacementAnchor == null) {
-                                // Cannot simplify this IfNode as there is no anchor.
-                                return;
-                            }
-                            // Rewire to the replacement anchor.
-                            n.replaceFirstInput(survivingSuccessor, replacementAnchor.asNode());
-                        }
-                    }
+                    // Rewire to the replacement anchor.
+                    n.replaceFirstInput(survivingSuccessor, replacementAnchor.asNode());
+                }
+            }
+
+            if (canSimplify) {
+                ifNode.setCondition(replacement);
+                if (compare.hasNoUsages()) {
+                    GraphUtil.killWithUnusedFloatingInputs(compare);
+                }
+            }
+        }
 
-                    ifNode.setCondition(replacement);
-                    if (compare.hasNoUsages()) {
-                        GraphUtil.killWithUnusedFloatingInputs(compare);
-                    }
-                }
-            } else if (node instanceof AbstractEndNode) {
-                AbstractEndNode endNode = (AbstractEndNode) node;
-                for (PhiNode phi : endNode.merge().phis()) {
-                    int index = endNode.merge().phiPredecessorIndex(endNode);
-                    ValueNode value = phi.valueAt(index);
-                    if (value instanceof ConditionalNode) {
-                        ConditionalNode materialize = (ConditionalNode) value;
-                        LogicNode compare = materialize.condition();
-                        ValueNode replacement = evaluateCondition(compare, materialize.trueValue(), materialize.falseValue());
-
-                        if (replacement != null) {
-                            phi.setValueAt(index, replacement);
-                            if (materialize.hasNoUsages()) {
-                                GraphUtil.killWithUnusedFloatingInputs(materialize);
+        private void processInvoke(Invoke invoke) {
+            if (invoke.callTarget() instanceof MethodCallTargetNode) {
+                MethodCallTargetNode callTarget = (MethodCallTargetNode) invoke.callTarget();
+                ValueNode receiver = callTarget.receiver();
+                if (receiver != null && callTarget.invokeKind().isIndirect()) {
+                    ResolvedJavaType type = state.getNodeType(receiver);
+                    if (!Objects.equals(type, StampTool.typeOrNull(receiver))) {
+                        ResolvedJavaMethod method = type.resolveConcreteMethod(callTarget.targetMethod(), invoke.getContextType());
+                        if (method != null) {
+                            if (method.canBeStaticallyBound() || type.isFinal()) {
+                                callTarget.setInvokeKind(InvokeKind.Special);
+                                callTarget.setTargetMethod(method);
                             }
                         }
                     }
                 }
-            } else if (node instanceof Invoke) {
-                Invoke invoke = (Invoke) node;
-                if (invoke.callTarget() instanceof MethodCallTargetNode) {
-                    MethodCallTargetNode callTarget = (MethodCallTargetNode) invoke.callTarget();
-                    ValueNode receiver = callTarget.receiver();
-                    if (receiver != null && callTarget.invokeKind().isIndirect()) {
-                        ResolvedJavaType type = state.getNodeType(receiver);
-                        if (!Objects.equals(type, StampTool.typeOrNull(receiver))) {
-                            ResolvedJavaMethod method = type.resolveConcreteMethod(callTarget.targetMethod(), invoke.getContextType());
-                            if (method != null) {
-                                if (method.canBeStaticallyBound() || type.isFinal()) {
-                                    callTarget.setInvokeKind(InvokeKind.Special);
-                                    callTarget.setTargetMethod(method);
-                                }
-                            }
+            }
+        }
+
+        private void processAbstractEnd(AbstractEndNode endNode) {
+            for (PhiNode phi : endNode.merge().phis()) {
+                int index = endNode.merge().phiPredecessorIndex(endNode);
+                ValueNode value = phi.valueAt(index);
+                if (value instanceof ConditionalNode) {
+                    ConditionalNode materialize = (ConditionalNode) value;
+                    LogicNode compare = materialize.condition();
+                    ValueNode replacement = evaluateCondition(compare, materialize.trueValue(), materialize.falseValue());
+
+                    if (replacement != null) {
+                        phi.setValueAt(index, replacement);
+                        if (materialize.hasNoUsages()) {
+                            GraphUtil.killWithUnusedFloatingInputs(materialize);
                         }
                     }
                 }
+            }
+        }
 
+        private void processConditionAnchor(ConditionAnchorNode conditionAnchorNode) {
+            LogicNode condition = conditionAnchorNode.condition();
+            GuardingNode replacementAnchor = null;
+            if (conditionAnchorNode.isNegated()) {
+                if (state.falseConditions.containsKey(condition)) {
+                    replacementAnchor = state.falseConditions.get(condition);
+                }
+            } else {
+                if (state.trueConditions.containsKey(condition)) {
+                    replacementAnchor = state.trueConditions.get(condition);
+                }
             }
+            if (replacementAnchor != null) {
+                conditionAnchorNode.replaceAtUsages(replacementAnchor.asNode());
+                conditionAnchorNode.graph().removeFixed(conditionAnchorNode);
+            }
+        }
+
+        private void processCheckCast(CheckCastNode checkCast) {
+            ValueNode object = checkCast.object();
+            boolean isNull = state.isNull(object);
+            ResolvedJavaType type = state.getNodeType(object);
+            if (isNull || (type != null && checkCast.type().isAssignableFrom(type))) {
+                boolean nonNull = state.isNonNull(object);
+                GuardingNode replacementAnchor = null;
+                if (nonNull) {
+                    replacementAnchor = searchAnchor(GraphUtil.unproxify(object), type);
+                }
+                if (replacementAnchor == null) {
+                    replacementAnchor = AbstractBeginNode.prevBegin(checkCast);
+                }
+                PiNode piNode;
+                if (isNull) {
+                    ConstantNode nullObject = ConstantNode.defaultForKind(Kind.Object, graph);
+                    piNode = graph.unique(new PiNode(nullObject, nullObject.stamp(), replacementAnchor.asNode()));
+                } else {
+                    piNode = graph.unique(new PiNode(object, StampFactory.declaredTrusted(type, nonNull), replacementAnchor.asNode()));
+                }
+                checkCast.replaceAtUsages(piNode);
+                graph.removeFixed(checkCast);
+                metricCheckCastRemoved.increment();
+            }
+        }
+
+        private void processFixedGuard(FixedGuardNode guard) {
+            GuardingNode existingGuard = guard.isNegated() ? state.falseConditions.get(guard.condition()) : state.trueConditions.get(guard.condition());
+            if (existingGuard != null && existingGuard instanceof FixedGuardNode) {
+                guard.replaceAtUsages(existingGuard.asNode());
+                guard.graph().removeFixed(guard);
+            } else {
+                registerCondition(!guard.isNegated(), guard.condition(), guard);
+            }
+        }
+
+        private void processAbstractBegin(AbstractBeginNode begin) {
+            Node pred = begin.predecessor();
+
+            if (pred != null) {
+                registerControlSplitInfo(pred, begin);
+            }
+
+            // First eliminate any guards which can be trivially removed and register any
+            // type constraints the guards produce.
+            for (GuardNode guard : begin.guards().snapshot()) {
+                eliminateTrivialGuardOrRegisterStamp(guard);
+            }
+
+            // Collect the guards which have produced conditional stamps.
+            // XXX (gd) IdentityHashMap.values().contains performs a linear search
+            // so we prefer to build a set
+            Set<GuardNode> provers = Node.newSet();
+            for (GuardedStamp e : state.valueConstraints.values()) {
+                provers.add(e.getGuard());
+            }
+
+            // Process the remaining guards. Guards which produced some type constraint should
+            // just be registered since they aren't trivially deleteable. Test the other guards
+            // to see if they can be deleted using type constraints.
+            for (GuardNode guard : begin.guards().snapshot()) {
+                if (provers.contains(guard) || !(tryReplaceWithExistingGuard(guard) || testImpliedGuard(guard))) {
+                    registerCondition(!guard.isNegated(), guard.condition(), guard);
+                }
+            }
+            assert assertImpliedGuard(provers);
+        }
+
+        private boolean assertImpliedGuard(Set<GuardNode> provers) {
+            for (GuardNode guard : provers) {
+                assert !testImpliedGuard(guard) : "provers shouldn't be trivially eliminatable";
+            }
+            return true;
         }
 
         private GuardingNode searchAnchor(ValueNode value, ResolvedJavaType type) {
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java	Fri Jan 30 11:56:24 2015 -0800
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java	Sun Feb 01 20:57:56 2015 -0800
@@ -1068,7 +1068,13 @@
     }
 
     private void addToLatestSorting(ValueNode i, SortState state) {
-        if (i == null || state.isVisited(i) || cfg.getNodeToBlock().get(i) != state.currentBlock() || i instanceof PhiNode || i instanceof ProxyNode) {
+        if (i == null || state.isVisited(i) || cfg.getNodeToBlock().get(i) != state.currentBlock() || i instanceof PhiNode) {
+            return;
+        }
+
+        if (i instanceof ProxyNode) {
+            ProxyNode proxyNode = (ProxyNode) i;
+            addToLatestSorting(proxyNode.value(), state);
             return;
         }
 
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Fri Jan 30 11:56:24 2015 -0800
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Sun Feb 01 20:57:56 2015 -0800
@@ -619,7 +619,8 @@
                 if (MethodsElidedInSnippets != null && methodToParse.getSignature().getReturnKind() == Kind.Void && MethodFilter.matches(MethodsElidedInSnippets, methodToParse)) {
                     graph.addAfterFixed(graph.start(), graph.add(new ReturnNode(null)));
                 } else {
-                    createGraphBuilder(metaAccess, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE).apply(graph);
+                    createGraphBuilder(metaAccess, replacements.providers.getStampProvider(), replacements.assumptions, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE).apply(
+                                    graph);
                 }
                 afterParsing(graph);
 
@@ -632,8 +633,9 @@
             return graph;
         }
 
-        protected Instance createGraphBuilder(MetaAccessProvider metaAccess, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts) {
-            return new GraphBuilderPhase.Instance(metaAccess, graphBuilderConfig, optimisticOpts);
+        protected Instance createGraphBuilder(MetaAccessProvider metaAccess, StampProvider stampProvider, Assumptions assumptions, GraphBuilderConfiguration graphBuilderConfig,
+                        OptimisticOptimizations optimisticOpts) {
+            return new GraphBuilderPhase.Instance(metaAccess, stampProvider, assumptions, graphBuilderConfig, optimisticOpts);
         }
 
         protected void afterParsing(StructuredGraph graph) {
--- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java	Fri Jan 30 11:56:24 2015 -0800
+++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java	Sun Feb 01 20:57:56 2015 -0800
@@ -177,7 +177,7 @@
         Suites suites = suitesProvider.createSuites();
         removeInliningPhase(suites);
         StructuredGraph graph = new StructuredGraph(javaMethod);
-        new GraphBuilderPhase.Instance(metaAccess, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph);
+        new GraphBuilderPhase.Instance(metaAccess, providers.getStampProvider(), new Assumptions(false), GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph);
         PhaseSuite<HighTierContext> graphBuilderSuite = getGraphBuilderSuite(suitesProvider);
         CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, graph.method(), false);
         Backend backend = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend();
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java	Fri Jan 30 11:56:24 2015 -0800
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java	Sun Feb 01 20:57:56 2015 -0800
@@ -94,13 +94,13 @@
 
     public StructuredGraph createInlineGraph(String name) {
         StructuredGraph graph = new StructuredGraph(name, callInlinedMethod);
-        new GraphBuilderPhase.Instance(providers.getMetaAccess(), config, TruffleCompilerImpl.Optimizations).apply(graph);
+        new GraphBuilderPhase.Instance(providers.getMetaAccess(), providers.getStampProvider(), new Assumptions(false), config, TruffleCompilerImpl.Optimizations).apply(graph);
         return graph;
     }
 
     public StructuredGraph createRootGraph(String name) {
         StructuredGraph graph = new StructuredGraph(name, callRootMethod);
-        new GraphBuilderPhase.Instance(providers.getMetaAccess(), configForRoot, TruffleCompilerImpl.Optimizations).apply(graph);
+        new GraphBuilderPhase.Instance(providers.getMetaAccess(), providers.getStampProvider(), new Assumptions(false), configForRoot, TruffleCompilerImpl.Optimizations).apply(graph);
         return graph;
     }
 
@@ -294,7 +294,7 @@
 
     protected StructuredGraph parseGraph(final ResolvedJavaMethod method, final PhaseContext phaseContext) {
         final StructuredGraph graph = new StructuredGraph(method);
-        new GraphBuilderPhase.Instance(phaseContext.getMetaAccess(), config, optimisticOptimizations).apply(graph);
+        new GraphBuilderPhase.Instance(phaseContext.getMetaAccess(), phaseContext.getStampProvider(), phaseContext.getAssumptions(), config, optimisticOptimizations).apply(graph);
         return graph;
     }
 
--- a/mx/suite.py	Fri Jan 30 11:56:24 2015 -0800
+++ b/mx/suite.py	Sun Feb 01 20:57:56 2015 -0800
@@ -818,6 +818,7 @@
         "com.oracle.graal.phases",
       ],
       "checkstyle" : "com.oracle.graal.graph",
+      "annotationProcessors" : ["com.oracle.graal.service.processor"],
       "javaCompliance" : "1.8",
       "workingSets" : "Graal,Java",
     },