changeset 19276:313f9a9647e5

Merge (rename LowLevel{Phases,..} to LIR{Phases,..})
author Josef Eisl <josef.eisl@jku.at>
date Wed, 11 Feb 2015 16:08:50 +0100
parents ab81848b9264 (current diff) fdb93d2ed5c8 (diff)
children 6bef14568a54
files graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InfopointReasonTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/BackendTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/tutorial/InvokeGraal.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPluginsProvider.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPluginsProvider.java graal/com.oracle.graal.java/src/com/oracle/graal/java/StandardGraphBuilderPluginsProvider.java graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/TruffleEventReceiver.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/DefaultEventReceiver.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/SimpleEventReceiver.java
diffstat 177 files changed, 1571 insertions(+), 1442 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Assumptions.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Assumptions.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.api.code;
 
-import static com.oracle.graal.api.meta.MetaUtil.*;
-
 import java.io.*;
 import java.lang.invoke.*;
 import java.util.*;
@@ -31,7 +29,9 @@
 import com.oracle.graal.api.meta.*;
 
 /**
- * Class for recording optimistic assumptions made during compilation.
+ * Class for recording assumptions made during compilation. {@link OptimisticAssumption}s can only
+ * be recorded in an {@link Assumptions} object if it {@linkplain #useOptimisticAssumptions()
+ * allows} them.
  */
 public final class Assumptions implements Serializable, Iterable<Assumptions.Assumption> {
 
@@ -45,7 +45,24 @@
         private static final long serialVersionUID = -1936652569665112915L;
     }
 
-    public static final class NoFinalizableSubclass extends Assumption {
+    /**
+     * Abstract base class for optimistic assumptions. An optimistic assumption assumes a property
+     * of the runtime that may be invalidated by subsequent execution (e.g., that a class has no
+     * subclasses implementing {@link NoFinalizableSubclass Object.finalize()}). A non-optimistic
+     * assumption assumes a property that will most likely only be invalidated by an external
+     * interface to the runtime (e.g., a {@linkplain MethodContents breakpoint is set or a class is
+     * redefined}).
+     */
+    public abstract static class OptimisticAssumption extends Assumption {
+
+        private static final long serialVersionUID = -1936652569665112932L;
+    }
+
+    /**
+     * An optimistic assumption that a given class has no subclasses implementing
+     * {@link Object#finalize()}).
+     */
+    public static final class NoFinalizableSubclass extends OptimisticAssumption {
 
         private static final long serialVersionUID = 6451169735564055081L;
 
@@ -77,9 +94,9 @@
     }
 
     /**
-     * An assumption about a unique subtype of a given type.
+     * An optimistic assumption that a given type has a given unique subtype.
      */
-    public static final class ConcreteSubtype extends Assumption {
+    public static final class ConcreteSubtype extends OptimisticAssumption {
 
         private static final long serialVersionUID = -1457173265437676252L;
 
@@ -125,9 +142,9 @@
     }
 
     /**
-     * An assumption about a unique implementation of a virtual method.
+     * An optimistic assumption that a given virtual method has a given unique implementation.
      */
-    public static final class ConcreteMethod extends Assumption {
+    public static final class ConcreteMethod extends OptimisticAssumption {
 
         private static final long serialVersionUID = -7636746737947390059L;
 
@@ -174,12 +191,19 @@
 
         @Override
         public String toString() {
-            return "ConcreteMethod[method=" + method.format("%H.%n(%p)") + ", context=" + context.toJavaName() + ", impl=" + impl.format("%H.%n(%p)") + "]";
+            return "ConcreteMethod[method=" + method.format("%H.%n(%p)%r") + ", context=" + context.toJavaName() + ", impl=" + impl.format("%H.%n(%p)%r") + "]";
         }
     }
 
     /**
-     * An assumption that specified that a method was used during the compilation.
+     * An non-optimistic assumption that the bytecodes of a given method used during compilation
+     * will not change. This kind of dependency may be used to invalidate and deoptimize compiled
+     * code when:
+     * <ul>
+     * <li>one of its constituent methods is redefined or</li>
+     * <li>a breakpoint is set in one of its constituent methods and the runtime only implements
+     * breakpoint support in non-compiled code.
+     * </ul>
      */
     public static final class MethodContents extends Assumption {
 
@@ -207,14 +231,14 @@
 
         @Override
         public String toString() {
-            return "MethodContents[method=" + method.format("%H.%n(%p)") + "]";
+            return "MethodContents[method=" + method.format("%H.%n(%p)%r") + "]";
         }
     }
 
     /**
-     * Assumption that a call site's method handle did not change.
+     * An optimistic assumption that a given call site's method handle did not change.
      */
-    public static final class CallSiteTargetValue extends Assumption {
+    public static final class CallSiteTargetValue extends OptimisticAssumption {
 
         private static final long serialVersionUID = 1732459941784550371L;
 
@@ -250,17 +274,25 @@
         }
     }
 
+    private Set<Assumption> assumptions;
+
     /**
-     * Array with the assumptions. This field is directly accessed from C++ code in the
-     * Graal/HotSpot implementation.
+     * Specifies whether {@link OptimisticAssumption}s can be made.
      */
-    private Assumption[] list;
-    private boolean useOptimisticAssumptions;
-    private int count;
+    private boolean allowOptimisticAssumptions;
+
+    public static final boolean ALLOW_OPTIMISTIC_ASSUMPTIONS = true;
+    public static final boolean DONT_ALLOW_OPTIMISTIC_ASSUMPTIONS = false;
 
-    public Assumptions(boolean useOptimisticAssumptions) {
-        this.useOptimisticAssumptions = useOptimisticAssumptions;
-        list = new Assumption[4];
+    /**
+     * Creates an object for recording assumptions.
+     *
+     * @param allowOptimisticAssumptions specifies whether {@link OptimisticAssumption}s can be
+     *            recorded in this object
+     */
+    public Assumptions(boolean allowOptimisticAssumptions) {
+        this.allowOptimisticAssumptions = allowOptimisticAssumptions;
+        assumptions = new HashSet<>();
     }
 
     /**
@@ -269,11 +301,14 @@
      * @return {@code true} if at least one assumption has been registered, {@code false} otherwise.
      */
     public boolean isEmpty() {
-        return count == 0;
+        return assumptions.isEmpty();
     }
 
+    /**
+     * Determines whether {@link OptimisticAssumption}s can be made.
+     */
     public boolean useOptimisticAssumptions() {
-        return useOptimisticAssumptions;
+        return allowOptimisticAssumptions;
     }
 
     @Override
@@ -282,25 +317,15 @@
     }
 
     @Override
-    public String toString() {
-        return identityHashCodeString(this);
-    }
-
-    @Override
     public boolean equals(Object obj) {
         if (this == obj) {
             return true;
         }
         if (obj instanceof Assumptions) {
             Assumptions that = (Assumptions) obj;
-            if (useOptimisticAssumptions != that.useOptimisticAssumptions || count != that.count) {
+            if (this.allowOptimisticAssumptions != that.allowOptimisticAssumptions || !this.assumptions.equals(that.assumptions)) {
                 return false;
             }
-            for (int i = 0; i < count; i++) {
-                if (!list[i].equals(that.list[i])) {
-                    return false;
-                }
-            }
             return true;
         }
         return false;
@@ -308,28 +333,7 @@
 
     @Override
     public Iterator<Assumption> iterator() {
-        return new Iterator<Assumptions.Assumption>() {
-
-            int index;
-
-            @Override
-            public void remove() {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public Assumption next() {
-                if (index >= count) {
-                    throw new NoSuchElementException();
-                }
-                return list[index++];
-            }
-
-            @Override
-            public boolean hasNext() {
-                return index < count;
-            }
-        };
+        return assumptions.iterator();
     }
 
     /**
@@ -338,7 +342,6 @@
      * @param receiverType the type that is assumed to have no finalizable subclasses
      */
     public void recordNoFinalizableSubclassAssumption(ResolvedJavaType receiverType) {
-        assert useOptimisticAssumptions;
         record(new NoFinalizableSubclass(receiverType));
     }
 
@@ -350,7 +353,6 @@
      * @param subtype the one concrete subtype
      */
     public void recordConcreteSubtype(ResolvedJavaType context, ResolvedJavaType subtype) {
-        assert useOptimisticAssumptions;
         record(new ConcreteSubtype(context, subtype));
     }
 
@@ -363,7 +365,6 @@
      * @param impl the concrete method that is the only possible target for the virtual call
      */
     public void recordConcreteMethod(ResolvedJavaMethod method, ResolvedJavaType context, ResolvedJavaMethod impl) {
-        assert useOptimisticAssumptions;
         record(new ConcreteMethod(method, context, impl));
     }
 
@@ -377,50 +378,27 @@
     }
 
     public void record(Assumption assumption) {
-        if (list == null) {
-            list = new Assumption[4];
-        } else {
-            for (int i = 0; i < count; ++i) {
-                if (assumption.equals(list[i])) {
-                    return;
-                }
-            }
-        }
-        if (list.length == count) {
-            Assumption[] newList = new Assumption[list.length * 2];
-            for (int i = 0; i < list.length; ++i) {
-                newList[i] = list[i];
-            }
-            list = newList;
-        }
-        list[count] = assumption;
-        count++;
+        assert allowOptimisticAssumptions || !(assumption instanceof OptimisticAssumption) : "cannot make optimistic assumption: " + assumption;
+        assumptions.add(assumption);
     }
 
-    public Assumption[] getAssumptions() {
-        return list;
+    /**
+     * Gets a copy of the assumptions recorded in this object as an array.
+     */
+    public Assumption[] toArray() {
+        return assumptions.toArray(new Assumption[assumptions.size()]);
     }
 
-    public void record(Assumptions assumptions) {
-        for (int i = 0; i < assumptions.count; i++) {
-            record(assumptions.list[i]);
-        }
+    /**
+     * Copies assumptions recorded by another {@link Assumptions} object into this object.
+     */
+    public void record(Assumptions other) {
+        assert other != this;
+        assumptions.addAll(other.assumptions);
     }
 
-    public void print(PrintStream out) {
-        List<Assumption> nonNullList = new ArrayList<>();
-        if (list != null) {
-            for (int i = 0; i < list.length; ++i) {
-                Assumption a = list[i];
-                if (a != null) {
-                    nonNullList.add(a);
-                }
-            }
-        }
-
-        out.printf("%d assumptions:%n", nonNullList.size());
-        for (Assumption a : nonNullList) {
-            out.println(a.toString());
-        }
+    @Override
+    public String toString() {
+        return "Assumptions{optimistic=" + allowOptimisticAssumptions + ", assumptions=" + assumptions + "}";
     }
 }
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java	Wed Feb 11 16:08:50 2015 +0100
@@ -28,6 +28,7 @@
 import java.io.*;
 import java.util.*;
 
+import com.oracle.graal.api.code.Assumptions.Assumption;
 import com.oracle.graal.api.code.CodeUtil.RefMapFormatter;
 import com.oracle.graal.api.meta.*;
 
@@ -528,7 +529,7 @@
 
     private ArrayList<CodeAnnotation> annotations;
 
-    private Assumptions assumptions;
+    private Assumption[] assumptions;
 
     public CompilationResult() {
         this(null);
@@ -564,12 +565,12 @@
                 this.targetCodeSize == that.targetCodeSize &&
                 Objects.equals(this.name, that.name) &&
                 Objects.equals(this.annotations, that.annotations) &&
-                Objects.equals(this.assumptions, that.assumptions) &&
                 Objects.equals(this.dataSection, that.dataSection) &&
                 Objects.equals(this.exceptionHandlers, that.exceptionHandlers) &&
                 Objects.equals(this.dataPatches, that.dataPatches) &&
                 Objects.equals(this.infopoints, that.infopoints) &&
                 Objects.equals(this.marks,  that.marks) &&
+                Arrays.equals(this.assumptions, that.assumptions) &&
                 Arrays.equals(targetCode, that.targetCode)) {
                 return true;
             }
@@ -606,12 +607,16 @@
         this.entryBCI = entryBCI;
     }
 
-    public void setAssumptions(Assumptions assumptions) {
+    public void setAssumptions(Assumption[] assumptions) {
         this.assumptions = assumptions;
     }
 
-    public Assumptions getAssumptions() {
-        return assumptions;
+    /**
+     * Gets a fixed-size {@linkplain Arrays#asList(Object...) view} of the assumptions recorded in
+     * this object.
+     */
+    public Collection<Assumption> getAssumptions() {
+        return assumptions == null ? Collections.emptyList() : Arrays.asList(assumptions);
     }
 
     public DataSection getDataSection() {
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/GraalOptions.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/GraalOptions.java	Wed Feb 11 16:08:50 2015 +0100
@@ -63,6 +63,9 @@
     @Option(help = "Inlines trivial methods during parsing of the bytecodes.", type = OptionType.Expert)
     public static final StableOptionValue<Boolean> InlineDuringParsing = new StableOptionValue<>(false);
 
+    @Option(help = "Traces .", type = OptionType.Debug)
+    public static final StableOptionValue<Boolean> TraceInlineDuringParsing = new StableOptionValue<>(false);
+
     @Option(help = "Maximum depth when inlining during parsing.", type = OptionType.Debug)
     public static final StableOptionValue<Integer> InlineDuringParsingMaxDepth = new StableOptionValue<>(10);
 
@@ -119,23 +122,11 @@
     public static final OptionValue<Boolean> LoopUnswitch = new OptionValue<>(true);
 
     @Option(help = "", type = OptionType.Expert)
-    public static final OptionValue<Integer> FullUnrollMaxNodes = new OptionValue<>(300);
-
-    @Option(help = "", type = OptionType.Expert)
-    public static final OptionValue<Integer> ExactFullUnrollMaxNodes = new OptionValue<>(1200);
-
-    @Option(help = "", type = OptionType.Expert)
     public static final OptionValue<Float> MinimumPeelProbability = new OptionValue<>(0.35f);
 
     @Option(help = "", type = OptionType.Expert)
     public static final OptionValue<Integer> LoopMaxUnswitch = new OptionValue<>(3);
 
-    @Option(help = "", type = OptionType.Expert)
-    public static final OptionValue<Integer> LoopUnswitchMaxIncrease = new OptionValue<>(50);
-
-    @Option(help = "", type = OptionType.Expert)
-    public static final OptionValue<Integer> LoopUnswitchUncertaintyBoost = new OptionValue<>(5);
-
     @Option(help = "", type = OptionType.Debug)
     public static final OptionValue<Boolean> UseLoopLimitChecks = new OptionValue<>(true);
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,9 +22,10 @@
  */
 package com.oracle.graal.compiler.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
+
 import org.junit.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.loop.phases.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.phases.*;
@@ -305,9 +306,8 @@
     }
 
     private void processMethod(final String snippet) {
-        graph = parseEager(snippet);
-        Assumptions assumptions = new Assumptions(false);
-        HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+        graph = parseEager(snippet, DONT_ALLOW_OPTIMISTIC_ASSUMPTIONS);
+        HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
         new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
         new PartialEscapePhase(false, new CanonicalizerPhase(true)).apply(graph, context);
     }
@@ -317,10 +317,8 @@
     }
 
     private void compareGraphs(final String snippet, final String referenceSnippet, final boolean loopPeeling, final boolean excludeVirtual) {
-        graph = parseEager(snippet);
-
-        Assumptions assumptions = new Assumptions(false);
-        HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+        graph = parseEager(snippet, DONT_ALLOW_OPTIMISTIC_ASSUMPTIONS);
+        HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
         CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true);
         canonicalizer.apply(graph, context);
         new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
@@ -334,7 +332,7 @@
         new DeadCodeEliminationPhase().apply(graph);
         canonicalizer.apply(graph, context);
 
-        StructuredGraph referenceGraph = parseEager(referenceSnippet);
+        StructuredGraph referenceGraph = parseEager(referenceSnippet, ALLOW_OPTIMISTIC_ASSUMPTIONS);
         new InliningPhase(new CanonicalizerPhase(true)).apply(referenceGraph, context);
         new DeadCodeEliminationPhase().apply(referenceGraph);
         new CanonicalizerPhase(true).apply(referenceGraph, context);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.compiler.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
 import static com.oracle.graal.debug.DelegatingDebugConfig.Feature.*;
 
 import java.io.*;
@@ -69,7 +70,7 @@
 
         PhaseSuite<HighTierContext> graphBuilderSuite = new PhaseSuite<>();
         graphBuilderSuite.appendPhase(new GraphBuilderPhase(GraphBuilderConfiguration.getEagerDefault()));
-        HighTierContext context = new HighTierContext(providers, new Assumptions(false), null, graphBuilderSuite, OptimisticOptimizations.NONE);
+        HighTierContext context = new HighTierContext(providers, null, graphBuilderSuite, OptimisticOptimizations.NONE);
 
         Assume.assumeTrue(VerifyPhase.class.desiredAssertionStatus());
 
@@ -138,7 +139,7 @@
                         if (matches(filters, methodName)) {
                             executor.execute(() -> {
                                 ResolvedJavaMethod method = metaAccess.lookupJavaMethod(m);
-                                StructuredGraph graph = new StructuredGraph(method);
+                                StructuredGraph graph = new StructuredGraph(method, DONT_ALLOW_OPTIMISTIC_ASSUMPTIONS);
                                 try (DebugConfigScope s = Debug.setConfig(new DelegatingDebugConfig().disable(INTERCEPT)); Debug.Scope ds = Debug.scope("CheckingGraph", graph, method)) {
                                     graphBuilderSuite.apply(graph, context);
                                     // update phi stamps
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CompareCanonicalizerTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CompareCanonicalizerTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,11 +22,11 @@
  */
 package com.oracle.graal.compiler.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
 import static org.junit.Assert.*;
 
 import org.junit.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.phases.common.*;
@@ -35,8 +35,8 @@
 public class CompareCanonicalizerTest extends GraalCompilerTest {
 
     private StructuredGraph getCanonicalizedGraph(String name) {
-        StructuredGraph graph = parseEager(name);
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null));
+        StructuredGraph graph = parseEager(name, ALLOW_OPTIMISTIC_ASSUMPTIONS);
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders()));
         return graph;
     }
 
@@ -48,13 +48,12 @@
 
     @Test
     public void testCanonicalComparison() {
-        StructuredGraph referenceGraph = parseEager("referenceCanonicalComparison");
+        StructuredGraph referenceGraph = parseEager("referenceCanonicalComparison", DONT_ALLOW_OPTIMISTIC_ASSUMPTIONS);
         for (int i = 1; i < 4; i++) {
-            StructuredGraph graph = parseEager("canonicalCompare" + i);
+            StructuredGraph graph = parseEager("canonicalCompare" + i, DONT_ALLOW_OPTIMISTIC_ASSUMPTIONS);
             assertEquals(referenceGraph, graph);
         }
-        Assumptions assumptions = new Assumptions(false);
-        new CanonicalizerPhase(true).apply(referenceGraph, new PhaseContext(getProviders(), assumptions));
+        new CanonicalizerPhase(true).apply(referenceGraph, new PhaseContext(getProviders()));
         for (int i = 1; i < 4; i++) {
             StructuredGraph graph = getCanonicalizedGraph("canonicalCompare" + i);
             assertEquals(referenceGraph, graph);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.compiler.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
+
 import org.junit.*;
 
 import com.oracle.graal.nodes.*;
@@ -90,9 +92,9 @@
 
     @Test
     public void testRedundantCompares() {
-        StructuredGraph graph = parseEager("testRedundantComparesSnippet");
+        StructuredGraph graph = parseEager("testRedundantComparesSnippet", ALLOW_OPTIMISTIC_ASSUMPTIONS);
         CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true);
-        PhaseContext context = new PhaseContext(getProviders(), null);
+        PhaseContext context = new PhaseContext(getProviders());
 
         new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
         canonicalizer.apply(graph, context);
@@ -113,10 +115,10 @@
     @Test
     @Ignore
     public void testInstanceOfCheckCastLowered() {
-        StructuredGraph graph = parseEager("testInstanceOfCheckCastSnippet");
+        StructuredGraph graph = parseEager("testInstanceOfCheckCastSnippet", ALLOW_OPTIMISTIC_ASSUMPTIONS);
 
         CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true);
-        PhaseContext context = new PhaseContext(getProviders(), null);
+        PhaseContext context = new PhaseContext(getProviders());
 
         new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
         canonicalizer.apply(graph, context);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/DegeneratedLoopsTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/DegeneratedLoopsTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,9 +22,10 @@
  */
 package com.oracle.graal.compiler.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
+
 import org.junit.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.nodes.*;
@@ -81,12 +82,12 @@
 
     private void test(final String snippet) {
         try (Scope s = Debug.scope("DegeneratedLoopsTest", new DebugDumpScope(snippet))) {
-            StructuredGraph graph = parseEager(snippet);
-            HighTierContext context = new HighTierContext(getProviders(), new Assumptions(false), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+            StructuredGraph graph = parseEager(snippet, ALLOW_OPTIMISTIC_ASSUMPTIONS);
+            HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
             new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
             new CanonicalizerPhase(true).apply(graph, context);
             Debug.dump(graph, "Graph");
-            StructuredGraph referenceGraph = parseEager(REFERENCE_SNIPPET);
+            StructuredGraph referenceGraph = parseEager(REFERENCE_SNIPPET, ALLOW_OPTIMISTIC_ASSUMPTIONS);
             Debug.dump(referenceGraph, "ReferenceGraph");
             assertEquals(referenceGraph, graph);
         } catch (Throwable e) {
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/EliminateNestedCheckCastsTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/EliminateNestedCheckCastsTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,9 +22,10 @@
  */
 package com.oracle.graal.compiler.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
+
 import org.junit.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.nodes.*;
@@ -106,11 +107,11 @@
     }
 
     private StructuredGraph compileSnippet(final String snippet, final int checkcasts, final int afterCanon) {
-        final StructuredGraph graph = parseEager(snippet);
+        final StructuredGraph graph = parseEager(snippet, ALLOW_OPTIMISTIC_ASSUMPTIONS);
         try (Scope s = Debug.scope("NestedCheckCastsTest", graph)) {
             Debug.dump(graph, "After parsing: " + snippet);
             Assert.assertEquals(checkcasts, graph.getNodes().filter(CheckCastNode.class).count());
-            new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), new Assumptions(false)));
+            new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders()));
             Assert.assertEquals(afterCanon, graph.getNodes().filter(CheckCastNode.class).count());
             return graph;
         } catch (Throwable e) {
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,13 +22,14 @@
  */
 package com.oracle.graal.compiler.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
+
 import java.io.*;
 import java.lang.reflect.*;
 import java.util.*;
 
 import org.junit.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.code.Assumptions.Assumption;
 import com.oracle.graal.api.code.Assumptions.NoFinalizableSubclass;
 import com.oracle.graal.api.meta.*;
@@ -60,26 +61,25 @@
         }
     }
 
-    private StructuredGraph parseAndProcess(Class<?> cl, Assumptions assumptions) {
+    private StructuredGraph parseAndProcess(Class<?> cl, boolean allowsOptimisticAssumptions) {
         Constructor<?>[] constructors = cl.getConstructors();
         Assert.assertTrue(constructors.length == 1);
         final ResolvedJavaMethod javaMethod = getMetaAccess().lookupJavaMethod(constructors[0]);
-        StructuredGraph graph = new StructuredGraph(javaMethod);
+        StructuredGraph graph = new StructuredGraph(javaMethod, allowsOptimisticAssumptions);
 
         GraphBuilderConfiguration conf = GraphBuilderConfiguration.getSnippetDefault();
-        new GraphBuilderPhase.Instance(getMetaAccess(), getProviders().getStampProvider(), assumptions, getProviders().getConstantReflection(), conf, OptimisticOptimizations.ALL).apply(graph);
-        HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+        new GraphBuilderPhase.Instance(getMetaAccess(), getProviders().getStampProvider(), getProviders().getConstantReflection(), conf, OptimisticOptimizations.ALL).apply(graph);
+        HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
         new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
         new CanonicalizerPhase(true).apply(graph, context);
         return graph;
     }
 
-    private void checkForRegisterFinalizeNode(Class<?> cl, boolean shouldContainFinalizer, boolean optimistic) {
-        Assumptions assumptions = new Assumptions(optimistic);
-        StructuredGraph graph = parseAndProcess(cl, assumptions);
+    private void checkForRegisterFinalizeNode(Class<?> cl, boolean shouldContainFinalizer, boolean allowsOptimisticAssumptions) {
+        StructuredGraph graph = parseAndProcess(cl, allowsOptimisticAssumptions);
         Assert.assertTrue(graph.getNodes().filter(RegisterFinalizerNode.class).count() == (shouldContainFinalizer ? 1 : 0));
         int noFinalizerAssumption = 0;
-        for (Assumption a : assumptions) {
+        for (Assumption a : graph.getAssumptions()) {
             if (a instanceof NoFinalizableSubclass) {
                 noFinalizerAssumption++;
             }
@@ -95,13 +95,13 @@
     public void test1() throws ClassNotFoundException {
         for (int i = 0; i < 2; i++) {
             ClassTemplateLoader loader = new ClassTemplateLoader();
-            checkForRegisterFinalizeNode(loader.findClass("NoFinalizerEverAAAA"), true, false);
-            checkForRegisterFinalizeNode(loader.findClass("NoFinalizerEverAAAA"), false, true);
+            checkForRegisterFinalizeNode(loader.findClass("NoFinalizerEverAAAA"), true, DONT_ALLOW_OPTIMISTIC_ASSUMPTIONS);
+            checkForRegisterFinalizeNode(loader.findClass("NoFinalizerEverAAAA"), false, ALLOW_OPTIMISTIC_ASSUMPTIONS);
 
-            checkForRegisterFinalizeNode(loader.findClass("NoFinalizerYetAAAA"), false, true);
+            checkForRegisterFinalizeNode(loader.findClass("NoFinalizerYetAAAA"), false, ALLOW_OPTIMISTIC_ASSUMPTIONS);
 
-            checkForRegisterFinalizeNode(loader.findClass("WithFinalizerAAAA"), true, true);
-            checkForRegisterFinalizeNode(loader.findClass("NoFinalizerYetAAAA"), true, true);
+            checkForRegisterFinalizeNode(loader.findClass("WithFinalizerAAAA"), true, ALLOW_OPTIMISTIC_ASSUMPTIONS);
+            checkForRegisterFinalizeNode(loader.findClass("NoFinalizerYetAAAA"), true, ALLOW_OPTIMISTIC_ASSUMPTIONS);
         }
     }
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FloatingReadTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FloatingReadTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,9 +22,10 @@
  */
 package com.oracle.graal.compiler.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
+
 import org.junit.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.graph.*;
@@ -58,8 +59,8 @@
     private void test(final String snippet) {
         try (Scope s = Debug.scope("FloatingReadTest", new DebugDumpScope(snippet))) {
 
-            StructuredGraph graph = parseEager(snippet);
-            PhaseContext context = new PhaseContext(getProviders(), new Assumptions(false));
+            StructuredGraph graph = parseEager(snippet, ALLOW_OPTIMISTIC_ASSUMPTIONS);
+            PhaseContext context = new PhaseContext(getProviders());
             new LoweringPhase(new CanonicalizerPhase(true), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
             new FloatingReadPhase().apply(graph);
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.compiler.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
 import static com.oracle.graal.api.code.CodeUtil.*;
 import static com.oracle.graal.compiler.GraalCompiler.*;
 import static com.oracle.graal.compiler.common.GraalOptions.*;
@@ -71,7 +72,7 @@
  * <p>
  * White box tests for Graal compiler transformations use this pattern:
  * <ol>
- * <li>Create a graph by {@linkplain #parseEager(String) parsing} a method.</li>
+ * <li>Create a graph by {@linkplain #parseEager(String, boolean) parsing} a method.</li>
  * <li>Manually modify the graph (e.g. replace a parameter node with a constant).</li>
  * <li>Apply a transformation to the graph.</li>
  * <li>Assert that the transformed graph is equal to an expected graph.</li>
@@ -661,7 +662,7 @@
 
     /**
      * Gets installed code for a given method, compiling it first if necessary. The graph is parsed
-     * {@link #parseEager(ResolvedJavaMethod) eagerly}.
+     * {@link #parseEager(ResolvedJavaMethod, boolean) eagerly}.
      */
     protected InstalledCode getCode(ResolvedJavaMethod method) {
         return getCode(method, null);
@@ -735,10 +736,10 @@
      * is null.
      *
      * The default implementation in {@link GraalCompilerTest} is to call
-     * {@link #parseEager(ResolvedJavaMethod)}.
+     * {@link #parseEager(ResolvedJavaMethod, boolean)}.
      */
     protected StructuredGraph parseForCompile(ResolvedJavaMethod method) {
-        return parseEager(method);
+        return parseEager(method, ALLOW_OPTIMISTIC_ASSUMPTIONS);
     }
 
     /**
@@ -815,16 +816,16 @@
      *
      * @param methodName the name of the method in {@code this.getClass()} to be parsed
      */
-    protected StructuredGraph parseProfiled(String methodName) {
-        return parseProfiled(getResolvedJavaMethod(methodName));
+    protected StructuredGraph parseProfiled(String methodName, boolean allowOptimisticAssumptions) {
+        return parseProfiled(getResolvedJavaMethod(methodName), allowOptimisticAssumptions);
     }
 
     /**
      * Parses a Java method in {@linkplain GraphBuilderConfiguration#getDefault() default} mode to
      * produce a graph.
      */
-    protected StructuredGraph parseProfiled(ResolvedJavaMethod m) {
-        return parse1(m, getDefaultGraphBuilderSuite());
+    protected StructuredGraph parseProfiled(ResolvedJavaMethod m, boolean allowOptimisticAssumptions) {
+        return parse1(m, getDefaultGraphBuilderSuite(), allowOptimisticAssumptions);
     }
 
     /**
@@ -833,31 +834,31 @@
      *
      * @param methodName the name of the method in {@code this.getClass()} to be parsed
      */
-    protected StructuredGraph parseEager(String methodName) {
-        return parseEager(getResolvedJavaMethod(methodName));
+    protected StructuredGraph parseEager(String methodName, boolean allowOptimisticAssumptions) {
+        return parseEager(getResolvedJavaMethod(methodName), allowOptimisticAssumptions);
     }
 
     /**
      * Parses a Java method in {@linkplain GraphBuilderConfiguration#getEagerDefault() eager} mode
      * to produce a graph.
      */
-    protected StructuredGraph parseEager(ResolvedJavaMethod m) {
-        return parse1(m, getCustomGraphBuilderSuite(GraphBuilderConfiguration.getEagerDefault()));
+    protected StructuredGraph parseEager(ResolvedJavaMethod m, boolean allowOptimisticAssumptions) {
+        return parse1(m, getCustomGraphBuilderSuite(GraphBuilderConfiguration.getEagerDefault()), allowOptimisticAssumptions);
     }
 
     /**
      * Parses a Java method in {@linkplain GraphBuilderConfiguration#getFullDebugDefault() full
      * debug} mode to produce a graph.
      */
-    protected StructuredGraph parseDebug(ResolvedJavaMethod m) {
-        return parse1(m, getCustomGraphBuilderSuite(GraphBuilderConfiguration.getFullDebugDefault()));
+    protected StructuredGraph parseDebug(ResolvedJavaMethod m, boolean allowOptimisticAssumptions) {
+        return parse1(m, getCustomGraphBuilderSuite(GraphBuilderConfiguration.getFullDebugDefault()), allowOptimisticAssumptions);
     }
 
-    private StructuredGraph parse1(ResolvedJavaMethod javaMethod, PhaseSuite<HighTierContext> graphBuilderSuite) {
+    private StructuredGraph parse1(ResolvedJavaMethod javaMethod, PhaseSuite<HighTierContext> graphBuilderSuite, boolean allowOptimisticAssumptions) {
         assert javaMethod.getAnnotation(Test.class) == null : "shouldn't parse method with @Test annotation: " + javaMethod;
         try (Scope ds = Debug.scope("Parsing", javaMethod)) {
-            StructuredGraph graph = new StructuredGraph(javaMethod);
-            graphBuilderSuite.apply(graph, new HighTierContext(providers, null, null, graphBuilderSuite, OptimisticOptimizations.ALL));
+            StructuredGraph graph = new StructuredGraph(javaMethod, allowOptimisticAssumptions);
+            graphBuilderSuite.apply(graph, new HighTierContext(providers, null, graphBuilderSuite, OptimisticOptimizations.ALL));
             return graph;
         } catch (Throwable e) {
             throw Debug.handle(e);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IfCanonicalizerTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IfCanonicalizerTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,11 +22,11 @@
  */
 package com.oracle.graal.compiler.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
 import static com.oracle.graal.graph.iterators.NodePredicates.*;
 
 import org.junit.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
@@ -180,11 +180,11 @@
     }
 
     private void testCombinedIf(String snippet, int count) {
-        StructuredGraph graph = parseEager(snippet);
-        PhaseContext context = new PhaseContext(getProviders(), new Assumptions(false));
+        StructuredGraph graph = parseEager(snippet, ALLOW_OPTIMISTIC_ASSUMPTIONS);
+        PhaseContext context = new PhaseContext(getProviders());
         new LoweringPhase(new CanonicalizerPhase(true), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
         new FloatingReadPhase().apply(graph);
-        MidTierContext midContext = new MidTierContext(getProviders(), new Assumptions(false), getCodeCache().getTarget(), OptimisticOptimizations.ALL, graph.method().getProfilingInfo(), null);
+        MidTierContext midContext = new MidTierContext(getProviders(), getCodeCache().getTarget(), OptimisticOptimizations.ALL, graph.method().getProfilingInfo(), null);
         new GuardLoweringPhase().apply(graph, midContext);
         new LoweringPhase(new CanonicalizerPhase(true), LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, midContext);
         new ValueAnchorCleanupPhase().apply(graph);
@@ -193,19 +193,19 @@
     }
 
     private void test(String snippet) {
-        StructuredGraph graph = parseEager(snippet);
+        StructuredGraph graph = parseEager(snippet, ALLOW_OPTIMISTIC_ASSUMPTIONS);
         ParameterNode param = graph.getNodes(ParameterNode.class).iterator().next();
         ConstantNode constant = ConstantNode.forInt(0, graph);
         for (Node n : param.usages().filter(isNotA(FrameState.class)).snapshot()) {
             n.replaceFirstInput(param, constant);
         }
         Debug.dump(graph, "Graph");
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), new Assumptions(false)));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders()));
         for (FrameState fs : param.usages().filter(FrameState.class).snapshot()) {
             fs.replaceFirstInput(param, null);
             param.safeDelete();
         }
-        StructuredGraph referenceGraph = parseEager(REFERENCE_SNIPPET);
+        StructuredGraph referenceGraph = parseEager(REFERENCE_SNIPPET, ALLOW_OPTIMISTIC_ASSUMPTIONS);
         assertEquals(referenceGraph, graph);
     }
 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InfopointReasonTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InfopointReasonTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,8 +22,10 @@
  */
 package com.oracle.graal.compiler.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
 import static com.oracle.graal.api.code.CodeUtil.*;
 import static com.oracle.graal.compiler.GraalCompiler.*;
+import static com.oracle.graal.compiler.common.GraalOptions.*;
 import static org.junit.Assert.*;
 
 import org.junit.*;
@@ -58,7 +60,7 @@
     @Test
     public void callInfopoints() {
         final ResolvedJavaMethod method = getResolvedJavaMethod("testMethod");
-        final StructuredGraph graph = parseEager(method);
+        final StructuredGraph graph = parseEager(method, ALLOW_OPTIMISTIC_ASSUMPTIONS);
         CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false);
         final CompilationResult cr = compileGraph(graph, cc, graph.method(), getProviders(), getBackend(), getCodeCache().getTarget(), null, getDefaultGraphBuilderSuite(),
                         OptimisticOptimizations.ALL, getProfilingInfo(graph), null, getSuites(), getLIRSuites(), new CompilationResult(), CompilationResultBuilderFactory.Default);
@@ -73,7 +75,7 @@
     @Test
     public void lineInfopoints() {
         final ResolvedJavaMethod method = getResolvedJavaMethod("testMethod");
-        final StructuredGraph graph = parseDebug(method);
+        final StructuredGraph graph = parseDebug(method, OptAssumptions.getValue());
         int graphLineSPs = 0;
         for (FullInfopointNode ipn : graph.getNodes().filter(FullInfopointNode.class)) {
             if (ipn.getReason() == InfopointReason.LINE_NUMBER) {
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IntegerEqualsCanonicalizerTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IntegerEqualsCanonicalizerTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.compiler.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
+
 import org.junit.*;
 
 import com.oracle.graal.nodes.*;
@@ -112,8 +114,8 @@
     }
 
     private StructuredGraph getCanonicalizedGraph(String snippet) {
-        StructuredGraph graph = parseEager(snippet);
-        new CanonicalizerPhase(false).apply(graph, new PhaseContext(getProviders(), null));
+        StructuredGraph graph = parseEager(snippet, ALLOW_OPTIMISTIC_ASSUMPTIONS);
+        new CanonicalizerPhase(false).apply(graph, new PhaseContext(getProviders()));
         for (FrameState state : graph.getNodes(FrameState.class).snapshot()) {
             state.replaceAtUsages(null);
             state.safeDelete();
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeExceptionTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeExceptionTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,11 +22,11 @@
  */
 package com.oracle.graal.compiler.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
 import java.util.*;
 
 import org.junit.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
@@ -61,13 +61,12 @@
     }
 
     private void test(String snippet) {
-        StructuredGraph graph = parseProfiled(snippet);
+        StructuredGraph graph = parseProfiled(snippet, DONT_ALLOW_OPTIMISTIC_ASSUMPTIONS);
         Map<Invoke, Double> hints = new HashMap<>();
         for (Invoke invoke : graph.getInvokes()) {
             hints.put(invoke, 1000d);
         }
-        Assumptions assumptions = new Assumptions(false);
-        HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+        HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
         new InliningPhase(hints, new CanonicalizerPhase(true)).apply(graph, context);
         new CanonicalizerPhase(true).apply(graph, context);
         new DeadCodeEliminationPhase().apply(graph);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeHintsTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeHintsTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,11 +22,12 @@
  */
 package com.oracle.graal.compiler.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
+
 import java.util.*;
 
 import org.junit.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
@@ -71,18 +72,17 @@
     }
 
     private void test(String snippet) {
-        StructuredGraph graph = parseEager(snippet);
+        StructuredGraph graph = parseEager(snippet, DONT_ALLOW_OPTIMISTIC_ASSUMPTIONS);
         Map<Invoke, Double> hints = new HashMap<>();
         for (Invoke invoke : graph.getInvokes()) {
             hints.put(invoke, 1000d);
         }
 
-        Assumptions assumptions = new Assumptions(false);
-        HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+        HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
         new InliningPhase(hints, new CanonicalizerPhase(true)).apply(graph, context);
         new CanonicalizerPhase(true).apply(graph, context);
         new DeadCodeEliminationPhase().apply(graph);
-        StructuredGraph referenceGraph = parseEager(REFERENCE_SNIPPET);
+        StructuredGraph referenceGraph = parseEager(REFERENCE_SNIPPET, DONT_ALLOW_OPTIMISTIC_ASSUMPTIONS);
         assertEquals(referenceGraph, graph);
     }
 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LockEliminationTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LockEliminationTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,9 +22,10 @@
  */
 package com.oracle.graal.compiler.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
+
 import org.junit.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
@@ -62,7 +63,7 @@
         test("testSynchronizedSnippet", new A(), new A());
 
         StructuredGraph graph = getGraph("testSynchronizedSnippet");
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders()));
         new LockEliminationPhase().apply(graph);
         assertDeepEquals(1, graph.getNodes().filter(MonitorEnterNode.class).count());
         assertDeepEquals(1, graph.getNodes().filter(MonitorExitNode.class).count());
@@ -80,7 +81,7 @@
         test("testSynchronizedMethodSnippet", new A());
 
         StructuredGraph graph = getGraph("testSynchronizedMethodSnippet");
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders()));
         new LockEliminationPhase().apply(graph);
         assertDeepEquals(1, graph.getNodes().filter(MonitorEnterNode.class).count());
         assertDeepEquals(1, graph.getNodes().filter(MonitorExitNode.class).count());
@@ -88,9 +89,8 @@
 
     private StructuredGraph getGraph(String snippet) {
         ResolvedJavaMethod method = getResolvedJavaMethod(snippet);
-        StructuredGraph graph = parseEager(method);
-        Assumptions assumptions = new Assumptions(true);
-        HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+        StructuredGraph graph = parseEager(method, ALLOW_OPTIMISTIC_ASSUMPTIONS);
+        HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
         new CanonicalizerPhase(true).apply(graph, context);
         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/LoopUnswitchTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LoopUnswitchTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,9 +22,10 @@
  */
 package com.oracle.graal.compiler.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
+
 import org.junit.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.graph.*;
@@ -121,8 +122,8 @@
     }
 
     private void test(String snippet, String referenceSnippet) {
-        final StructuredGraph graph = parseEager(snippet);
-        final StructuredGraph referenceGraph = parseEager(referenceSnippet);
+        final StructuredGraph graph = parseEager(snippet, DONT_ALLOW_OPTIMISTIC_ASSUMPTIONS);
+        final StructuredGraph referenceGraph = parseEager(referenceSnippet, DONT_ALLOW_OPTIMISTIC_ASSUMPTIONS);
 
         new LoopUnswitchingPhase().apply(graph);
 
@@ -134,9 +135,8 @@
             ((StateSplit) stateSplit).setStateAfter(null);
         }
 
-        Assumptions assumptions = new Assumptions(false);
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), assumptions));
-        new CanonicalizerPhase(true).apply(referenceGraph, new PhaseContext(getProviders(), assumptions));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders()));
+        new CanonicalizerPhase(true).apply(referenceGraph, new PhaseContext(getProviders()));
         try (Scope s = Debug.scope("Test", new DebugDumpScope("Test:" + snippet))) {
             assertEquals(referenceGraph, graph);
         } catch (Throwable e) {
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.compiler.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
 import static com.oracle.graal.compiler.common.GraalOptions.*;
 import static org.junit.Assert.*;
 
@@ -29,7 +30,6 @@
 
 import org.junit.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.graph.*;
@@ -596,11 +596,10 @@
     }
 
     private SchedulePhase getFinalSchedule(final String snippet, final TestMode mode, final SchedulingStrategy schedulingStrategy) {
-        final StructuredGraph graph = parseEager(snippet);
+        final StructuredGraph graph = parseEager(snippet, DONT_ALLOW_OPTIMISTIC_ASSUMPTIONS);
         try (Scope d = Debug.scope("FloatingReadTest", graph)) {
             try (OverrideScope s = OptionValue.override(OptScheduleOutOfLoops, schedulingStrategy == SchedulingStrategy.LATEST_OUT_OF_LOOPS, OptImplicitNullChecks, false)) {
-                Assumptions assumptions = new Assumptions(false);
-                HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+                HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
                 CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true);
                 canonicalizer.apply(graph, context);
                 if (mode == TestMode.INLINED_WITHOUT_FRAMESTATES) {
@@ -623,7 +622,7 @@
                 new FloatingReadPhase().apply(graph);
                 new RemoveValueProxyPhase().apply(graph);
 
-                MidTierContext midContext = new MidTierContext(getProviders(), assumptions, getCodeCache().getTarget(), OptimisticOptimizations.ALL, graph.method().getProfilingInfo(), null);
+                MidTierContext midContext = new MidTierContext(getProviders(), getCodeCache().getTarget(), OptimisticOptimizations.ALL, graph.method().getProfilingInfo(), null);
                 new GuardLoweringPhase().apply(graph, midContext);
                 new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, midContext);
                 new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.LOW_TIER).apply(graph, midContext);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MergeCanonicalizerTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MergeCanonicalizerTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,9 +22,10 @@
  */
 package com.oracle.graal.compiler.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
+
 import org.junit.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.phases.common.*;
@@ -57,9 +58,9 @@
     }
 
     private void testReturnCount(String snippet, int returnCount) {
-        StructuredGraph graph = parseEager(snippet);
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), new Assumptions(false)));
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), new Assumptions(false)));
+        StructuredGraph graph = parseEager(snippet, ALLOW_OPTIMISTIC_ASSUMPTIONS);
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders()));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders()));
         Debug.dump(graph, "Graph");
         assertDeepEquals(returnCount, graph.getNodes(ReturnNode.class).count());
     }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MonitorGraphTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MonitorGraphTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,13 +22,13 @@
  */
 package com.oracle.graal.compiler.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
 import static com.oracle.graal.graph.iterators.NodePredicates.*;
 
 import java.util.*;
 
 import org.junit.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.iterators.*;
 import com.oracle.graal.nodes.*;
@@ -84,7 +84,7 @@
     }
 
     private StructuredGraph parseAndProcess(String snippet) {
-        StructuredGraph graph = parseEager(snippet);
+        StructuredGraph graph = parseEager(snippet, DONT_ALLOW_OPTIMISTIC_ASSUMPTIONS);
         ParameterNode param = graph.getNodes(ParameterNode.class).first();
         if (param != null) {
             ConstantNode constant = ConstantNode.forInt(0, graph);
@@ -96,8 +96,7 @@
         for (Invoke invoke : graph.getInvokes()) {
             hints.put(invoke, 1000d);
         }
-        Assumptions assumptions = new Assumptions(false);
-        HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+        HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
         new InliningPhase(hints, new CanonicalizerPhase(true)).apply(graph, context);
         new CanonicalizerPhase(true).apply(graph, context);
         new DeadCodeEliminationPhase().apply(graph);
@@ -106,7 +105,7 @@
 
     private void test(String snippet) {
         StructuredGraph graph = parseAndProcess(snippet);
-        StructuredGraph referenceGraph = parseEager(REFERENCE_SNIPPET);
+        StructuredGraph referenceGraph = parseEager(REFERENCE_SNIPPET, DONT_ALLOW_OPTIMISTIC_ASSUMPTIONS);
         assertEquals(referenceGraph, graph);
     }
 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/NestedLoopTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/NestedLoopTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.compiler.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
+
 import org.junit.*;
 
 import com.oracle.graal.compiler.common.cfg.*;
@@ -145,7 +147,7 @@
     }
 
     private void test(String snippet, int rootExits, int nestedExits, int innerExits) {
-        StructuredGraph graph = parseEager(snippet);
+        StructuredGraph graph = parseEager(snippet, ALLOW_OPTIMISTIC_ASSUMPTIONS);
         Debug.dump(graph, "Graph");
         ControlFlowGraph cfg = ControlFlowGraph.compute(graph, true, true, true, true);
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PhiCreationTests.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PhiCreationTests.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.compiler.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
+
 import org.junit.*;
 
 import com.oracle.graal.debug.*;
@@ -40,7 +42,7 @@
 
     @Test
     public void test1() {
-        StructuredGraph graph = parseEager("test1Snippet");
+        StructuredGraph graph = parseEager("test1Snippet", ALLOW_OPTIMISTIC_ASSUMPTIONS);
         Assert.assertFalse(graph.getNodes().filter(ValuePhiNode.class).iterator().hasNext());
     }
 
@@ -53,7 +55,7 @@
 
     @Test
     public void test2() {
-        StructuredGraph graph = parseEager("test2Snippet");
+        StructuredGraph graph = parseEager("test2Snippet", ALLOW_OPTIMISTIC_ASSUMPTIONS);
         Assert.assertFalse(graph.getNodes().filter(ValuePhiNode.class).iterator().hasNext());
     }
 
@@ -66,7 +68,7 @@
 
     @Test
     public void test3() {
-        StructuredGraph graph = parseEager("test3Snippet");
+        StructuredGraph graph = parseEager("test3Snippet", ALLOW_OPTIMISTIC_ASSUMPTIONS);
         Debug.dump(graph, "Graph");
         Assert.assertFalse(graph.getNodes().filter(ValuePhiNode.class).iterator().hasNext());
     }
@@ -82,7 +84,7 @@
 
     @Test
     public void test4() {
-        StructuredGraph graph = parseEager("test4Snippet");
+        StructuredGraph graph = parseEager("test4Snippet", ALLOW_OPTIMISTIC_ASSUMPTIONS);
         Debug.dump(graph, "Graph");
         Assert.assertFalse(graph.getNodes().filter(ValuePhiNode.class).iterator().hasNext());
     }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,9 +22,10 @@
  */
 package com.oracle.graal.compiler.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
+
 import org.junit.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.debug.*;
@@ -91,8 +92,8 @@
     }
 
     private StructuredGraph compileTestSnippet(final String snippet) {
-        StructuredGraph graph = parseEager(snippet);
-        PhaseContext context = new PhaseContext(getProviders(), new Assumptions(false));
+        StructuredGraph graph = parseEager(snippet, ALLOW_OPTIMISTIC_ASSUMPTIONS);
+        PhaseContext context = new PhaseContext(getProviders());
         CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true);
         new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
         canonicalizer.apply(graph, context);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushThroughIfTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushThroughIfTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,9 +22,10 @@
  */
 package com.oracle.graal.compiler.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
+
 import org.junit.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.util.*;
@@ -57,21 +58,21 @@
     }
 
     private void test(String snippet, String reference) {
-        StructuredGraph graph = parseEager(snippet);
+        StructuredGraph graph = parseEager(snippet, ALLOW_OPTIMISTIC_ASSUMPTIONS);
         Debug.dump(graph, "Graph");
         for (FrameState fs : graph.getNodes(FrameState.class).snapshot()) {
             fs.replaceAtUsages(null);
             GraphUtil.killWithUnusedFloatingInputs(fs);
         }
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), new Assumptions(false)));
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), new Assumptions(false)));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders()));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders()));
 
-        StructuredGraph referenceGraph = parseEager(reference);
+        StructuredGraph referenceGraph = parseEager(reference, ALLOW_OPTIMISTIC_ASSUMPTIONS);
         for (FrameState fs : referenceGraph.getNodes(FrameState.class).snapshot()) {
             fs.replaceAtUsages(null);
             GraphUtil.killWithUnusedFloatingInputs(fs);
         }
-        new CanonicalizerPhase(true).apply(referenceGraph, new PhaseContext(getProviders(), new Assumptions(false)));
+        new CanonicalizerPhase(true).apply(referenceGraph, new PhaseContext(getProviders()));
         assertEquals(referenceGraph, graph);
     }
 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,9 +22,10 @@
  */
 package com.oracle.graal.compiler.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
+
 import org.junit.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.nodes.*;
@@ -81,8 +82,8 @@
         try (Scope s = Debug.scope("ReadAfterCheckCastTest", new DebugDumpScope(snippet))) {
             // check shape of graph, with lots of assumptions. will probably fail if graph
             // structure changes significantly
-            StructuredGraph graph = parseEager(snippet);
-            PhaseContext context = new PhaseContext(getProviders(), new Assumptions(false));
+            StructuredGraph graph = parseEager(snippet, ALLOW_OPTIMISTIC_ASSUMPTIONS);
+            PhaseContext context = new PhaseContext(getProviders());
             CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true);
             new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
             new FloatingReadPhase().apply(graph);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReassociateAndCanonicalTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReassociateAndCanonicalTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,9 +22,10 @@
  */
 package com.oracle.graal.compiler.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
+
 import org.junit.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.phases.common.*;
@@ -243,11 +244,10 @@
     }
 
     private <T extends Node & IterableNodeType> void test(String test, String ref) {
-        StructuredGraph testGraph = parseEager(test);
-        Assumptions assumptions = new Assumptions(false);
-        new CanonicalizerPhase(true).apply(testGraph, new PhaseContext(getProviders(), assumptions));
-        StructuredGraph refGraph = parseEager(ref);
-        new CanonicalizerPhase(true).apply(refGraph, new PhaseContext(getProviders(), assumptions));
+        StructuredGraph testGraph = parseEager(test, DONT_ALLOW_OPTIMISTIC_ASSUMPTIONS);
+        new CanonicalizerPhase(true).apply(testGraph, new PhaseContext(getProviders()));
+        StructuredGraph refGraph = parseEager(ref, DONT_ALLOW_OPTIMISTIC_ASSUMPTIONS);
+        new CanonicalizerPhase(true).apply(refGraph, new PhaseContext(getProviders()));
         assertEquals(testGraph, refGraph);
     }
 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ScalarTypeSystemTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ScalarTypeSystemTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,9 +22,10 @@
  */
 package com.oracle.graal.compiler.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
+
 import org.junit.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.phases.common.*;
@@ -130,12 +131,11 @@
 
     private void test(final String snippet, final String referenceSnippet) {
         // No debug scope to reduce console noise for @Test(expected = ...) tests
-        StructuredGraph graph = parseEager(snippet);
+        StructuredGraph graph = parseEager(snippet, DONT_ALLOW_OPTIMISTIC_ASSUMPTIONS);
         Debug.dump(graph, "Graph");
-        Assumptions assumptions = new Assumptions(false);
-        PhaseContext context = new PhaseContext(getProviders(), assumptions);
+        PhaseContext context = new PhaseContext(getProviders());
         new CanonicalizerPhase(true).apply(graph, context);
-        StructuredGraph referenceGraph = parseEager(referenceSnippet);
+        StructuredGraph referenceGraph = parseEager(referenceSnippet, DONT_ALLOW_OPTIMISTIC_ASSUMPTIONS);
         assertEquals(referenceGraph, graph);
     }
 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/SchedulingTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/SchedulingTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.compiler.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
 import static org.junit.Assert.*;
 
 import java.util.*;
@@ -51,7 +52,7 @@
 
     @Test
     public void testValueProxyInputs() {
-        StructuredGraph graph = parseEager("testValueProxyInputsSnippet");
+        StructuredGraph graph = parseEager("testValueProxyInputsSnippet", ALLOW_OPTIMISTIC_ASSUMPTIONS);
         for (FrameState fs : graph.getNodes().filter(FrameState.class).snapshot()) {
             fs.replaceAtUsages(null);
             GraphUtil.killWithUnusedFloatingInputs(fs);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/SimpleCFGTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/SimpleCFGTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.compiler.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
 import static org.junit.Assert.*;
 
 import java.util.*;
@@ -40,7 +41,7 @@
 
     @Test
     public void testImplies() {
-        StructuredGraph graph = new StructuredGraph();
+        StructuredGraph graph = new StructuredGraph(ALLOW_OPTIMISTIC_ASSUMPTIONS);
 
         AbstractEndNode trueEnd = graph.add(new EndNode());
         AbstractEndNode falseEnd = graph.add(new EndNode());
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StampCanonicalizerTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StampCanonicalizerTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,9 +22,10 @@
  */
 package com.oracle.graal.compiler.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
+
 import org.junit.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.phases.common.*;
@@ -109,8 +110,8 @@
     }
 
     private void testZeroReturn(String methodName) {
-        StructuredGraph graph = parseEager(methodName);
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), new Assumptions(false)));
+        StructuredGraph graph = parseEager(methodName, ALLOW_OPTIMISTIC_ASSUMPTIONS);
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders()));
         new DeadCodeEliminationPhase().apply(graph);
         assertConstantReturn(graph, 0);
     }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StraighteningTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StraighteningTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,9 +22,10 @@
  */
 package com.oracle.graal.compiler.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
+
 import org.junit.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.phases.common.*;
@@ -87,10 +88,10 @@
 
     private void test(final String snippet) {
         // No debug scope to reduce console noise for @Test(expected = ...) tests
-        StructuredGraph graph = parseEager(snippet);
+        StructuredGraph graph = parseEager(snippet, ALLOW_OPTIMISTIC_ASSUMPTIONS);
         Debug.dump(graph, "Graph");
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), new Assumptions(false)));
-        StructuredGraph referenceGraph = parseEager(REFERENCE_SNIPPET);
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders()));
+        StructuredGraph referenceGraph = parseEager(REFERENCE_SNIPPET, ALLOW_OPTIMISTIC_ASSUMPTIONS);
         assertEquals(referenceGraph, graph);
     }
 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/TypeSystemTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/TypeSystemTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,11 +22,12 @@
  */
 package com.oracle.graal.compiler.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
+
 import java.io.*;
 
 import org.junit.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodeinfo.*;
@@ -170,20 +171,19 @@
     }
 
     private void test(String snippet, String referenceSnippet) {
-        StructuredGraph graph = parseEager(snippet);
+        StructuredGraph graph = parseEager(snippet, DONT_ALLOW_OPTIMISTIC_ASSUMPTIONS);
         Debug.dump(graph, "Graph");
-        Assumptions assumptions = new Assumptions(false);
         /*
          * When using FlowSensitiveReductionPhase instead of ConditionalEliminationPhase,
          * tail-duplication gets activated thus resulting in a graph with more nodes than the
          * reference graph.
          */
-        new ConditionalEliminationPhase().apply(graph, new PhaseContext(getProviders(), assumptions));
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), assumptions));
+        new ConditionalEliminationPhase().apply(graph, new PhaseContext(getProviders()));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders()));
         // a second canonicalizer is needed to process nested MaterializeNodes
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), assumptions));
-        StructuredGraph referenceGraph = parseEager(referenceSnippet);
-        new CanonicalizerPhase(true).apply(referenceGraph, new PhaseContext(getProviders(), assumptions));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders()));
+        StructuredGraph referenceGraph = parseEager(referenceSnippet, DONT_ALLOW_OPTIMISTIC_ASSUMPTIONS);
+        new CanonicalizerPhase(true).apply(referenceGraph, new PhaseContext(getProviders()));
         assertEquals(referenceGraph, graph);
     }
 
@@ -230,10 +230,9 @@
     }
 
     private <T extends Node> void testHelper(String snippet, Class<T> clazz) {
-        StructuredGraph graph = parseEager(snippet);
-        Assumptions assumptions = new Assumptions(false);
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), assumptions));
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), assumptions));
+        StructuredGraph graph = parseEager(snippet, DONT_ALLOW_OPTIMISTIC_ASSUMPTIONS);
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders()));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders()));
         Debug.dump(graph, "Graph " + snippet);
         Assert.assertFalse("shouldn't have nodes of type " + clazz, graph.getNodes().filter(clazz).iterator().hasNext());
     }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.compiler.test.backend;
 
+import static com.oracle.graal.api.code.Assumptions.*;
+
 import java.util.*;
 
 import org.junit.*;
@@ -38,7 +40,7 @@
 public class AllocatorTest extends BackendTest {
 
     protected void testAllocation(String snippet, final int expectedRegisters, final int expectedRegRegMoves, final int expectedSpillMoves) {
-        final StructuredGraph graph = parseEager(snippet);
+        final StructuredGraph graph = parseEager(snippet, ALLOW_OPTIMISTIC_ASSUMPTIONS);
         try (Scope s = Debug.scope("AllocatorTest", graph, graph.method(), getCodeCache())) {
             final RegisterStats stats = new RegisterStats(getLIRGenerationResult(graph).getLIR());
             try (Scope s2 = Debug.scope("Assertions", stats.lir)) {
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/BackendTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/BackendTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -23,8 +23,6 @@
 package com.oracle.graal.compiler.test.backend;
 
 import static com.oracle.graal.api.code.CodeUtil.*;
-import static com.oracle.graal.compiler.common.GraalOptions.*;
-
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.code.CallingConvention.Type;
 import com.oracle.graal.compiler.*;
@@ -47,11 +45,9 @@
     }
 
     protected LIRGenerationResult getLIRGenerationResult(final StructuredGraph graph) {
-        final Assumptions assumptions = new Assumptions(OptAssumptions.getValue());
-
         SchedulePhase schedule = null;
         try (Scope s = Debug.scope("FrontEnd")) {
-            schedule = GraalCompiler.emitFrontEnd(getProviders(), getBackend().getTarget(), graph, assumptions, null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.NONE,
+            schedule = GraalCompiler.emitFrontEnd(getProviders(), getBackend().getTarget(), graph, null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.NONE,
                             graph.method().getProfilingInfo(), null, getSuites());
         } catch (Throwable e) {
             throw Debug.handle(e);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/CompiledMethodTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/CompiledMethodTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.compiler.test.deopt;
 
+import static com.oracle.graal.api.code.Assumptions.*;
+
 import org.junit.*;
 
 import com.oracle.graal.api.code.*;
@@ -51,8 +53,8 @@
     @Test
     public void test1() {
         final ResolvedJavaMethod javaMethod = getResolvedJavaMethod("testMethod");
-        final StructuredGraph graph = parseEager(javaMethod);
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), new Assumptions(false)));
+        final StructuredGraph graph = parseEager(javaMethod, DONT_ALLOW_OPTIMISTIC_ASSUMPTIONS);
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders()));
         new DeadCodeEliminationPhase().apply(graph);
 
         for (ConstantNode node : ConstantNode.getConstantNodes(graph)) {
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/MonitorDeoptTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/MonitorDeoptTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -24,6 +24,8 @@
  */
 package com.oracle.graal.compiler.test.deopt;
 
+import static com.oracle.graal.api.code.Assumptions.*;
+
 import org.junit.*;
 
 import com.oracle.graal.api.code.*;
@@ -134,7 +136,7 @@
     public void run0() throws Throwable {
         ResolvedJavaMethod javaMethod = getResolvedJavaMethod("test");
 
-        StructuredGraph graph = parseEager(javaMethod);
+        StructuredGraph graph = parseEager(javaMethod, ALLOW_OPTIMISTIC_ASSUMPTIONS);
         removeLoopSafepoint(graph);
 
         CompilationResult compilationResult = compile(javaMethod, graph);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EATestBase.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EATestBase.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,11 +22,12 @@
  */
 package com.oracle.graal.compiler.test.ea;
 
+import static com.oracle.graal.api.code.Assumptions.*;
+
 import java.util.*;
 
 import org.junit.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.test.*;
 import com.oracle.graal.debug.*;
@@ -149,12 +150,11 @@
 
     protected void prepareGraph(String snippet, final boolean iterativeEscapeAnalysis) {
         ResolvedJavaMethod method = getResolvedJavaMethod(snippet);
-        graph = new StructuredGraph(method);
+        graph = new StructuredGraph(method, DONT_ALLOW_OPTIMISTIC_ASSUMPTIONS);
         try (Scope s = Debug.scope(getClass(), graph, method, getCodeCache())) {
-            Assumptions assumptions = new Assumptions(false);
-            new GraphBuilderPhase.Instance(getMetaAccess(), getProviders().getStampProvider(), assumptions, getProviders().getConstantReflection(), GraphBuilderConfiguration.getEagerDefault(),
+            new GraphBuilderPhase.Instance(getMetaAccess(), getProviders().getStampProvider(), getProviders().getConstantReflection(), GraphBuilderConfiguration.getEagerDefault(),
                             OptimisticOptimizations.ALL).apply(graph);
-            context = new HighTierContext(getProviders(), assumptions, null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+            context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
             new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
             new DeadCodeEliminationPhase().apply(graph);
             new CanonicalizerPhase(true).apply(graph, context);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EarlyReadEliminationTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EarlyReadEliminationTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,9 +22,10 @@
  */
 package com.oracle.graal.compiler.test.ea;
 
+import static com.oracle.graal.api.code.Assumptions.*;
+
 import org.junit.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.common.inlining.*;
@@ -40,9 +41,8 @@
 
     @Override
     protected void processMethod(final String snippet) {
-        graph = parseEager(snippet);
-        Assumptions assumptions = new Assumptions(false);
-        HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+        graph = parseEager(getResolvedJavaMethod(snippet), DONT_ALLOW_OPTIMISTIC_ASSUMPTIONS);
+        HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
         new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
         new EarlyReadEliminationPhase(new CanonicalizerPhase(true)).apply(graph, context);
     }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/IterativeInliningTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/IterativeInliningTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,13 +22,13 @@
  */
 package com.oracle.graal.compiler.test.ea;
 
+import static com.oracle.graal.api.code.Assumptions.*;
 import static org.junit.Assert.*;
 
 import java.util.concurrent.*;
 
 import org.junit.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.compiler.test.*;
 import com.oracle.graal.compiler.test.ea.EATestBase.TestClassInt;
 import com.oracle.graal.nodes.*;
@@ -84,8 +84,8 @@
     }
 
     private void processMethod(final String snippet) {
-        graph = parseEager(snippet);
-        HighTierContext context = new HighTierContext(getProviders(), new Assumptions(false), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+        graph = parseEager(snippet, ALLOW_OPTIMISTIC_ASSUMPTIONS);
+        HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
         new IterativeInliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
     }
 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PEAReadEliminationTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PEAReadEliminationTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,13 +22,13 @@
  */
 package com.oracle.graal.compiler.test.ea;
 
+import static com.oracle.graal.api.code.Assumptions.*;
 import static org.junit.Assert.*;
 
 import java.util.*;
 
 import org.junit.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.compiler.test.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
@@ -244,9 +244,8 @@
     }
 
     protected void processMethod(final String snippet) {
-        graph = parseEager(snippet);
-        Assumptions assumptions = new Assumptions(false);
-        HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+        graph = parseEager(snippet, DONT_ALLOW_OPTIMISTIC_ASSUMPTIONS);
+        HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
         new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
         new PartialEscapePhase(false, true, new CanonicalizerPhase(true), null).apply(graph, context);
     }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PoorMansEATest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PoorMansEATest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,9 +22,10 @@
  */
 package com.oracle.graal.compiler.test.ea;
 
+import static com.oracle.graal.api.code.Assumptions.*;
+
 import org.junit.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.compiler.test.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
@@ -39,7 +40,7 @@
 
 /**
  * Tests {@link AbstractNewObjectNode#simplify(com.oracle.graal.graph.spi.SimplifierTool)}.
- * 
+ *
  */
 public class PoorMansEATest extends GraalCompilerTest {
     public static class A {
@@ -59,11 +60,10 @@
 
     private void test(final String snippet) {
         try (Scope s = Debug.scope("PoorMansEATest", new DebugDumpScope(snippet))) {
-            StructuredGraph graph = parseEager(snippet);
-            Assumptions assumptions = new Assumptions(false);
-            HighTierContext highTierContext = new HighTierContext(getProviders(), assumptions, null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+            StructuredGraph graph = parseEager(snippet, DONT_ALLOW_OPTIMISTIC_ASSUMPTIONS);
+            HighTierContext highTierContext = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
             new InliningPhase(new CanonicalizerPhase(true)).apply(graph, highTierContext);
-            PhaseContext context = new PhaseContext(getProviders(), assumptions);
+            PhaseContext context = new PhaseContext(getProviders());
             new LoweringPhase(new CanonicalizerPhase(true), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
 
             // remove framestates in order to trigger the simplification.
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.compiler.test.inlining;
 
+import static com.oracle.graal.api.code.Assumptions.*;
 import static org.junit.Assert.*;
 
 import org.junit.*;
@@ -231,10 +232,9 @@
     private StructuredGraph getGraph(final String snippet, final boolean eagerInfopointMode) {
         try (Scope s = Debug.scope("InliningTest", new DebugDumpScope(snippet))) {
             ResolvedJavaMethod method = getResolvedJavaMethod(snippet);
-            StructuredGraph graph = eagerInfopointMode ? parseDebug(method) : parseEager(method);
+            StructuredGraph graph = eagerInfopointMode ? parseDebug(method, ALLOW_OPTIMISTIC_ASSUMPTIONS) : parseEager(method, ALLOW_OPTIMISTIC_ASSUMPTIONS);
             PhaseSuite<HighTierContext> graphBuilderSuite = eagerInfopointMode ? getCustomGraphBuilderSuite(GraphBuilderConfiguration.getFullDebugDefault()) : getDefaultGraphBuilderSuite();
-            Assumptions assumptions = new Assumptions(true);
-            HighTierContext context = new HighTierContext(getProviders(), assumptions, null, graphBuilderSuite, OptimisticOptimizations.ALL);
+            HighTierContext context = new HighTierContext(getProviders(), null, graphBuilderSuite, OptimisticOptimizations.ALL);
             Debug.dump(graph, "Graph");
             new CanonicalizerPhase(true).apply(graph, context);
             new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/tutorial/InvokeGraal.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/tutorial/InvokeGraal.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.compiler.test.tutorial;
 
+import static com.oracle.graal.api.code.Assumptions.*;
+
 import java.lang.reflect.*;
 import java.util.*;
 import java.util.concurrent.atomic.*;
@@ -78,9 +80,11 @@
 
             /*
              * The graph that is compiled. We leave it empty (no nodes added yet). This means that
-             * it will be filled according to the graphBuilderSuite defined below.
+             * it will be filled according to the graphBuilderSuite defined below. We also specify
+             * that we want the compilation to make optimistic assumptions about runtime state such
+             * as the loaded class hierarchy.
              */
-            StructuredGraph graph = new StructuredGraph(method);
+            StructuredGraph graph = new StructuredGraph(method, ALLOW_OPTIMISTIC_ASSUMPTIONS);
 
             /*
              * The phases used to build the graph. Usually this is just the GraphBuilderPhase. If
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/tutorial/StaticAnalysis.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/tutorial/StaticAnalysis.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,9 +22,10 @@
  */
 package com.oracle.graal.compiler.test.tutorial;
 
+import static com.oracle.graal.api.code.Assumptions.*;
+
 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.*;
@@ -210,7 +211,7 @@
                  * Build the Graal graph for the method using the bytecode parser provided by Graal.
                  */
 
-                StructuredGraph graph = new StructuredGraph(method);
+                StructuredGraph graph = new StructuredGraph(method, DONT_ALLOW_OPTIMISTIC_ASSUMPTIONS);
                 /*
                  * Support for graph dumping, IGV uses this information to show the method name of a
                  * graph.
@@ -236,9 +237,8 @@
                      * wrong.
                      */
                     OptimisticOptimizations optimisticOpts = OptimisticOptimizations.NONE;
-                    Assumptions assumptions = new Assumptions(false);
 
-                    GraphBuilderPhase.Instance graphBuilder = new GraphBuilderPhase.Instance(metaAccess, stampProvider, assumptions, null, graphBuilderConfig, optimisticOpts);
+                    GraphBuilderPhase.Instance graphBuilder = new GraphBuilderPhase.Instance(metaAccess, stampProvider, null, graphBuilderConfig, optimisticOpts);
                     graphBuilder.apply(graph);
                 } catch (Throwable ex) {
                     Debug.handle(ex);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Wed Feb 11 16:08:50 2015 +0100
@@ -24,7 +24,6 @@
 
 import static com.oracle.graal.compiler.GraalCompiler.Options.*;
 import static com.oracle.graal.compiler.MethodFilter.*;
-import static com.oracle.graal.compiler.common.GraalOptions.*;
 import static com.oracle.graal.phases.common.DeadCodeEliminationPhase.Optionality.*;
 
 import java.util.*;
@@ -220,9 +219,8 @@
     public static <T extends CompilationResult> T compile(Request<T> r) {
         assert !r.graph.isFrozen();
         try (Scope s0 = Debug.scope("GraalCompiler", r.graph, r.providers.getCodeCache())) {
-            Assumptions assumptions = new Assumptions(OptAssumptions.getValue());
-            SchedulePhase schedule = emitFrontEnd(r.providers, r.target, r.graph, assumptions, r.cache, r.graphBuilderSuite, r.optimisticOpts, r.profilingInfo, r.speculationLog, r.suites);
-            emitBackEnd(r.graph, null, r.cc, r.installedCodeOwner, r.backend, r.target, r.compilationResult, r.factory, assumptions, schedule, null, r.lirSuites);
+            SchedulePhase schedule = emitFrontEnd(r.providers, r.target, r.graph, r.cache, r.graphBuilderSuite, r.optimisticOpts, r.profilingInfo, r.speculationLog, r.suites);
+            emitBackEnd(r.graph, null, r.cc, r.installedCodeOwner, r.backend, r.target, r.compilationResult, r.factory, schedule, null, r.lirSuites);
         } catch (Throwable e) {
             throw Debug.handle(e);
         }
@@ -240,14 +238,14 @@
     /**
      * Builds the graph, optimizes it.
      */
-    public static SchedulePhase emitFrontEnd(Providers providers, TargetDescription target, StructuredGraph graph, Assumptions assumptions, Map<ResolvedJavaMethod, StructuredGraph> cache,
+    public static SchedulePhase emitFrontEnd(Providers providers, TargetDescription target, StructuredGraph graph, Map<ResolvedJavaMethod, StructuredGraph> cache,
                     PhaseSuite<HighTierContext> graphBuilderSuite, OptimisticOptimizations optimisticOpts, ProfilingInfo profilingInfo, SpeculationLog speculationLog, Suites suites) {
         try (Scope s = Debug.scope("FrontEnd"); TimerCloseable a = FrontEnd.start()) {
             if (speculationLog != null) {
                 speculationLog.collectFailedSpeculations();
             }
 
-            HighTierContext highTierContext = new HighTierContext(providers, assumptions, cache, graphBuilderSuite, optimisticOpts);
+            HighTierContext highTierContext = new HighTierContext(providers, cache, graphBuilderSuite, optimisticOpts);
             if (graph.start().next() == null) {
                 graphBuilderSuite.apply(graph, highTierContext);
                 new DeadCodeEliminationPhase(Optional).apply(graph);
@@ -258,11 +256,11 @@
             suites.getHighTier().apply(graph, highTierContext);
             graph.maybeCompress();
 
-            MidTierContext midTierContext = new MidTierContext(providers, assumptions, target, optimisticOpts, profilingInfo, speculationLog);
+            MidTierContext midTierContext = new MidTierContext(providers, target, optimisticOpts, profilingInfo, speculationLog);
             suites.getMidTier().apply(graph, midTierContext);
             graph.maybeCompress();
 
-            LowTierContext lowTierContext = new LowTierContext(providers, assumptions, target);
+            LowTierContext lowTierContext = new LowTierContext(providers, target);
             suites.getLowTier().apply(graph, lowTierContext);
             graph.maybeCompress();
 
@@ -276,13 +274,12 @@
     }
 
     public static <T extends CompilationResult> void emitBackEnd(StructuredGraph graph, Object stub, CallingConvention cc, ResolvedJavaMethod installedCodeOwner, Backend backend,
-                    TargetDescription target, T compilationResult, CompilationResultBuilderFactory factory, Assumptions assumptions, SchedulePhase schedule, RegisterConfig registerConfig,
-                    LIRSuites lirSuites) {
+                    TargetDescription target, T compilationResult, CompilationResultBuilderFactory factory, SchedulePhase schedule, RegisterConfig registerConfig, LIRSuites lirSuites) {
         try (TimerCloseable a = BackEnd.start()) {
             LIRGenerationResult lirGen = null;
             lirGen = emitLIR(backend, target, schedule, graph, stub, cc, registerConfig, lirSuites);
             try (Scope s = Debug.scope("CodeGen", lirGen, lirGen.getLIR())) {
-                emitCode(backend, assumptions, lirGen, compilationResult, installedCodeOwner, factory);
+                emitCode(backend, graph.getAssumptions(), lirGen, compilationResult, installedCodeOwner, factory);
             } catch (Throwable e) {
                 throw Debug.handle(e);
             }
@@ -373,7 +370,7 @@
         backend.emitCode(crb, lirGenRes.getLIR(), installedCodeOwner);
         crb.finish();
         if (!assumptions.isEmpty()) {
-            compilationResult.setAssumptions(assumptions);
+            compilationResult.setAssumptions(assumptions.toArray());
         }
 
         if (Debug.isMeterEnabled()) {
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java	Wed Feb 11 16:08:50 2015 +0100
@@ -65,6 +65,8 @@
     public static final OptionValue<Boolean> SuppressZeroDebugValues = new OptionValue<>(false);
     @Option(help = "Send Graal IR to dump handlers on error", type = OptionType.Debug)
     public static final OptionValue<Boolean> DumpOnError = new OptionValue<>(false);
+    @Option(help = "Intercept also bailout exceptions", type = OptionType.Debug)
+    public static final OptionValue<Boolean> InterceptBailout = new OptionValue<>(false);
     @Option(help = "Enable more verbose log output when available", type = OptionType.Debug)
     public static final OptionValue<Boolean> LogVerbose = new OptionValue<>(false);
     // @formatter:on
@@ -254,7 +256,7 @@
 
     @Override
     public RuntimeException interceptException(Throwable e) {
-        if (e instanceof BailoutException) {
+        if (e instanceof BailoutException && !InterceptBailout.getValue()) {
             return null;
         }
         Debug.setConfig(Debug.fixedConfig(Debug.DEFAULT_LOG_LEVEL, Debug.DEFAULT_LOG_LEVEL, false, false, false, false, dumpHandlers, verifyHandlers, output));
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java	Wed Feb 11 16:08:50 2015 +0100
@@ -467,6 +467,10 @@
         log(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
     }
 
+    public static void log(String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7, Object arg8) {
+        log(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
+    }
+
     /**
      * @see #log(int, String, Object)
      */
@@ -476,6 +480,12 @@
         }
     }
 
+    public static void log(int logLevel, String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7, Object arg8) {
+        if (ENABLED) {
+            DebugScope.getInstance().log(logLevel, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
+        }
+    }
+
     public static void logv(String format, Object... args) {
         logv(DEFAULT_LOG_LEVEL, format, args);
     }
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/spi/CanonicalizerTool.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/spi/CanonicalizerTool.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,13 +22,10 @@
  */
 package com.oracle.graal.graph.spi;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 
 public interface CanonicalizerTool {
 
-    Assumptions assumptions();
-
     MetaAccessProvider getMetaAccess();
 
     ConstantReflectionProvider getConstantReflection();
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java	Wed Feb 11 16:08:50 2015 +0100
@@ -152,15 +152,12 @@
             try (InitTimer rt = timer("create Lowerer provider")) {
                 lowerer = createLowerer(runtime, metaAccess, foreignCalls, registers, target);
             }
-            // Replacements cannot have speculative optimizations since they have
-            // to be valid for the entire run of the VM.
-            Assumptions assumptions = new Assumptions(false);
             Providers p = new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, null, new HotSpotStampProvider());
             try (InitTimer rt = timer("create SnippetReflection provider")) {
                 snippetReflection = createSnippetReflection(runtime);
             }
             try (InitTimer rt = timer("create Replacements provider")) {
-                replacements = createReplacements(runtime, assumptions, p, snippetReflection);
+                replacements = createReplacements(runtime, p, snippetReflection);
             }
             try (InitTimer rt = timer("create Disassembler provider")) {
                 disassembler = createDisassembler(runtime);
@@ -187,8 +184,8 @@
         return new HotSpotDisassemblerProvider(runtime);
     }
 
-    protected Replacements createReplacements(HotSpotGraalRuntimeProvider runtime, Assumptions assumptions, Providers p, SnippetReflectionProvider snippetReflection) {
-        return new HotSpotReplacementsImpl(p, snippetReflection, runtime.getConfig(), assumptions, p.getCodeCache().getTarget());
+    protected Replacements createReplacements(HotSpotGraalRuntimeProvider runtime, Providers p, SnippetReflectionProvider snippetReflection) {
+        return new HotSpotReplacementsImpl(p, snippetReflection, runtime.getConfig(), p.getCodeCache().getTarget());
     }
 
     protected AMD64HotSpotForeignCallsProvider createForeignCalls(HotSpotGraalRuntimeProvider runtime, HotSpotMetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache,
@@ -251,15 +248,15 @@
         } else {
             /*
              * System V Application Binary Interface, AMD64 Architecture Processor Supplement
-             *
+             * 
              * Draft Version 0.96
-             *
+             * 
              * http://www.uclibc.org/docs/psABI-x86_64.pdf
-             *
+             * 
              * 3.2.1
-             *
+             * 
              * ...
-             *
+             * 
              * This subsection discusses usage of each register. Registers %rbp, %rbx and %r12
              * through %r15 "belong" to the calling function and the called function is required to
              * preserve their values. In other words, a called function must preserve these
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java	Wed Feb 11 16:08:50 2015 +0100
@@ -60,12 +60,9 @@
         Value[] nativeABICallerSaveRegisters = createNativeABICallerSaveRegisters(runtime.getConfig(), codeCache.getRegisterConfig());
         HotSpotForeignCallsProvider foreignCalls = new SPARCHotSpotForeignCallsProvider(runtime, metaAccess, codeCache, nativeABICallerSaveRegisters);
         LoweringProvider lowerer = new SPARCHotSpotLoweringProvider(runtime, metaAccess, foreignCalls, registers, target);
-        // Replacements cannot have speculative optimizations since they have
-        // to be valid for the entire run of the VM.
-        Assumptions assumptions = new Assumptions(false);
         Providers p = new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, null, new HotSpotStampProvider());
         HotSpotSnippetReflectionProvider snippetReflection = new HotSpotSnippetReflectionProvider(runtime);
-        HotSpotReplacementsImpl replacements = new HotSpotReplacementsImpl(p, snippetReflection, runtime.getConfig(), assumptions, target);
+        HotSpotReplacementsImpl replacements = new HotSpotReplacementsImpl(p, snippetReflection, runtime.getConfig(), target);
         HotSpotDisassemblerProvider disassembler = new HotSpotDisassemblerProvider(runtime);
         HotSpotSuitesProvider suites = new HotSpotSuitesProvider(runtime);
         HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers, snippetReflection);
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.hotspot.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
 import static com.oracle.graal.api.code.CodeUtil.*;
 import static com.oracle.graal.compiler.GraalCompiler.*;
 import static com.oracle.graal.compiler.common.GraalOptions.*;
@@ -204,7 +205,7 @@
     }
 
     private StructuredGraph compile(String test, boolean compileAOT) {
-        StructuredGraph graph = parseEager(test);
+        StructuredGraph graph = parseEager(test, ALLOW_OPTIMISTIC_ASSUMPTIONS);
         ResolvedJavaMethod method = graph.method();
 
         try (OverrideScope s = OptionValue.override(ImmutableCode, compileAOT)) {
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/ClassSubstitutionsTests.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/ClassSubstitutionsTests.java	Wed Feb 11 16:08:50 2015 +0100
@@ -23,6 +23,7 @@
 
 package com.oracle.graal.hotspot.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
 import static org.junit.Assert.*;
 
 import org.junit.*;
@@ -43,7 +44,7 @@
 
     protected StructuredGraph test(final String snippet) {
         try (Scope s = Debug.scope("ClassSubstitutionsTest", getMetaAccess().lookupJavaMethod(getMethod(snippet)))) {
-            StructuredGraph graph = parseEager(snippet);
+            StructuredGraph graph = parseEager(snippet, ALLOW_OPTIMISTIC_ASSUMPTIONS);
             compile(graph.method(), graph);
             assertNotInGraph(graph, Invoke.class);
             Debug.dump(graph, snippet);
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotNmethodTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotNmethodTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.hotspot.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
+
 import org.junit.*;
 
 import com.oracle.graal.api.code.*;
@@ -36,7 +38,7 @@
     @Test
     public void testInstallCodeInvalidation() {
         final ResolvedJavaMethod testJavaMethod = getResolvedJavaMethod("foo");
-        final HotSpotNmethod nmethod = (HotSpotNmethod) getCode(testJavaMethod, parseEager("otherFoo"));
+        final HotSpotNmethod nmethod = (HotSpotNmethod) getCode(testJavaMethod, parseEager("otherFoo", ALLOW_OPTIMISTIC_ASSUMPTIONS));
         Assert.assertTrue(nmethod.isValid());
         Object result;
         try {
@@ -59,7 +61,7 @@
     @Test
     public void testInstallCodeInvalidationWhileRunning() {
         final ResolvedJavaMethod testJavaMethod = getResolvedJavaMethod("foo");
-        final HotSpotNmethod nmethod = (HotSpotNmethod) getCode(testJavaMethod, parseEager("otherFoo"));
+        final HotSpotNmethod nmethod = (HotSpotNmethod) getCode(testJavaMethod, parseEager("otherFoo", ALLOW_OPTIMISTIC_ASSUMPTIONS));
         Object result;
         try {
             result = nmethod.executeVarargs(nmethod, null, null);
@@ -73,7 +75,7 @@
     @Test
     public void testInstalledCodeCalledFromCompiledCode() {
         final ResolvedJavaMethod testJavaMethod = getResolvedJavaMethod("foo");
-        final HotSpotNmethod nmethod = (HotSpotNmethod) getCode(testJavaMethod, parseEager("otherFoo"));
+        final HotSpotNmethod nmethod = (HotSpotNmethod) getCode(testJavaMethod, parseEager("otherFoo", ALLOW_OPTIMISTIC_ASSUMPTIONS));
         Assert.assertTrue(nmethod.isValid());
         try {
             for (int i = 0; i < ITERATION_COUNT; ++i) {
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotNodeSubstitutionsTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotNodeSubstitutionsTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.hotspot.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
+
 import org.junit.*;
 
 import com.oracle.graal.graph.*;
@@ -35,7 +37,7 @@
 
     @Test
     public void test() {
-        StructuredGraph graph = new StructuredGraph();
+        StructuredGraph graph = new StructuredGraph(ALLOW_OPTIMISTIC_ASSUMPTIONS);
         test("getNodeClass", ConstantNode.forInt(42, graph));
     }
 
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/InstalledCodeExecuteHelperTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/InstalledCodeExecuteHelperTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -68,8 +68,8 @@
     }
 
     @Override
-    protected StructuredGraph parseEager(ResolvedJavaMethod m) {
-        StructuredGraph graph = super.parseEager(m);
+    protected StructuredGraph parseEager(ResolvedJavaMethod m, boolean allowOptimisticAssumptions) {
+        StructuredGraph graph = super.parseEager(m, allowOptimisticAssumptions);
         if (argsToBind != null) {
             Object receiver = isStatic(m.getModifiers()) ? null : this;
             Object[] args = argsWithReceiver(receiver, argsToBind);
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/MemoryUsageBenchmark.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/MemoryUsageBenchmark.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.hotspot.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
 import static com.oracle.graal.debug.internal.MemUseTrackerImpl.*;
 import static com.oracle.graal.hotspot.CompileTheWorld.*;
 import static com.oracle.graal.hotspot.CompileTheWorld.Options.*;
@@ -164,7 +165,7 @@
     private void compileAndTime(String methodName) {
 
         // Parse in eager mode to resolve methods/fields/classes
-        parseEager(methodName);
+        parseEager(methodName, ALLOW_OPTIMISTIC_ASSUMPTIONS);
 
         // Warm up and initialize compiler phases used by this compilation
         for (int i = 0; i < 10; i++) {
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,11 +22,12 @@
  */
 package com.oracle.graal.hotspot.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
+
 import java.lang.ref.*;
 
 import org.junit.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.compiler.test.*;
@@ -244,9 +245,9 @@
     private void testHelper(final String snippetName, final int expectedBarriers) throws Exception, SecurityException {
         ResolvedJavaMethod snippet = getResolvedJavaMethod(snippetName);
         try (Scope s = Debug.scope("WriteBarrierAdditionTest", snippet)) {
-            StructuredGraph graph = parseEager(snippet);
-            HighTierContext highContext = new HighTierContext(getProviders(), new Assumptions(false), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
-            MidTierContext midContext = new MidTierContext(getProviders(), new Assumptions(false), getCodeCache().getTarget(), OptimisticOptimizations.ALL, graph.method().getProfilingInfo(), null);
+            StructuredGraph graph = parseEager(snippet, DONT_ALLOW_OPTIMISTIC_ASSUMPTIONS);
+            HighTierContext highContext = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+            MidTierContext midContext = new MidTierContext(getProviders(), getCodeCache().getTarget(), OptimisticOptimizations.ALL, graph.method().getProfilingInfo(), null);
             new NodeIntrinsificationPhase(getProviders(), getSnippetReflection()).apply(graph);
             new InliningPhase(new InlineEverythingPolicy(), new CanonicalizerPhase(true)).apply(graph, highContext);
             new LoweringPhase(new CanonicalizerPhase(true), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, highContext);
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,11 +22,12 @@
  */
 package com.oracle.graal.hotspot.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
+
 import java.util.*;
 
 import org.junit.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.test.*;
 import com.oracle.graal.debug.*;
@@ -626,11 +627,11 @@
 
     private void testPredicate(final String snippet, final GraphPredicate expectedBarriers, final int... removedBarrierIndices) {
         try (Scope d = Debug.scope("WriteBarrierVerificationTest", new DebugDumpScope(snippet))) {
-            final StructuredGraph graph = parseEager(snippet);
-            HighTierContext highTierContext = new HighTierContext(getProviders(), new Assumptions(false), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+            final StructuredGraph graph = parseEager(snippet, ALLOW_OPTIMISTIC_ASSUMPTIONS);
+            HighTierContext highTierContext = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
             new InliningPhase(new CanonicalizerPhase(true)).apply(graph, highTierContext);
 
-            MidTierContext midTierContext = new MidTierContext(getProviders(), new Assumptions(false), getCodeCache().getTarget(), OptimisticOptimizations.ALL, graph.method().getProfilingInfo(), null);
+            MidTierContext midTierContext = new MidTierContext(getProviders(), getCodeCache().getTarget(), OptimisticOptimizations.ALL, graph.method().getProfilingInfo(), null);
 
             new LoweringPhase(new CanonicalizerPhase(true), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, highTierContext);
             new GuardLoweringPhase().apply(graph, midTierContext);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Wed Feb 11 16:08:50 2015 +0100
@@ -213,7 +213,7 @@
                     Replacements replacements = providers.getReplacements();
                     graph = replacements.getMethodSubstitution(method);
                     if (graph == null || entryBCI != INVOCATION_ENTRY_BCI) {
-                        graph = new StructuredGraph(method, entryBCI);
+                        graph = new StructuredGraph(method, entryBCI, OptAssumptions.getValue());
                     } else {
                         // Compiling method substitution - must clone the graph
                         graph = graph.copy();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotDebugInfoBuilder.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotDebugInfoBuilder.java	Wed Feb 11 16:08:50 2015 +0100
@@ -67,7 +67,7 @@
 
     @Override
     protected BytecodeFrame computeFrameForState(FrameState state) {
-        assert state.bci >= 0 || state.bci == BytecodeFrame.BEFORE_BCI;
+        assert state.bci >= 0 || state.bci == BytecodeFrame.BEFORE_BCI : state.bci;
         return super.computeFrameForState(state);
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java	Wed Feb 11 16:08:50 2015 +0100
@@ -69,10 +69,7 @@
         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);
-            }
+            registerGraphBuilderPlugins(providers.getMetaAccess(), plugins);
         }
 
         try (InitTimer st = timer("foreignCalls.initialize")) {
@@ -103,4 +100,9 @@
             }
         }
     }
+
+    protected void registerGraphBuilderPlugins(MetaAccessProvider metaAccess, GraphBuilderPlugins plugins) {
+        StandardGraphBuilderPlugins.registerPlugins(metaAccess, plugins);
+        HotSpotGraphBuilderPlugins.registerPlugins(metaAccess, plugins);
+    }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java	Wed Feb 11 16:08:50 2015 +0100
@@ -44,8 +44,8 @@
 
     private final HotSpotVMConfig config;
 
-    public HotSpotReplacementsImpl(Providers providers, SnippetReflectionProvider snippetReflection, HotSpotVMConfig config, Assumptions assumptions, TargetDescription target) {
-        super(providers, snippetReflection, assumptions, target);
+    public HotSpotReplacementsImpl(Providers providers, SnippetReflectionProvider snippetReflection, HotSpotVMConfig config, TargetDescription target) {
+        super(providers, snippetReflection, target);
         this.config = config;
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java	Wed Feb 11 16:08:50 2015 +0100
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.meta;
+
+import static com.oracle.graal.java.GraphBuilderContext.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.common.type.*;
+import com.oracle.graal.hotspot.replacements.*;
+import com.oracle.graal.java.*;
+import com.oracle.graal.java.GraphBuilderPlugins.InvocationPlugin;
+import com.oracle.graal.java.GraphBuilderPlugins.Registration;
+import com.oracle.graal.java.GraphBuilderPlugins.Registration.Receiver;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.options.*;
+
+/**
+ * Provider of HotSpot specific {@link GraphBuilderPlugin}s.
+ */
+public class HotSpotGraphBuilderPlugins {
+    public static void registerPlugins(MetaAccessProvider metaAccess, GraphBuilderPlugins plugins) {
+        // Object.class
+        Registration r = new Registration(plugins, metaAccess, Object.class);
+        r.register1("getClass", Receiver.class, new InvocationPlugin() {
+            public boolean apply(GraphBuilderContext builder, ValueNode rcvr) {
+                ObjectStamp objectStamp = (ObjectStamp) rcvr.stamp();
+                ValueNode mirror;
+                if (objectStamp.isExactType() && objectStamp.nonNull()) {
+                    mirror = builder.append(ConstantNode.forConstant(objectStamp.type().getJavaClass(), builder.getMetaAccess()));
+                } else {
+                    StampProvider stampProvider = builder.getStampProvider();
+                    LoadHubNode hub = builder.append(new LoadHubNode(stampProvider, nullCheckedValue(builder, rcvr)));
+                    mirror = builder.append(new HubGetClassNode(builder.getMetaAccess(), hub));
+                }
+                builder.push(Kind.Object, mirror);
+                return true;
+            }
+        });
+
+        // Class.class
+        r = new Registration(plugins, metaAccess, Class.class);
+        r.register2("cast", Receiver.class, Object.class, new InvocationPlugin() {
+            public boolean apply(GraphBuilderContext builder, ValueNode rcvr, ValueNode object) {
+                if (rcvr.isConstant() && !rcvr.isNullConstant() && object.isConstant()) {
+                    ResolvedJavaType type = builder.getConstantReflection().asJavaType(rcvr.asConstant());
+                    if (type != null && !type.isPrimitive() && type.isInstance(object.asJavaConstant())) {
+                        builder.push(Kind.Object, object);
+                        return true;
+                    }
+                }
+                return false;
+            }
+        });
+        // StableOptionValue.class
+        r = new Registration(plugins, metaAccess, StableOptionValue.class);
+        r.register1("getValue", Receiver.class, new InvocationPlugin() {
+            public boolean apply(GraphBuilderContext builder, ValueNode rcvr) {
+                if (rcvr.isConstant() && !rcvr.isNullConstant()) {
+                    Object object = ((HotSpotObjectConstantImpl) rcvr.asConstant()).object();
+                    StableOptionValue<?> option = (StableOptionValue<?>) object;
+                    ConstantNode value = builder.append(ConstantNode.forConstant(HotSpotObjectConstantImpl.forObject(option.getValue()), builder.getMetaAccess()));
+                    builder.push(Kind.Object, value);
+                    return true;
+                }
+                return false;
+            }
+        });
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPluginsProvider.java	Wed Feb 11 15:53:27 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.meta;
-
-import static com.oracle.graal.java.GraphBuilderContext.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.api.runtime.*;
-import com.oracle.graal.compiler.common.type.*;
-import com.oracle.graal.hotspot.replacements.*;
-import com.oracle.graal.java.*;
-import com.oracle.graal.java.GraphBuilderPlugins.InvocationPlugin;
-import com.oracle.graal.java.GraphBuilderPlugins.Registration;
-import com.oracle.graal.java.GraphBuilderPlugins.Registration.Receiver;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.extended.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.options.*;
-
-/**
- * Provider of HotSpot specific {@link GraphBuilderPlugin}s.
- */
-@ServiceProvider(GraphBuilderPluginsProvider.class)
-public class HotSpotGraphBuilderPluginsProvider implements GraphBuilderPluginsProvider {
-    public void registerPlugins(MetaAccessProvider metaAccess, GraphBuilderPlugins plugins) {
-        // Object.class
-        Registration r = new Registration(plugins, metaAccess, Object.class);
-        r.register1("getClass", Receiver.class, new InvocationPlugin() {
-            public boolean apply(GraphBuilderContext builder, ValueNode rcvr) {
-                ObjectStamp objectStamp = (ObjectStamp) rcvr.stamp();
-                ValueNode mirror;
-                if (objectStamp.isExactType() && objectStamp.nonNull()) {
-                    mirror = builder.append(ConstantNode.forConstant(objectStamp.type().getJavaClass(), builder.getMetaAccess()));
-                } else {
-                    StampProvider stampProvider = builder.getStampProvider();
-                    LoadHubNode hub = builder.append(new LoadHubNode(stampProvider, nullCheckedValue(builder, rcvr)));
-                    mirror = builder.append(new HubGetClassNode(builder.getMetaAccess(), hub));
-                }
-                builder.push(Kind.Object, mirror);
-                return true;
-            }
-        });
-
-        // Class.class
-        r = new Registration(plugins, metaAccess, Class.class);
-        r.register2("cast", Receiver.class, Object.class, new InvocationPlugin() {
-            public boolean apply(GraphBuilderContext builder, ValueNode rcvr, ValueNode object) {
-                if (rcvr.isConstant() && !rcvr.isNullConstant() && object.isConstant()) {
-                    ResolvedJavaType type = builder.getConstantReflection().asJavaType(rcvr.asConstant());
-                    if (type != null && !type.isPrimitive() && type.isInstance(object.asJavaConstant())) {
-                        builder.push(Kind.Object, object);
-                        return true;
-                    }
-                }
-                return false;
-            }
-        });
-        // StableOptionValue.class
-        r = new Registration(plugins, metaAccess, StableOptionValue.class);
-        r.register1("getValue", Receiver.class, new InvocationPlugin() {
-            public boolean apply(GraphBuilderContext builder, ValueNode rcvr) {
-                if (rcvr.isConstant() && !rcvr.isNullConstant()) {
-                    Object object = ((HotSpotObjectConstantImpl) rcvr.asConstant()).object();
-                    StableOptionValue<?> option = (StableOptionValue<?>) object;
-                    ConstantNode value = builder.append(ConstantNode.forConstant(HotSpotObjectConstantImpl.forObject(option.getValue()), builder.getMetaAccess()));
-                    builder.push(Kind.Object, value);
-                    return true;
-                }
-                return false;
-            }
-        });
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/NativeCallStubGraphBuilder.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/NativeCallStubGraphBuilder.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.hotspot.nfi;
 
+import static com.oracle.graal.api.code.Assumptions.*;
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 
 import java.util.*;
@@ -52,7 +53,7 @@
     public static StructuredGraph getGraph(HotSpotProviders providers, RawNativeCallNodeFactory factory, long functionPointer, Class<?> returnType, Class<?>... argumentTypes) {
         try {
             ResolvedJavaMethod method = providers.getMetaAccess().lookupJavaMethod(NativeCallStubGraphBuilder.class.getMethod("libCall", Object.class, Object.class, Object.class));
-            StructuredGraph g = new StructuredGraph(method);
+            StructuredGraph g = new StructuredGraph(method, DONT_ALLOW_OPTIMISTIC_ASSUMPTIONS);
             ParameterNode arg0 = g.unique(new ParameterNode(0, StampFactory.forKind(Kind.Object)));
             ParameterNode arg1 = g.unique(new ParameterNode(1, StampFactory.forKind(Kind.Object)));
             ParameterNode arg2 = g.unique(new ParameterNode(2, StampFactory.forKind(Kind.Object)));
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteTargetNode.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteTargetNode.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.hotspot.replacements;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.spi.*;
@@ -43,10 +42,10 @@
         return arguments.get(0);
     }
 
-    private ConstantNode getConstantCallTarget(MetaAccessProvider metaAccess, Assumptions assumptions) {
+    private ConstantNode getConstantCallTarget(MetaAccessProvider metaAccess) {
         if (getCallSite().isConstant() && !getCallSite().isNullConstant()) {
             HotSpotObjectConstant c = (HotSpotObjectConstant) getCallSite().asConstant();
-            JavaConstant target = c.getCallSiteTarget(assumptions);
+            JavaConstant target = c.getCallSiteTarget(graph().getAssumptions());
             if (target != null) {
                 return ConstantNode.forConstant(target, metaAccess);
             }
@@ -56,7 +55,7 @@
 
     @Override
     public Node canonical(CanonicalizerTool tool) {
-        ConstantNode target = getConstantCallTarget(tool.getMetaAccess(), tool.assumptions());
+        ConstantNode target = getConstantCallTarget(tool.getMetaAccess());
         if (target != null) {
             return target;
         }
@@ -66,7 +65,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        ConstantNode target = getConstantCallTarget(tool.getMetaAccess(), tool.assumptions());
+        ConstantNode target = getConstantCallTarget(tool.getMetaAccess());
 
         if (target != null) {
             graph().replaceFixedWithFloating(this, target);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java	Wed Feb 11 16:08:50 2015 +0100
@@ -226,7 +226,8 @@
             if (replacer.instanceOf instanceof InstanceOfNode) {
                 InstanceOfNode instanceOf = (InstanceOfNode) replacer.instanceOf;
                 ValueNode object = instanceOf.getValue();
-                TypeCheckHints hintInfo = new TypeCheckHints(instanceOf.type(), instanceOf.profile(), tool.assumptions(), TypeCheckMinProfileHitProbability.getValue(), TypeCheckMaxHints.getValue());
+                Assumptions assumptions = instanceOf.graph().getAssumptions();
+                TypeCheckHints hintInfo = new TypeCheckHints(instanceOf.type(), instanceOf.profile(), assumptions, TypeCheckMinProfileHitProbability.getValue(), TypeCheckMaxHints.getValue());
                 final HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) instanceOf.type();
                 ConstantNode hub = ConstantNode.forConstant(KlassPointerStamp.klassNonNull(), type.klass(), providers.getMetaAccess(), instanceOf.graph());
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java	Wed Feb 11 16:08:50 2015 +0100
@@ -26,6 +26,7 @@
 
 import java.lang.reflect.*;
 
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
@@ -68,9 +69,10 @@
                 }
                 assert false : "unhandled array type " + type.getComponentType().getKind();
             } else {
-                type = getConcreteType(getObject().stamp(), tool.assumptions(), tool.getMetaAccess());
+                Assumptions assumptions = graph().getAssumptions();
+                type = getConcreteType(getObject().stamp(), assumptions, tool.getMetaAccess());
                 if (type != null) {
-                    StructuredGraph newGraph = new StructuredGraph();
+                    StructuredGraph newGraph = new StructuredGraph(assumptions.useOptimisticAssumptions());
                     ParameterNode param = newGraph.unique(new ParameterNode(0, getObject().stamp()));
                     NewInstanceNode newInstance = newGraph.add(new NewInstanceNode(type, true));
                     newGraph.addAfterFixed(newGraph.start(), newInstance);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/ArrayCopyNode.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/ArrayCopyNode.java	Wed Feb 11 16:08:50 2015 +0100
@@ -73,7 +73,7 @@
         }
         // the canonicalization before loop unrolling is needed to propagate the length into
         // additions, etc.
-        PhaseContext context = new PhaseContext(tool.getMetaAccess(), tool.getConstantReflection(), tool.getLowerer(), tool.getReplacements(), tool.assumptions(), tool.getStampProvider());
+        PhaseContext context = new PhaseContext(tool.getMetaAccess(), tool.getConstantReflection(), tool.getLowerer(), tool.getReplacements(), tool.getStampProvider());
         new CanonicalizerPhase(true).apply(snippetGraph, context);
         new LoopFullUnrollPhase(new CanonicalizerPhase(true)).apply(snippetGraph, context);
         new CanonicalizerPhase(true).apply(snippetGraph, context);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.hotspot.stubs;
 
+import static com.oracle.graal.api.code.Assumptions.*;
 import static com.oracle.graal.api.code.CallingConvention.Type.*;
 import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.RegisterEffect.*;
 
@@ -190,7 +191,7 @@
         Class<?>[] args = linkage.getDescriptor().getArgumentTypes();
         boolean isObjectResult = linkage.getOutgoingCallingConvention().getReturn().getKind() == Kind.Object;
 
-        StructuredGraph graph = new StructuredGraph(toString(), null);
+        StructuredGraph graph = new StructuredGraph(toString(), null, DONT_ALLOW_OPTIMISTIC_ASSUMPTIONS);
 
         GraphKit kit = new HotSpotGraphKit(graph, providers);
         ParameterNode[] params = createParameters(kit, args);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Wed Feb 11 16:08:50 2015 +0100
@@ -23,7 +23,6 @@
 package com.oracle.graal.hotspot.stubs;
 
 import static com.oracle.graal.compiler.GraalCompiler.*;
-import static com.oracle.graal.compiler.common.GraalOptions.*;
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 
 import java.util.*;
@@ -158,6 +157,7 @@
         if (code == null) {
             try (Scope d = Debug.sandbox("CompilingStub", DebugScope.getConfig(), providers.getCodeCache(), debugScopeContext())) {
                 final StructuredGraph graph = getGraph();
+                assert !graph.getAssumptions().useOptimisticAssumptions();
                 if (!(graph.start() instanceof StubStartNode)) {
                     StubStartNode newStart = graph.add(new StubStartNode(Stub.this));
                     newStart.setStateAfter(graph.start().stateAfter());
@@ -171,14 +171,12 @@
 
                 compResult = new CompilationResult(toString());
                 try (Scope s0 = Debug.scope("StubCompilation", graph, providers.getCodeCache())) {
-                    Assumptions assumptions = new Assumptions(OptAssumptions.getValue());
                     Suites defaultSuites = providers.getSuites().getDefaultSuites();
                     Suites suites = new Suites(new PhaseSuite<>(), defaultSuites.getMidTier(), defaultSuites.getLowTier());
-                    SchedulePhase schedule = emitFrontEnd(providers, target, graph, assumptions, null, providers.getSuites().getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL,
-                                    getProfilingInfo(graph), null, suites);
+                    SchedulePhase schedule = emitFrontEnd(providers, target, graph, null, providers.getSuites().getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL, getProfilingInfo(graph),
+                                    null, suites);
                     LIRSuites lirSuites = providers.getSuites().getDefaultLIRSuites();
-                    emitBackEnd(graph, Stub.this, incomingCc, getInstalledCodeOwner(), backend, target, compResult, CompilationResultBuilderFactory.Default, assumptions, schedule,
-                                    getRegisterConfig(), lirSuites);
+                    emitBackEnd(graph, Stub.this, incomingCc, getInstalledCodeOwner(), backend, target, compResult, CompilationResultBuilderFactory.Default, schedule, getRegisterConfig(), lirSuites);
                 } catch (Throwable e) {
                     throw Debug.handle(e);
                 }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java	Wed Feb 11 16:08:50 2015 +0100
@@ -24,6 +24,7 @@
 package com.oracle.graal.java;
 
 import static com.oracle.graal.api.code.TypeCheckHints.*;
+import static com.oracle.graal.api.meta.DeoptimizationReason.*;
 import static com.oracle.graal.bytecode.Bytecodes.*;
 
 import java.util.*;
@@ -604,9 +605,19 @@
 
     protected abstract T createNewInstance(ResolvedJavaType type, boolean fillContents);
 
+    @SuppressWarnings("unchecked")
     void genNewInstance(int cpi) {
         JavaType type = lookupType(cpi, NEW);
         if (type instanceof ResolvedJavaType && ((ResolvedJavaType) type).isInitialized()) {
+            ResolvedJavaType[] skippedExceptionTypes = this.graphBuilderConfig.getSkippedExceptionTypes();
+            if (skippedExceptionTypes != null) {
+                for (ResolvedJavaType exceptionType : skippedExceptionTypes) {
+                    if (exceptionType.isAssignableFrom((ResolvedJavaType) type)) {
+                        append((T) new DeoptimizeNode(DeoptimizationAction.None, TransferToInterpreter));
+                        return;
+                    }
+                }
+            }
             frameState.apush(append(createNewInstance((ResolvedJavaType) type, true)));
         } else {
             handleUnresolvedNewInstance(type);
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/DefaultGraphBuilderPlugins.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/DefaultGraphBuilderPlugins.java	Wed Feb 11 16:08:50 2015 +0100
@@ -55,6 +55,12 @@
         return plugins.get(method);
     }
 
+    public DefaultGraphBuilderPlugins copy() {
+        DefaultGraphBuilderPlugins result = new DefaultGraphBuilderPlugins();
+        result.plugins.putAll(plugins);
+        return result;
+    }
+
     @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/GraphBuilderContext.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderContext.java	Wed Feb 11 16:08:50 2015 +0100
@@ -24,6 +24,7 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.*;
@@ -41,6 +42,8 @@
 
     <T extends FloatingNode> T append(T value);
 
+    <T extends ValueNode> T append(T value);
+
     StampProvider getStampProvider();
 
     MetaAccessProvider getMetaAccess();
@@ -49,6 +52,8 @@
 
     ConstantReflectionProvider getConstantReflection();
 
+    SnippetReflectionProvider getSnippetReflection();
+
     void push(Kind kind, ValueNode value);
 
     /**
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Wed Feb 11 16:08:50 2015 +0100
@@ -32,6 +32,7 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.meta.ProfilingInfo.TriState;
+import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.bytecode.*;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.compiler.common.calc.*;
@@ -77,8 +78,7 @@
 
     @Override
     protected void run(StructuredGraph graph, HighTierContext context) {
-        new Instance(context.getMetaAccess(), context.getStampProvider(), context.getAssumptions(), context.getConstantReflection(), graphBuilderConfig, graphBuilderPlugins,
-                        context.getOptimisticOptimizations()).run(graph);
+        new Instance(context.getMetaAccess(), context.getStampProvider(), null, context.getConstantReflection(), graphBuilderConfig, graphBuilderPlugins, context.getOptimisticOptimizations()).run(graph);
     }
 
     public GraphBuilderConfiguration getGraphBuilderConfig() {
@@ -101,8 +101,8 @@
         private final GraphBuilderPlugins graphBuilderPlugins;
         private final OptimisticOptimizations optimisticOpts;
         private final StampProvider stampProvider;
-        private final Assumptions assumptions;
         private final ConstantReflectionProvider constantReflection;
+        private final SnippetReflectionProvider snippetReflectionProvider;
 
         /**
          * Gets the graph being processed by this builder.
@@ -111,21 +111,21 @@
             return currentGraph;
         }
 
-        public Instance(MetaAccessProvider metaAccess, StampProvider stampProvider, Assumptions assumptions, ConstantReflectionProvider constantReflection,
+        public Instance(MetaAccessProvider metaAccess, StampProvider stampProvider, SnippetReflectionProvider snippetReflectionProvider, ConstantReflectionProvider constantReflection,
                         GraphBuilderConfiguration graphBuilderConfig, GraphBuilderPlugins graphBuilderPlugins, OptimisticOptimizations optimisticOpts) {
             this.graphBuilderConfig = graphBuilderConfig;
             this.optimisticOpts = optimisticOpts;
             this.metaAccess = metaAccess;
             this.stampProvider = stampProvider;
-            this.assumptions = assumptions;
             this.graphBuilderPlugins = graphBuilderPlugins;
             this.constantReflection = constantReflection;
+            this.snippetReflectionProvider = snippetReflectionProvider;
             assert metaAccess != null;
         }
 
-        public Instance(MetaAccessProvider metaAccess, StampProvider stampProvider, Assumptions assumptions, ConstantReflectionProvider constantReflection,
-                        GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts) {
-            this(metaAccess, stampProvider, assumptions, constantReflection, graphBuilderConfig, null, optimisticOpts);
+        public Instance(MetaAccessProvider metaAccess, StampProvider stampProvider, ConstantReflectionProvider constantReflection, GraphBuilderConfiguration graphBuilderConfig,
+                        OptimisticOptimizations optimisticOpts) {
+            this(metaAccess, stampProvider, null, constantReflection, graphBuilderConfig, null, optimisticOpts);
         }
 
         @Override
@@ -296,8 +296,9 @@
                     processBlock(this, returnBlock);
                     processBlock(this, unwindBlock);
 
-                    Debug.dump(currentGraph, "After bytecode parsing");
-
+                    if (Debug.isDumpEnabled()) {
+                        Debug.dump(currentGraph, "Bytecodes parsed: " + method.getDeclaringClass().getUnqualifiedName() + "." + method.getName());
+                    }
                 }
             }
 
@@ -522,7 +523,7 @@
 
             @Override
             protected ValueNode genIntegerSub(Kind kind, ValueNode x, ValueNode y) {
-                return new SubNode(x, y);
+                return SubNode.create(x, y);
             }
 
             @Override
@@ -532,12 +533,12 @@
 
             @Override
             protected ValueNode genFloatAdd(Kind kind, ValueNode x, ValueNode y, boolean isStrictFP) {
-                return new AddNode(x, y);
+                return AddNode.create(x, y);
             }
 
             @Override
             protected ValueNode genFloatSub(Kind kind, ValueNode x, ValueNode y, boolean isStrictFP) {
-                return new SubNode(x, y);
+                return SubNode.create(x, y);
             }
 
             @Override
@@ -664,12 +665,12 @@
 
             @Override
             protected ValueNode createCheckCast(ResolvedJavaType type, ValueNode object, JavaTypeProfile profileForTypeCheck, boolean forStoreCheck) {
-                return new CheckCastNode(type, object, profileForTypeCheck, forStoreCheck);
+                return CheckCastNode.create(type, object, profileForTypeCheck, forStoreCheck);
             }
 
             @Override
             protected ValueNode createInstanceOf(ResolvedJavaType type, ValueNode object, JavaTypeProfile profileForTypeCheck) {
-                return new InstanceOfNode(type, object, profileForTypeCheck);
+                return InstanceOfNode.create(type, object, profileForTypeCheck);
             }
 
             @Override
@@ -832,7 +833,7 @@
                 InvokeKind invokeKind = initialInvokeKind;
                 if (initialInvokeKind.isIndirect()) {
                     ResolvedJavaType contextType = this.frameState.method.getDeclaringClass();
-                    ResolvedJavaMethod specialCallTarget = MethodCallTargetNode.findSpecialCallTarget(initialInvokeKind, args[0], initialTargetMethod, assumptions, contextType);
+                    ResolvedJavaMethod specialCallTarget = MethodCallTargetNode.findSpecialCallTarget(initialInvokeKind, args[0], initialTargetMethod, contextType);
                     if (specialCallTarget != null) {
                         invokeKind = InvokeKind.Special;
                         targetMethod = specialCallTarget;
@@ -860,6 +861,12 @@
 
                 if (graphBuilderPlugins != null) {
                     if (tryUsingInvocationPlugin(args, targetMethod, resultType)) {
+                        if (GraalOptions.TraceInlineDuringParsing.getValue()) {
+                            for (int i = 0; i < this.currentDepth; ++i) {
+                                TTY.print(' ');
+                            }
+                            TTY.println("Used invocation plugin for " + targetMethod);
+                        }
                         return;
                     }
                 }
@@ -867,8 +874,20 @@
                 InlineInvokePlugin inlineInvokePlugin = graphBuilderConfig.getInlineInvokePlugin();
                 if (inlineInvokePlugin != null && invokeKind.isDirect() && targetMethod.canBeInlined() && targetMethod.hasBytecodes() &&
                                 inlineInvokePlugin.shouldInlineInvoke(targetMethod, currentDepth)) {
+                    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());
+                    }
                     parseAndInlineCallee(targetMethod, args);
                     return;
+                } else {
+                    // System.out.println("Could not inline invoke " + targetMethod);
                 }
 
                 MethodCallTargetNode callTarget = currentGraph.add(createMethodCallTarget(invokeKind, targetMethod, args, returnType));
@@ -940,6 +959,15 @@
                 if (calleeBeforeUnwindNode != null) {
                     ValueNode calleeUnwindValue = parser.getUnwindValue();
                     assert calleeUnwindValue != null;
+                    if (calleeBeforeUnwindNode instanceof AbstractMergeNode) {
+                        AbstractMergeNode mergeNode = (AbstractMergeNode) calleeBeforeUnwindNode;
+                        HIRFrameStateBuilder dispatchState = frameState.copy();
+                        dispatchState.clearStack();
+                        dispatchState.apush(calleeUnwindValue);
+                        dispatchState.setRethrowException(true);
+                        mergeNode.setStateAfter(dispatchState.create(bci()));
+
+                    }
                     calleeBeforeUnwindNode.setNext(handleException(calleeUnwindValue, bci()));
                 }
             }
@@ -1063,8 +1091,13 @@
                 return ConstantNode.forConstant(constant, metaAccess, currentGraph);
             }
 
+            @SuppressWarnings("unchecked")
             @Override
-            protected ValueNode append(ValueNode v) {
+            public ValueNode append(ValueNode v) {
+                if (v.graph() != null) {
+                    // This node was already appended to the graph.
+                    return v;
+                }
                 if (v instanceof ControlSinkNode) {
                     return append((ControlSinkNode) v);
                 }
@@ -1655,7 +1688,7 @@
             }
 
             public Assumptions getAssumptions() {
-                return assumptions;
+                return currentGraph.getAssumptions();
             }
 
             public void push(Kind kind, ValueNode value) {
@@ -1675,6 +1708,10 @@
                 return constantReflection;
             }
 
+            public SnippetReflectionProvider getSnippetReflection() {
+                return snippetReflectionProvider;
+            }
+
         }
     }
 }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPlugin.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPlugin.java	Wed Feb 11 16:08:50 2015 +0100
@@ -27,7 +27,6 @@
  *
  * Concrete plugins implement one of the sub-interfaces of this interface.
  *
- * @see GraphBuilderPluginsProvider
  * @see GraphBuilderPlugins
  * @see GraphBuilderPlugins.Registration
  */
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPlugins.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPlugins.java	Wed Feb 11 16:08:50 2015 +0100
@@ -296,4 +296,6 @@
      * @return the plugin associated with {@code method} or {@code null} if none exists
      */
     InvocationPlugin lookupInvocation(ResolvedJavaMethod method);
+
+    DefaultGraphBuilderPlugins copy();
 }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPluginsProvider.java	Wed Feb 11 15:53:27 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.java;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.api.runtime.*;
-
-/**
- * Interface for providers of {@link GraphBuilderPlugin}s.
- */
-public interface GraphBuilderPluginsProvider extends Service {
-    /**
-     * Registers the plugins provided by this object.
-     */
-    void registerPlugins(MetaAccessProvider metaAccess, GraphBuilderPlugins plugins);
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/StandardGraphBuilderPlugins.java	Wed Feb 11 16:08:50 2015 +0100
@@ -0,0 +1,100 @@
+/*
+ * 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 static com.oracle.graal.java.GraphBuilderContext.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.java.GraphBuilderPlugins.InvocationPlugin;
+import com.oracle.graal.java.GraphBuilderPlugins.Registration;
+import com.oracle.graal.java.GraphBuilderPlugins.Registration.Receiver;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.java.*;
+
+/**
+ * Provider of non-runtime specific {@link GraphBuilderPlugin}s.
+ */
+public class StandardGraphBuilderPlugins {
+    public static void registerPlugins(MetaAccessProvider metaAccess, GraphBuilderPlugins plugins) {
+        Registration r = new Registration(plugins, metaAccess, Object.class);
+        r.register1("<init>", Receiver.class, new InvocationPlugin() {
+            public boolean apply(GraphBuilderContext builder, ValueNode object) {
+                if (RegisterFinalizerNode.mayHaveFinalizer(object, builder.getAssumptions())) {
+                    builder.append(new RegisterFinalizerNode(object));
+                }
+                return true;
+            }
+        });
+
+        for (Kind kind : Kind.values()) {
+            if (kind.isPrimitive() && kind != Kind.Void) {
+                new BoxPlugin(kind).register(metaAccess, plugins);
+                new UnboxPlugin(kind).register(metaAccess, plugins);
+            }
+        }
+
+        GraalDirectivePlugins.registerPlugins(metaAccess, plugins);
+    }
+
+    static class BoxPlugin implements InvocationPlugin {
+
+        private final Kind kind;
+
+        BoxPlugin(Kind kind) {
+            this.kind = kind;
+        }
+
+        public boolean apply(GraphBuilderContext builder, ValueNode value) {
+            ResolvedJavaType resultType = builder.getMetaAccess().lookupJavaType(kind.toBoxedJavaClass());
+            builder.push(Kind.Object, builder.append(new BoxNode(value, resultType, kind)));
+            return true;
+        }
+
+        void register(MetaAccessProvider metaAccess, GraphBuilderPlugins plugins) {
+            ResolvedJavaMethod method = Registration.resolve(metaAccess, kind.toBoxedJavaClass(), "valueOf", kind.toJavaClass());
+            plugins.register(method, this);
+        }
+    }
+
+    static class UnboxPlugin implements InvocationPlugin {
+
+        private final Kind kind;
+
+        UnboxPlugin(Kind kind) {
+            this.kind = kind;
+        }
+
+        public boolean apply(GraphBuilderContext builder, ValueNode value) {
+            ValueNode valueNode = UnboxNode.create(builder.getMetaAccess(), builder.getConstantReflection(), nullCheckedValue(builder, value), kind);
+            builder.push(kind.getStackKind(), builder.append(valueNode));
+            return true;
+        }
+
+        void register(MetaAccessProvider metaAccess, GraphBuilderPlugins plugins) {
+            String name = kind.toJavaClass().getSimpleName() + "Value";
+            ResolvedJavaMethod method = Registration.resolve(metaAccess, kind.toBoxedJavaClass(), name);
+            plugins.register(method, this);
+        }
+    }
+}
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/StandardGraphBuilderPluginsProvider.java	Wed Feb 11 15:53:27 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,101 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.java;
-
-import static com.oracle.graal.java.GraphBuilderContext.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.api.runtime.*;
-import com.oracle.graal.java.GraphBuilderPlugins.InvocationPlugin;
-import com.oracle.graal.java.GraphBuilderPlugins.Registration;
-import com.oracle.graal.java.GraphBuilderPlugins.Registration.Receiver;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.extended.*;
-import com.oracle.graal.nodes.java.*;
-
-/**
- * Provider of non-runtime specific {@link GraphBuilderPlugin}s.
- */
-@ServiceProvider(GraphBuilderPluginsProvider.class)
-public class StandardGraphBuilderPluginsProvider implements GraphBuilderPluginsProvider {
-    public void registerPlugins(MetaAccessProvider metaAccess, GraphBuilderPlugins plugins) {
-        Registration r = new Registration(plugins, metaAccess, Object.class);
-        r.register1("<init>", Receiver.class, new InvocationPlugin() {
-            public boolean apply(GraphBuilderContext builder, ValueNode object) {
-                if (RegisterFinalizerNode.mayHaveFinalizer(object, builder.getAssumptions())) {
-                    builder.append(new RegisterFinalizerNode(object));
-                }
-                return true;
-            }
-        });
-
-        for (Kind kind : Kind.values()) {
-            if (kind.isPrimitive() && kind != Kind.Void) {
-                new BoxPlugin(kind).register(metaAccess, plugins);
-                new UnboxPlugin(kind).register(metaAccess, plugins);
-            }
-        }
-
-        GraalDirectivePlugins.registerPlugins(metaAccess, plugins);
-    }
-
-    static class BoxPlugin implements InvocationPlugin {
-
-        private final Kind kind;
-
-        BoxPlugin(Kind kind) {
-            this.kind = kind;
-        }
-
-        public boolean apply(GraphBuilderContext builder, ValueNode value) {
-            ResolvedJavaType resultType = builder.getMetaAccess().lookupJavaType(kind.toBoxedJavaClass());
-            builder.push(Kind.Object, builder.append(new BoxNode(value, resultType, kind)));
-            return true;
-        }
-
-        void register(MetaAccessProvider metaAccess, GraphBuilderPlugins plugins) {
-            ResolvedJavaMethod method = Registration.resolve(metaAccess, kind.toBoxedJavaClass(), "valueOf", kind.toJavaClass());
-            plugins.register(method, this);
-        }
-    }
-
-    static class UnboxPlugin implements InvocationPlugin {
-
-        private final Kind kind;
-
-        UnboxPlugin(Kind kind) {
-            this.kind = kind;
-        }
-
-        public boolean apply(GraphBuilderContext builder, ValueNode value) {
-            builder.push(kind.getStackKind(), builder.append(new UnboxNode(nullCheckedValue(builder, value), kind)));
-            return true;
-        }
-
-        void register(MetaAccessProvider metaAccess, GraphBuilderPlugins plugins) {
-            String name = kind.toJavaClass().getSimpleName() + "Value";
-            ResolvedJavaMethod method = Registration.resolve(metaAccess, kind.toBoxedJavaClass(), name);
-            plugins.register(method, this);
-        }
-    }
-}
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/JTTTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/JTTTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -56,8 +56,8 @@
     }
 
     @Override
-    protected StructuredGraph parseEager(ResolvedJavaMethod m) {
-        StructuredGraph graph = super.parseEager(m);
+    protected StructuredGraph parseEager(ResolvedJavaMethod m, boolean allowOptimisticAssumptions) {
+        StructuredGraph graph = super.parseEager(m, allowOptimisticAssumptions);
         if (argsToBind != null) {
             Object receiver = isStatic(m.getModifiers()) ? null : this;
             Object[] args = argsWithReceiver(receiver, argsToBind);
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopEx.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopEx.java	Wed Feb 11 16:08:50 2015 +0100
@@ -233,26 +233,23 @@
         return data;
     }
 
-    public NodeBitMap nodesInLoopFrom(AbstractBeginNode point, AbstractBeginNode until) {
+    public NodeBitMap nodesInLoopBranch(AbstractBeginNode branch) {
         Collection<AbstractBeginNode> blocks = new LinkedList<>();
         Collection<LoopExitNode> exits = new LinkedList<>();
         Queue<Block> work = new LinkedList<>();
         ControlFlowGraph cfg = loopsData().controlFlowGraph();
-        work.add(cfg.blockFor(point));
-        Block untilBlock = until != null ? cfg.blockFor(until) : null;
+        work.add(cfg.blockFor(branch));
         while (!work.isEmpty()) {
             Block b = work.remove();
-            if (b == untilBlock) {
-                continue;
-            }
             if (loop().getExits().contains(b)) {
                 exits.add((LoopExitNode) b.getBeginNode());
-            } else if (loop().getBlocks().contains(b)) {
+            } else {
+                assert loop().getBlocks().contains(b);
                 blocks.add(b.getBeginNode());
                 work.addAll(b.getDominated());
             }
         }
-        return LoopFragment.computeNodes(point.graph(), blocks, exits);
+        return LoopFragment.computeNodes(branch.graph(), blocks, exits);
     }
 
     public Map<Node, InductionVariable> getInductionVariables() {
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopPolicies.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopPolicies.java	Wed Feb 11 16:08:50 2015 +0100
@@ -30,10 +30,19 @@
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.VirtualState.VirtualClosure;
 import com.oracle.graal.nodes.cfg.*;
 import com.oracle.graal.nodes.debug.*;
+import com.oracle.graal.options.*;
 
 public abstract class LoopPolicies {
+    @Option(help = "", type = OptionType.Expert) public static final OptionValue<Integer> LoopUnswitchMaxIncrease = new OptionValue<>(500);
+    @Option(help = "", type = OptionType.Expert) public static final OptionValue<Integer> LoopUnswitchTrivial = new OptionValue<>(10);
+    @Option(help = "", type = OptionType.Expert) public static final OptionValue<Double> LoopUnswitchFrequencyBoost = new OptionValue<>(10.0);
+
+    @Option(help = "", type = OptionType.Expert) public static final OptionValue<Integer> FullUnrollMaxNodes = new OptionValue<>(300);
+    @Option(help = "", type = OptionType.Expert) public static final OptionValue<Integer> FullUnrollMaxIterations = new OptionValue<>(600);
+    @Option(help = "", type = OptionType.Expert) public static final OptionValue<Integer> ExactFullUnrollMaxNodes = new OptionValue<>(1200);
 
     private LoopPolicies() {
         // does not need to be instantiated
@@ -82,31 +91,57 @@
     }
 
     public static boolean shouldTryUnswitch(LoopEx loop) {
-        return loop.loopBegin().unswitches() <= LoopMaxUnswitch.getValue();
+        LoopBeginNode loopBegin = loop.loopBegin();
+        double loopFrequency = loopBegin.loopFrequency();
+        if (loopFrequency <= 1.0) {
+            return false;
+        }
+        return loopBegin.unswitches() <= LoopMaxUnswitch.getValue();
+    }
+
+    private static final class CountingClosure implements VirtualClosure {
+        int count;
+
+        public void apply(VirtualState node) {
+            count++;
+        }
+    }
+
+    private static class IsolatedInitialization {
+        static final DebugMetric UNSWITCH_SPLIT_WITH_PHIS = Debug.metric("UnswitchSplitWithPhis");
     }
 
     public static boolean shouldUnswitch(LoopEx loop, List<ControlSplitNode> controlSplits) {
-        int loopTotal = loop.size();
         int inBranchTotal = 0;
-        double maxProbability = 0;
+        int phis = 0;
         for (ControlSplitNode controlSplit : controlSplits) {
-            Block postDomBlock = loop.loopsData().controlFlowGraph().blockFor(controlSplit).getPostdominator();
-            AbstractBeginNode postDom = postDomBlock != null ? postDomBlock.getBeginNode() : null;
             for (Node successor : controlSplit.successors()) {
                 AbstractBeginNode branch = (AbstractBeginNode) successor;
                 // this may count twice because of fall-through in switches
-                inBranchTotal += loop.nodesInLoopFrom(branch, postDom).count();
-                double probability = controlSplit.probability(branch);
-                if (probability > maxProbability) {
-                    maxProbability = probability;
-                }
+                inBranchTotal += loop.nodesInLoopBranch(branch).count();
+            }
+            Block postDomBlock = loop.loopsData().controlFlowGraph().blockFor(controlSplit).getPostdominator();
+            if (postDomBlock != null) {
+                IsolatedInitialization.UNSWITCH_SPLIT_WITH_PHIS.increment();
+                phis += ((MergeNode) postDomBlock.getBeginNode()).phis().count();
             }
         }
-        int netDiff = loopTotal - (inBranchTotal);
-        double uncertainty = 1 - maxProbability;
-        int maxDiff = LoopUnswitchMaxIncrease.getValue() + (int) (LoopUnswitchUncertaintyBoost.getValue() * loop.loopBegin().loopFrequency() * uncertainty);
-        Debug.log("shouldUnswitch(%s, %s) : delta=%d, max=%d, %.2f%% inside of branches", loop, controlSplits, netDiff, maxDiff, (double) (inBranchTotal) / loopTotal * 100);
-        return netDiff <= maxDiff;
+
+        CountingClosure stateNodesCount = new CountingClosure();
+        double loopFrequency = loop.loopBegin().loopFrequency();
+        int maxDiff = LoopUnswitchTrivial.getValue() + (int) (LoopUnswitchFrequencyBoost.getValue() * (loopFrequency - 1.0 + phis));
+
+        maxDiff = Math.min(maxDiff, LoopUnswitchMaxIncrease.getValue());
+        int remainingGraphSpace = MaximumDesiredSize.getValue() - loop.loopBegin().graph().getNodeCount();
+        maxDiff = Math.min(maxDiff, remainingGraphSpace);
+
+        loop.loopBegin().stateAfter().applyToVirtual(stateNodesCount);
+        int loopTotal = loop.size() - loop.loopBegin().phis().count() - stateNodesCount.count - 1;
+        int actualDiff = loopTotal - inBranchTotal;
+
+        Debug.log("shouldUnswitch(%s, %s) : delta=%d (%.2f%% inside of branches), max=%d, f=%.2f, phis=%d -> %b", loop, controlSplits, actualDiff, (double) (inBranchTotal) / loopTotal * 100, maxDiff,
+                        loopFrequency, phis, actualDiff <= maxDiff);
+        return actualDiff <= maxDiff;
     }
 
 }
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopTransformations.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopTransformations.java	Wed Feb 11 16:08:50 2015 +0100
@@ -37,22 +37,13 @@
 
 public abstract class LoopTransformations {
 
-    private static final int UNROLL_LIMIT = FullUnrollMaxNodes.getValue() * 2;
-
     private LoopTransformations() {
         // does not need to be instantiated
     }
 
-    public static void invert(LoopEx loop, FixedNode point) {
-        LoopFragmentInsideBefore head = loop.insideBefore(point);
-        LoopFragmentInsideBefore duplicate = head.duplicate();
-        head.disconnect();
-        head.insertBefore(loop);
-        duplicate.appendInside(loop);
-    }
-
     public static void peel(LoopEx loop) {
         loop.inside().duplicate().insertBefore(loop);
+        loop.loopBegin().setLoopFrequency(Math.max(0.0, loop.loopBegin().loopFrequency() - 1));
     }
 
     public static void fullUnroll(LoopEx loop, PhaseContext context, CanonicalizerPhase canonicalizer) {
@@ -66,7 +57,7 @@
             canonicalizer.applyIncremental(graph, context, mark);
             loopBegin.removeDeadPhis();
             loop.invalidateFragments();
-            if (iterations++ > UNROLL_LIMIT || graph.getNodeCount() > MaximumDesiredSize.getValue() * 3) {
+            if (iterations++ > LoopPolicies.FullUnrollMaxIterations.getValue() || graph.getNodeCount() > MaximumDesiredSize.getValue() * 3) {
                 throw new BailoutException("FullUnroll : Graph seems to grow out of proportion");
             }
         }
@@ -121,27 +112,6 @@
         // TODO (gd) probabilities need some amount of fixup.. (probably also in other transforms)
     }
 
-    public static void unroll(LoopEx loop, int factor) {
-        assert loop.isCounted();
-        if (factor > 0) {
-            throw new UnsupportedOperationException();
-        }
-        // TODO (gd) implement counted loop
-        LoopFragmentWhole main = loop.whole();
-        LoopFragmentWhole prologue = main.duplicate();
-        prologue.insertBefore(loop);
-        // CountedLoopBeginNode counted = prologue.countedLoop();
-        // StructuredGraph graph = (StructuredGraph) counted.graph();
-        // ValueNode tripCountPrologue = counted.tripCount();
-        // ValueNode tripCountMain = counted.tripCount();
-        // graph.replaceFloating(tripCountPrologue, "tripCountPrologue % factor");
-        // graph.replaceFloating(tripCountMain, "tripCountMain - (tripCountPrologue % factor)");
-        LoopFragmentInside inside = loop.inside();
-        for (int i = 0; i < factor; i++) {
-            inside.duplicate().appendInside(loop);
-        }
-    }
-
     public static List<ControlSplitNode> findUnswitchable(LoopEx loop) {
         List<ControlSplitNode> controls = null;
         ValueNode invariantValue = null;
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopUnswitchingPhase.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopUnswitchingPhase.java	Wed Feb 11 16:08:50 2015 +0100
@@ -34,6 +34,7 @@
 
     private static final DebugMetric UNSWITCHED = Debug.metric("Unswitched");
     private static final DebugMetric UNSWITCH_CANDIDATES = Debug.metric("UnswitchCandidates");
+    private static final DebugMetric UNSWITCH_EARLY_REJECTS = Debug.metric("UnswitchEarlyRejects");
 
     @Override
     protected void run(StructuredGraph graph) {
@@ -57,6 +58,8 @@
                                 break;
                             }
                         }
+                    } else {
+                        UNSWITCH_EARLY_REJECTS.increment();
                     }
                 }
             } while (unswitched);
--- a/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/IntegerStampTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/IntegerStampTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.nodes.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
 import static org.junit.Assert.*;
 
 import org.junit.*;
@@ -45,7 +46,7 @@
 
     @Before
     public void before() {
-        graph = new StructuredGraph();
+        graph = new StructuredGraph(ALLOW_OPTIMISTIC_ASSUMPTIONS);
     }
 
     @Test
--- a/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/LoopPhiCanonicalizerTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/LoopPhiCanonicalizerTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.nodes.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
+
 import org.junit.*;
 
 import com.oracle.graal.compiler.test.*;
@@ -56,10 +58,10 @@
 
     @Test
     public void test() {
-        StructuredGraph graph = parseEager("loopSnippet");
+        StructuredGraph graph = parseEager("loopSnippet", ALLOW_OPTIMISTIC_ASSUMPTIONS);
         NodePredicate loopPhis = node -> node instanceof PhiNode && ((PhiNode) node).merge() instanceof LoopBeginNode;
 
-        PhaseContext context = new PhaseContext(getProviders(), null);
+        PhaseContext context = new PhaseContext(getProviders());
         Assert.assertEquals(5, graph.getNodes().filter(loopPhis).count());
         new CanonicalizerPhase(false).apply(graph, context);
         Assert.assertEquals(2, graph.getNodes().filter(loopPhis).count());
--- a/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/NegateNodeCanonicalizationTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/NegateNodeCanonicalizationTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.nodes.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
 import static org.junit.Assert.*;
 
 import org.junit.*;
@@ -39,7 +40,7 @@
 
     @Before
     public void before() {
-        graph = new StructuredGraph();
+        graph = new StructuredGraph(ALLOW_OPTIMISTIC_ASSUMPTIONS);
     }
 
     @Test
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java	Wed Feb 11 16:08:50 2015 +0100
@@ -52,9 +52,7 @@
     }
 
     public PiNode(ValueNode object, Stamp stamp) {
-        super(stamp);
-        this.piStamp = stamp;
-        this.object = object;
+        this(object, stamp, null);
     }
 
     public PiNode(ValueNode object, Stamp stamp, ValueNode anchor) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java	Wed Feb 11 16:08:50 2015 +0100
@@ -25,6 +25,8 @@
 import java.util.*;
 import java.util.concurrent.atomic.*;
 
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.Assumptions.OptimisticAssumption;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.*;
@@ -94,35 +96,55 @@
     private boolean hasValueProxies = true;
 
     /**
+     * The assumptions made while constructing and transforming this graph.
+     */
+    private final Assumptions assumptions;
+
+    /**
      * Creates a new Graph containing a single {@link AbstractBeginNode} as the {@link #start()
      * start} node.
+     *
+     * @param allowOptimisticAssumptions specifies whether {@link OptimisticAssumption}s can be made
+     *            while processing the graph
      */
-    public StructuredGraph() {
-        this(null, null);
+    public StructuredGraph(boolean allowOptimisticAssumptions) {
+        this(null, null, allowOptimisticAssumptions);
     }
 
     /**
      * Creates a new Graph containing a single {@link AbstractBeginNode} as the {@link #start()
      * start} node.
+     *
+     * @param allowOptimisticAssumptions specifies whether {@link OptimisticAssumption}s can be made
+     *            while processing the graph
      */
-    public StructuredGraph(String name, ResolvedJavaMethod method) {
-        this(name, method, uniqueGraphIds.incrementAndGet(), INVOCATION_ENTRY_BCI);
+    public StructuredGraph(String name, ResolvedJavaMethod method, boolean allowOptimisticAssumptions) {
+        this(name, method, uniqueGraphIds.incrementAndGet(), INVOCATION_ENTRY_BCI, null, allowOptimisticAssumptions);
     }
 
-    public StructuredGraph(ResolvedJavaMethod method) {
-        this(null, method, uniqueGraphIds.incrementAndGet(), INVOCATION_ENTRY_BCI);
+    /**
+     * @param allowOptimisticAssumptions specifies whether {@link OptimisticAssumption}s can be made
+     *            while processing the graph
+     */
+    public StructuredGraph(ResolvedJavaMethod method, boolean allowOptimisticAssumptions) {
+        this(null, method, uniqueGraphIds.incrementAndGet(), INVOCATION_ENTRY_BCI, null, allowOptimisticAssumptions);
     }
 
-    public StructuredGraph(ResolvedJavaMethod method, int entryBCI) {
-        this(null, method, uniqueGraphIds.incrementAndGet(), entryBCI);
+    /**
+     * @param allowOptimisticAssumptions specifies whether {@link OptimisticAssumption}s can be made
+     *            while processing the graph
+     */
+    public StructuredGraph(ResolvedJavaMethod method, int entryBCI, boolean allowOptimisticAssumptions) {
+        this(null, method, uniqueGraphIds.incrementAndGet(), entryBCI, null, allowOptimisticAssumptions);
     }
 
-    private StructuredGraph(String name, ResolvedJavaMethod method, long graphId, int entryBCI) {
+    private StructuredGraph(String name, ResolvedJavaMethod method, long graphId, int entryBCI, Assumptions assumptions, boolean allowOptimisticAssumptions) {
         super(name);
         this.setStart(add(new StartNode()));
         this.method = method;
         this.graphId = graphId;
         this.entryBCI = entryBCI;
+        this.assumptions = assumptions == null ? new Assumptions(allowOptimisticAssumptions) : assumptions;
     }
 
     public Stamp getReturnStamp() {
@@ -196,7 +218,9 @@
     }
 
     public StructuredGraph copy(String newName, ResolvedJavaMethod newMethod) {
-        StructuredGraph copy = new StructuredGraph(newName, newMethod, graphId, entryBCI);
+        final boolean ignored = true;
+        StructuredGraph copy = new StructuredGraph(newName, newMethod, graphId, entryBCI, assumptions, ignored);
+        assert copy.assumptions.equals(assumptions);
         copy.setGuardsStage(getGuardsStage());
         copy.isAfterFloatingReadPhase = isAfterFloatingReadPhase;
         copy.hasValueProxies = hasValueProxies;
@@ -467,4 +491,8 @@
         assert !state : "cannot 'unapply' value proxy removal on graph";
         hasValueProxies = state;
     }
+
+    public Assumptions getAssumptions() {
+        return assumptions;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java	Wed Feb 11 16:08:50 2015 +0100
@@ -165,32 +165,32 @@
         return null;
     }
 
-    public static CompareNode createCompareNode(StructuredGraph graph, Condition condition, ValueNode x, ValueNode y) {
-        return graph.unique(createCompareNode(condition, x, y));
+    public static LogicNode createCompareNode(StructuredGraph graph, Condition condition, ValueNode x, ValueNode y, ConstantReflectionProvider constantReflection) {
+        return graph.unique(createCompareNode(condition, x, y, constantReflection));
     }
 
-    public static CompareNode createCompareNode(Condition condition, ValueNode x, ValueNode y) {
+    public static LogicNode createCompareNode(Condition condition, ValueNode x, ValueNode y, ConstantReflectionProvider constantReflection) {
         assert x.getKind() == y.getKind();
         assert condition.isCanonical() : "condition is not canonical: " + condition;
         assert !x.getKind().isNumericFloat();
 
-        CompareNode comparison;
+        LogicNode comparison;
         if (condition == Condition.EQ) {
             if (x.stamp() instanceof AbstractObjectStamp) {
-                comparison = new ObjectEqualsNode(x, y);
+                comparison = ObjectEqualsNode.create(x, y, constantReflection);
             } else if (x.stamp() instanceof AbstractPointerStamp) {
                 comparison = new PointerEqualsNode(x, y);
             } else {
                 assert x.getKind().isNumericInteger();
-                comparison = new IntegerEqualsNode(x, y);
+                comparison = IntegerEqualsNode.create(x, y, constantReflection);
             }
         } else if (condition == Condition.LT) {
             assert x.getKind().isNumericInteger();
-            comparison = new IntegerLessThanNode(x, y);
+            comparison = IntegerLessThanNode.create(x, y, constantReflection);
         } else {
             assert condition == Condition.BT;
             assert x.getKind().isNumericInteger();
-            comparison = new IntegerBelowNode(x, y);
+            comparison = IntegerBelowNode.create(x, y, constantReflection);
         }
 
         return comparison;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java	Wed Feb 11 16:08:50 2015 +0100
@@ -120,7 +120,7 @@
     }
 
     public ConditionalNode(@InjectedNodeParameter StructuredGraph graph, Condition condition, ValueNode x, ValueNode y) {
-        this(createCompareNode(graph, condition, x, y));
+        this(createCompareNode(graph, condition, x, y, null));
     }
 
     public ConditionalNode(ValueNode type, ValueNode object) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowNode.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowNode.java	Wed Feb 11 16:08:50 2015 +0100
@@ -64,7 +64,7 @@
         }
         if (forX.isConstant() && forX.asJavaConstant().asLong() == 0) {
             // 0 |<| y is the same as 0 != y
-            return new LogicNegationNode(CompareNode.createCompareNode(Condition.EQ, forX, forY));
+            return new LogicNegationNode(CompareNode.createCompareNode(Condition.EQ, forX, forY, tool.getConstantReflection()));
         }
         return this;
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/SubNode.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/SubNode.java	Wed Feb 11 16:08:50 2015 +0100
@@ -25,7 +25,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.compiler.common.type.ArithmeticOpTable.BinaryOp;
-import com.oracle.graal.compiler.common.type.ArithmeticOpTable.BinaryOp.Sub;
+import com.oracle.graal.compiler.common.type.ArithmeticOpTable.BinaryOp.*;
 import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.lir.gen.*;
 import com.oracle.graal.nodeinfo.*;
@@ -40,6 +40,17 @@
         super(ArithmeticOpTable::getSub, x, y);
     }
 
+    public static ValueNode create(ValueNode x, ValueNode y) {
+        BinaryOp<Sub> op = ArithmeticOpTable.forStamp(x.stamp()).getSub();
+        Stamp stamp = op.foldStamp(x.stamp(), y.stamp());
+        ConstantNode tryConstantFold = tryConstantFold(op, x, y, stamp);
+        if (tryConstantFold != null) {
+            return tryConstantFold;
+        } else {
+            return new SubNode(x, y);
+        }
+    }
+
     @SuppressWarnings("hiding")
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java	Wed Feb 11 16:08:50 2015 +0100
@@ -275,7 +275,7 @@
                         if (sux.loop != loop) {
                             AbstractBeginNode begin = sux.getBeginNode();
                             if (!(begin instanceof LoopExitNode && ((LoopExitNode) begin).loopBegin() == loopBegin)) {
-                                Debug.log("Unexpected loop exit with %s, including whole branch in the loop", sux);
+                                Debug.log(3, "Unexpected loop exit with %s, including whole branch in the loop", sux);
                                 unexpected.add(sux);
                             }
                         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java	Wed Feb 11 16:08:50 2015 +0100
@@ -73,10 +73,10 @@
             ResolvedJavaType exactType;
             if (objectStamp.isExactType()) {
                 exactType = objectStamp.type();
-            } else if (objectStamp.type() != null && tool.assumptions().useOptimisticAssumptions()) {
+            } else if (objectStamp.type() != null && graph().getAssumptions().useOptimisticAssumptions()) {
                 exactType = objectStamp.type().findUniqueConcreteSubtype();
                 if (exactType != null) {
-                    tool.assumptions().recordConcreteSubtype(objectStamp.type(), exactType);
+                    graph().getAssumptions().recordConcreteSubtype(objectStamp.type(), exactType);
                 }
             } else {
                 exactType = null;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadMethodNode.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadMethodNode.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.nodes.extended;
 
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.*;
@@ -68,10 +69,11 @@
             if (StampTool.isExactType(object)) {
                 return resolveExactMethod(tool, type);
             }
-            if (type != null && tool.assumptions().useOptimisticAssumptions()) {
+            Assumptions assumptions = graph().getAssumptions();
+            if (type != null && assumptions.useOptimisticAssumptions()) {
                 ResolvedJavaMethod resolvedMethod = type.findUniqueConcreteMethod(method);
                 if (resolvedMethod != null && !type.isInterface() && method.getDeclaringClass().isAssignableFrom(type)) {
-                    tool.assumptions().recordConcreteMethod(method, type, resolvedMethod);
+                    assumptions.recordConcreteMethod(method, type, resolvedMethod);
                     return ConstantNode.forConstant(stamp(), resolvedMethod.getEncoding(), tool.getMetaAccess());
                 }
             }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java	Wed Feb 11 16:08:50 2015 +0100
@@ -31,15 +31,23 @@
 import com.oracle.graal.nodes.spi.*;
 
 @NodeInfo
-public class UnboxNode extends UnaryNode implements Virtualizable, Lowerable {
+public final class UnboxNode extends UnaryNode implements Virtualizable, Lowerable {
 
     protected final Kind boxingKind;
 
-    public UnboxNode(ValueNode value, Kind boxingKind) {
+    protected UnboxNode(ValueNode value, Kind boxingKind) {
         super(StampFactory.forKind(boxingKind.getStackKind()), value);
         this.boxingKind = boxingKind;
     }
 
+    public static ValueNode create(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, ValueNode value, Kind boxingKind) {
+        ValueNode synonym = findSynonym(metaAccess, constantReflection, value, boxingKind);
+        if (synonym != null) {
+            return synonym;
+        }
+        return new UnboxNode(value, boxingKind);
+    }
+
     public Kind getBoxingKind() {
         return boxingKind;
     }
@@ -63,11 +71,19 @@
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
+        ValueNode synonym = findSynonym(tool.getMetaAccess(), tool.getConstantReflection(), forValue, boxingKind);
+        if (synonym != null) {
+            return synonym;
+        }
+        return this;
+    }
+
+    private static ValueNode findSynonym(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, ValueNode forValue, Kind boxingKind) {
         if (forValue.isConstant()) {
             JavaConstant constant = forValue.asJavaConstant();
-            JavaConstant unboxed = tool.getConstantReflection().unboxPrimitive(constant);
+            JavaConstant unboxed = constantReflection.unboxPrimitive(constant);
             if (unboxed != null && unboxed.getKind() == boxingKind) {
-                return ConstantNode.forConstant(unboxed, tool.getMetaAccess());
+                return ConstantNode.forConstant(unboxed, metaAccess);
             }
         } else if (forValue instanceof BoxNode) {
             BoxNode box = (BoxNode) forValue;
@@ -75,7 +91,7 @@
                 return box.getValue();
             }
         }
-        return this;
+        return null;
     }
 
     @NodeIntrinsic
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java	Wed Feb 11 16:08:50 2015 +0100
@@ -52,6 +52,11 @@
     }
 
     public static ValueNode create(ValueNode forValue, ConstantReflectionProvider constantReflection) {
+        if (forValue instanceof NewArrayNode) {
+            NewArrayNode newArray = (NewArrayNode) forValue;
+            return newArray.length();
+        }
+
         ValueNode length = readArrayLengthConstant(forValue, constantReflection);
         if (length != null) {
             return length;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java	Wed Feb 11 16:08:50 2015 +0100
@@ -26,6 +26,7 @@
 import static com.oracle.graal.api.meta.DeoptimizationReason.*;
 import static com.oracle.graal.nodes.extended.BranchProbabilityNode.*;
 
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.meta.ProfilingInfo.TriState;
 import com.oracle.graal.compiler.common.type.*;
@@ -62,6 +63,14 @@
         this.forStoreCheck = forStoreCheck;
     }
 
+    public static ValueNode create(ResolvedJavaType type, ValueNode object, JavaTypeProfile profile, boolean forStoreCheck) {
+        ValueNode synonym = findSynonym(type, object);
+        if (synonym != null) {
+            return synonym;
+        }
+        return new CheckCastNode(type, object, profile, forStoreCheck);
+    }
+
     public boolean isForStoreCheck() {
         return forStoreCheck;
     }
@@ -144,22 +153,17 @@
 
     @Override
     public Node canonical(CanonicalizerTool tool) {
-        ResolvedJavaType objectType = StampTool.typeOrNull(object());
-        if (objectType != null && type.isAssignableFrom(objectType)) {
-            // we don't have to check for null types here because they will also pass the
-            // checkcast.
-            return object();
+        ValueNode synonym = findSynonym(type, object());
+        if (synonym != null) {
+            return synonym;
         }
 
-        if (StampTool.isPointerAlwaysNull(object())) {
-            return object();
-        }
-
-        if (tool.assumptions() != null && tool.assumptions().useOptimisticAssumptions()) {
+        Assumptions assumptions = graph().getAssumptions();
+        if (assumptions.useOptimisticAssumptions()) {
             ResolvedJavaType exactType = type.findUniqueConcreteSubtype();
             if (exactType != null && !exactType.equals(type)) {
                 // Propagate more precise type information to usages of the checkcast.
-                tool.assumptions().recordConcreteSubtype(type, exactType);
+                assumptions.recordConcreteSubtype(type, exactType);
                 return new CheckCastNode(exactType, object, profile, forStoreCheck);
             }
         }
@@ -167,6 +171,20 @@
         return this;
     }
 
+    private static ValueNode findSynonym(ResolvedJavaType type, ValueNode object) {
+        ResolvedJavaType objectType = StampTool.typeOrNull(object);
+        if (objectType != null && type.isAssignableFrom(objectType)) {
+            // we don't have to check for null types here because they will also pass the
+            // checkcast.
+            return object;
+        }
+
+        if (StampTool.isPointerAlwaysNull(object)) {
+            return object;
+        }
+        return null;
+    }
+
     @Override
     public void simplify(SimplifierTool tool) {
         // if the previous node is also a checkcast, with a less precise and compatible type,
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.nodes.java;
 
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.spi.*;
@@ -46,6 +47,16 @@
         assert type != null;
     }
 
+    public static LogicNode create(ResolvedJavaType type, ValueNode object, JavaTypeProfile profile) {
+        ObjectStamp objectStamp = (ObjectStamp) object.stamp();
+        LogicNode constantValue = findSynonym(type, objectStamp.type(), objectStamp.nonNull(), objectStamp.isExactType());
+        if (constantValue != null) {
+            return constantValue;
+        } else {
+            return new InstanceOfNode(type, object, profile);
+        }
+    }
+
     @Override
     public void lower(LoweringTool tool) {
         tool.getLowerer().lower(this, tool);
@@ -67,12 +78,13 @@
             if (result != null) {
                 return result;
             }
-            if (tool.assumptions() != null && tool.assumptions().useOptimisticAssumptions()) {
+            Assumptions assumptions = graph().getAssumptions();
+            if (assumptions.useOptimisticAssumptions()) {
                 ResolvedJavaType exact = stampType.findUniqueConcreteSubtype();
                 if (exact != null) {
                     result = checkInstanceOf(forValue, exact, objectStamp.nonNull(), true);
                     if (result != null) {
-                        tool.assumptions().recordConcreteSubtype(stampType, exact);
+                        assumptions.recordConcreteSubtype(stampType, exact);
                         return result;
                     }
                 }
@@ -82,7 +94,25 @@
     }
 
     private ValueNode checkInstanceOf(ValueNode forValue, ResolvedJavaType inputType, boolean nonNull, boolean exactType) {
-        boolean subType = type().isAssignableFrom(inputType);
+        ValueNode result = findSynonym(type(), inputType, nonNull, exactType);
+        if (result != null) {
+            return result;
+        }
+        if (type().isAssignableFrom(inputType)) {
+            if (!nonNull) {
+                // the instanceof matches if the object is non-null, so return true
+                // depending on the null-ness.
+                return new LogicNegationNode(new IsNullNode(forValue));
+            }
+        }
+        return null;
+    }
+
+    public static LogicNode findSynonym(ResolvedJavaType type, ResolvedJavaType inputType, boolean nonNull, boolean exactType) {
+        if (inputType == null) {
+            return null;
+        }
+        boolean subType = type.isAssignableFrom(inputType);
         if (subType) {
             if (nonNull) {
                 // the instanceOf matches, so return true
@@ -95,21 +125,14 @@
                 // also make the check fail.
                 return LogicConstantNode.contradiction();
             } else {
-                boolean superType = inputType.isAssignableFrom(type());
-                if (!superType && !inputType.isInterface() && !type().isInterface()) {
+                boolean superType = inputType.isAssignableFrom(type);
+                if (!superType && !inputType.isInterface() && !type.isInterface()) {
                     return LogicConstantNode.contradiction();
                 }
                 // since the subtype comparison was only performed on a declared type we don't
                 // really know if it might be true at run time...
             }
         }
-        if (type().isAssignableFrom(inputType)) {
-            if (!nonNull) {
-                // the instanceof matches if the object is non-null, so return true
-                // depending on the null-ness.
-                return new LogicNegationNode(new IsNullNode(forValue));
-            }
-        }
         return null;
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java	Wed Feb 11 16:08:50 2015 +0100
@@ -94,7 +94,11 @@
         }
     }
 
-    public static ResolvedJavaMethod findSpecialCallTarget(InvokeKind invokeKind, ValueNode receiver, ResolvedJavaMethod targetMethod, Assumptions assumptions, ResolvedJavaType contextType) {
+    public static ResolvedJavaMethod findSpecialCallTarget(InvokeKind invokeKind, ValueNode receiver, ResolvedJavaMethod targetMethod, ResolvedJavaType contextType) {
+        if (targetMethod.getName().equals("getProperties") && receiver.graph().method().getDeclaringClass().getName().equals("Ljava/lang/Character;")) {
+            System.console();
+        }
+
         if (invokeKind.isDirect()) {
             return null;
         }
@@ -119,7 +123,8 @@
             if (resolvedMethod != null && (resolvedMethod.canBeStaticallyBound() || StampTool.isExactType(receiver) || type.isArray())) {
                 return resolvedMethod;
             }
-            if (assumptions != null && assumptions.useOptimisticAssumptions()) {
+            Assumptions assumptions = receiver.graph().getAssumptions();
+            if (assumptions.useOptimisticAssumptions()) {
                 ResolvedJavaType uniqueConcreteType = type.findUniqueConcreteSubtype();
                 if (uniqueConcreteType != null) {
                     ResolvedJavaMethod methodFromUniqueType = uniqueConcreteType.resolveConcreteMethod(targetMethod, contextType);
@@ -144,7 +149,7 @@
     public void simplify(SimplifierTool tool) {
         // attempt to devirtualize the call
         ResolvedJavaType contextType = (invoke().stateAfter() == null && invoke().stateDuring() == null) ? null : invoke().getContextType();
-        ResolvedJavaMethod specialCallTarget = findSpecialCallTarget(invokeKind, receiver(), targetMethod, tool.assumptions(), contextType);
+        ResolvedJavaMethod specialCallTarget = findSpecialCallTarget(invokeKind, receiver(), targetMethod, contextType);
         if (specialCallTarget != null) {
             this.setTargetMethod(specialCallTarget);
             setInvokeKind(InvokeKind.Special);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java	Wed Feb 11 16:08:50 2015 +0100
@@ -80,7 +80,7 @@
         if (!(forValue.stamp() instanceof ObjectStamp)) {
             return this;
         }
-        if (!mayHaveFinalizer(forValue, tool.assumptions())) {
+        if (!mayHaveFinalizer(forValue, graph().getAssumptions())) {
             return null;
         }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringTool.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringTool.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.nodes.spi;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
@@ -43,8 +42,6 @@
 
     GuardingNode createGuard(FixedNode before, LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated);
 
-    Assumptions assumptions();
-
     /**
      * Gets the closest fixed node preceding the node currently being lowered.
      */
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Replacements.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Replacements.java	Wed Feb 11 16:08:50 2015 +0100
@@ -25,7 +25,6 @@
 import java.lang.reflect.*;
 import java.util.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.nodes.*;
@@ -83,11 +82,6 @@
     Class<? extends FixedWithNextNode> getMacroSubstitution(ResolvedJavaMethod method);
 
     /**
-     * Gets the assumptions with which replacement graphs are preprocessed.
-     */
-    Assumptions getAssumptions();
-
-    /**
      * Registers all the {@linkplain MethodSubstitution method} and {@linkplain MacroSubstitution
      * macro} substitutions defined by a given class.
      *
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/VirtualizerTool.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/VirtualizerTool.java	Wed Feb 11 16:08:50 2015 +0100
@@ -24,7 +24,6 @@
 
 import java.util.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
@@ -35,7 +34,7 @@
 /**
  * This tool can be used to query the current state (normal/virtualized/re-materialized) of values
  * and to describe the actions that would be taken for this state.
- * 
+ *
  * See also {@link Virtualizable}.
  */
 public interface VirtualizerTool {
@@ -52,15 +51,9 @@
     ConstantReflectionProvider getConstantReflectionProvider();
 
     /**
-     * @return the {@link Assumptions} associated with the current compilation, which can be used to
-     *         make type assumptions during virtualization.
-     */
-    Assumptions getAssumptions();
-
-    /**
      * This method should be used to query the maximum size of virtualized objects before attempting
      * virtualization.
-     * 
+     *
      * @return the maximum number of entries for virtualized objects.
      */
     int getMaximumEntryCount();
@@ -69,7 +62,7 @@
 
     /**
      * Introduces a new virtual object to the current state.
-     * 
+     *
      * @param virtualObject the new virtual object.
      * @param entryState the initial state of the virtual object's fields.
      * @param locks the initial locking depths.
@@ -79,7 +72,7 @@
     /**
      * Queries the current state of the given value: if it is virtualized (thread-local and the
      * compiler knows all entries) or not.
-     * 
+     *
      * @param value the value whose state should be queried.
      * @return the {@link State} representing the value if it has been virtualized at some point,
      *         null otherwise.
@@ -88,7 +81,7 @@
 
     /**
      * Sets the entry (field or array element) with the given index in the virtualized object.
-     * 
+     *
      * @param state the state.
      * @param index the index to be set.
      * @param value the new value for the given index.
@@ -102,7 +95,7 @@
      * Replacements via {@link #replaceWithValue(ValueNode)} are not immediately committed. This
      * method can be used to determine if a value was replaced by another one (e.g., a load field by
      * the loaded value).
-     * 
+     *
      * @param original the original input value.
      * @return the replacement value, or the original value if there is no replacement.
      */
@@ -112,14 +105,14 @@
 
     /**
      * Deletes the current node and replaces it with the given virtualized object.
-     * 
+     *
      * @param virtual the virtualized object that should replace the current node.
      */
     void replaceWithVirtual(VirtualObjectNode virtual);
 
     /**
      * Deletes the current node and replaces it with the given value.
-     * 
+     *
      * @param replacement the value that should replace the current node.
      */
     void replaceWithValue(ValueNode replacement);
@@ -131,7 +124,7 @@
 
     /**
      * Replaces an input of the current node.
-     * 
+     *
      * @param oldInput the old input value.
      * @param replacement the new input value.
      */
@@ -140,7 +133,7 @@
     /**
      * Adds the given node to the graph.This action will only be performed when, and if, the changes
      * are committed.
-     * 
+     *
      * @param node the node to add.
      */
     void addNode(ValueNode node);
@@ -148,7 +141,7 @@
     /**
      * This method performs either {@link #replaceWithValue(ValueNode)} or
      * {@link #replaceWithVirtual(VirtualObjectNode)}, depending on the given value.
-     * 
+     *
      * @param value the replacement value
      */
     void replaceWith(ValueNode value);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java	Wed Feb 11 16:08:50 2015 +0100
@@ -24,7 +24,6 @@
 
 import java.util.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.iterators.*;
@@ -473,22 +472,16 @@
     }
 
     private static final class DefaultSimplifierTool implements SimplifierTool {
-        private final Assumptions assumptions;
         private final MetaAccessProvider metaAccess;
         private final ConstantReflectionProvider constantReflection;
         private final boolean canonicalizeReads;
 
-        public DefaultSimplifierTool(Assumptions assumptions, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, boolean canonicalizeReads) {
-            this.assumptions = assumptions;
+        public DefaultSimplifierTool(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, boolean canonicalizeReads) {
             this.metaAccess = metaAccess;
             this.constantReflection = constantReflection;
             this.canonicalizeReads = canonicalizeReads;
         }
 
-        public Assumptions assumptions() {
-            return assumptions;
-        }
-
         public MetaAccessProvider getMetaAccess() {
             return metaAccess;
         }
@@ -517,7 +510,7 @@
         }
     }
 
-    public static SimplifierTool getDefaultSimplifier(Assumptions assumptions, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, boolean canonicalizeReads) {
-        return new DefaultSimplifierTool(assumptions, metaAccess, constantReflection, canonicalizeReads);
+    public static SimplifierTool getDefaultSimplifier(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, boolean canonicalizeReads) {
+        return new DefaultSimplifierTool(metaAccess, constantReflection, canonicalizeReads);
     }
 }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,12 +22,13 @@
  */
 package com.oracle.graal.phases.common;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.graph.*;
-import com.oracle.graal.graph.Graph.*;
+import com.oracle.graal.graph.Graph.Mark;
+import com.oracle.graal.graph.Graph.NodeEventListener;
+import com.oracle.graal.graph.Graph.NodeEventScope;
 import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodeinfo.*;
 import com.oracle.graal.nodes.*;
@@ -394,15 +395,6 @@
                 GraphUtil.killCFG(branch, this);
             }
 
-            /**
-             * @return an object that can be used for recording assumptions or {@code null} if
-             *         assumptions are not allowed in the current context.
-             */
-            @Override
-            public Assumptions assumptions() {
-                return context.getAssumptions();
-            }
-
             @Override
             public MetaAccessProvider getMetaAccess() {
                 return context.getMetaAccess();
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java	Wed Feb 11 16:08:50 2015 +0100
@@ -49,7 +49,7 @@
  *
  */
 public class ConvertDeoptimizeToGuardPhase extends Phase {
-    private SimplifierTool simplifierTool = GraphUtil.getDefaultSimplifier(null, null, null, false);
+    private SimplifierTool simplifierTool = GraphUtil.getDefaultSimplifier(null, null, false);
 
     private static AbstractBeginNode findBeginNode(FixedNode startNode) {
         return GraphUtil.predecessorIterable(startNode).filter(AbstractBeginNode.class).first();
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java	Wed Feb 11 16:08:50 2015 +0100
@@ -26,7 +26,6 @@
 
 import java.util.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.Graph.Mark;
@@ -120,11 +119,6 @@
             return createGuard(before, condition, deoptReason, action, false);
         }
 
-        @Override
-        public Assumptions assumptions() {
-            return context.getAssumptions();
-        }
-
         public StampProvider getStampProvider() {
             return context.getStampProvider();
         }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningPhase.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningPhase.java	Wed Feb 11 16:08:50 2015 +0100
@@ -27,9 +27,8 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.options.*;
 import com.oracle.graal.phases.common.*;
-import com.oracle.graal.phases.common.inlining.policy.GreedyInliningPolicy;
-import com.oracle.graal.phases.common.inlining.policy.InliningPolicy;
-import com.oracle.graal.phases.common.inlining.walker.InliningData;
+import com.oracle.graal.phases.common.inlining.policy.*;
+import com.oracle.graal.phases.common.inlining.walker.*;
 import com.oracle.graal.phases.tiers.*;
 
 public class InliningPhase extends AbstractInliningPhase {
@@ -93,5 +92,4 @@
         assert data.inliningDepth() == 0;
         assert data.graphCount() == 0;
     }
-
 }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java	Wed Feb 11 16:08:50 2015 +0100
@@ -114,7 +114,15 @@
 
     public static void logNotInlinedMethod(Invoke invoke, String msg) {
         if (shouldLogInliningDecision()) {
-            String methodString = invoke.toString() + (invoke.callTarget() == null ? " callTarget=null" : invoke.callTarget().targetName());
+            String methodString = invoke.toString();
+            if (invoke.callTarget() == null) {
+                methodString += " callTarget=null";
+            } else {
+                String targetName = invoke.callTarget().targetName();
+                if (!methodString.endsWith(targetName)) {
+                    methodString += " " + targetName;
+                }
+            }
             logInliningDecision(methodString, false, msg, new Object[0]);
         }
     }
@@ -355,6 +363,9 @@
         invokeNode.replaceAtUsages(null);
         GraphUtil.killCFG(invokeNode);
 
+        // Copy assumptions from inlinee to caller
+        graph.getAssumptions().record(inlineGraph.getAssumptions());
+
         return duplicates;
     }
 
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/AbstractInlineInfo.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/AbstractInlineInfo.java	Wed Feb 11 16:08:50 2015 +0100
@@ -24,7 +24,6 @@
 
 import java.util.*;
 
-import com.oracle.graal.api.code.Assumptions;
 import com.oracle.graal.api.meta.ResolvedJavaMethod;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
@@ -53,7 +52,7 @@
         return invoke;
     }
 
-    protected static Collection<Node> inline(Invoke invoke, ResolvedJavaMethod concrete, Inlineable inlineable, Assumptions assumptions, boolean receiverNullCheck) {
+    protected static Collection<Node> inline(Invoke invoke, ResolvedJavaMethod concrete, Inlineable inlineable, boolean receiverNullCheck) {
         List<Node> canonicalizeNodes = new ArrayList<>();
         if (inlineable instanceof InlineableGraph) {
             StructuredGraph calleeGraph = ((InlineableGraph) inlineable).getGraph();
@@ -68,7 +67,7 @@
         }
 
         InliningUtil.InlinedBytecodes.add(concrete.getCodeSize());
-        assumptions.recordMethodContents(concrete);
+        invoke.asNode().graph().getAssumptions().recordMethodContents(concrete);
         return canonicalizeNodes;
     }
 
@@ -83,9 +82,9 @@
         }
     }
 
-    public final void populateInlinableElements(HighTierContext context, Assumptions calleeAssumptions, CanonicalizerPhase canonicalizer) {
+    public final void populateInlinableElements(HighTierContext context, StructuredGraph caller, CanonicalizerPhase canonicalizer) {
         for (int i = 0; i < numberOfMethods(); i++) {
-            Inlineable elem = Inlineable.getInlineableElement(methodAt(i), invoke, context.replaceAssumptions(calleeAssumptions), canonicalizer);
+            Inlineable elem = Inlineable.getInlineableElement(methodAt(i), invoke, context, canonicalizer);
             setInlinableElement(i, elem);
         }
     }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/AssumptionInlineInfo.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/AssumptionInlineInfo.java	Wed Feb 11 16:08:50 2015 +0100
@@ -24,7 +24,6 @@
 
 import java.util.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.code.Assumptions.Assumption;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
@@ -47,14 +46,14 @@
     }
 
     @Override
-    public Collection<Node> inline(Providers providers, Assumptions assumptions) {
-        assumptions.record(takenAssumption);
-        return super.inline(providers, assumptions);
+    public Collection<Node> inline(Providers providers) {
+        invoke.asNode().graph().getAssumptions().record(takenAssumption);
+        return super.inline(providers);
     }
 
     @Override
-    public void tryToDevirtualizeInvoke(Providers providers, Assumptions assumptions) {
-        assumptions.record(takenAssumption);
+    public void tryToDevirtualizeInvoke(Providers providers) {
+        invoke.asNode().graph().getAssumptions().record(takenAssumption);
         InliningUtil.replaceInvokeCallTarget(invoke, graph(), InvokeKind.Special, concrete);
     }
 
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/ExactInlineInfo.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/ExactInlineInfo.java	Wed Feb 11 16:08:50 2015 +0100
@@ -24,7 +24,6 @@
 
 import java.util.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
@@ -52,12 +51,12 @@
     }
 
     @Override
-    public Collection<Node> inline(Providers providers, Assumptions assumptions) {
-        return inline(invoke, concrete, inlineableElement, assumptions, !suppressNullCheck);
+    public Collection<Node> inline(Providers providers) {
+        return inline(invoke, concrete, inlineableElement, !suppressNullCheck);
     }
 
     @Override
-    public void tryToDevirtualizeInvoke(Providers providers, Assumptions assumptions) {
+    public void tryToDevirtualizeInvoke(Providers providers) {
         // nothing todo, can already be bound statically
     }
 
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/InlineInfo.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/InlineInfo.java	Wed Feb 11 16:08:50 2015 +0100
@@ -24,7 +24,6 @@
 
 import java.util.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
@@ -74,16 +73,16 @@
      *
      * @return a collection of nodes that need to be canonicalized after the inlining
      */
-    Collection<Node> inline(Providers providers, Assumptions assumptions);
+    Collection<Node> inline(Providers providers);
 
     /**
      * Try to make the call static bindable to avoid interface and virtual method calls.
      */
-    void tryToDevirtualizeInvoke(Providers providers, Assumptions assumptions);
+    void tryToDevirtualizeInvoke(Providers providers);
 
     boolean shouldInline();
 
-    void populateInlinableElements(HighTierContext context, Assumptions calleeAssumptions, CanonicalizerPhase canonicalizer);
+    void populateInlinableElements(HighTierContext context, StructuredGraph caller, CanonicalizerPhase canonicalizer);
 
     int determineNodeCount();
 }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/MultiTypeGuardInlineInfo.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/MultiTypeGuardInlineInfo.java	Wed Feb 11 16:08:50 2015 +0100
@@ -26,7 +26,6 @@
 
 import java.util.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.meta.JavaTypeProfile.ProfiledType;
 import com.oracle.graal.compiler.common.calc.*;
@@ -142,11 +141,11 @@
     }
 
     @Override
-    public Collection<Node> inline(Providers providers, Assumptions assumptions) {
+    public Collection<Node> inline(Providers providers) {
         if (hasSingleMethod()) {
-            return inlineSingleMethod(graph(), providers.getMetaAccess(), assumptions, providers.getStampProvider());
+            return inlineSingleMethod(graph(), providers.getMetaAccess(), providers.getStampProvider());
         } else {
-            return inlineMultipleMethods(graph(), providers, assumptions);
+            return inlineMultipleMethods(graph(), providers);
         }
     }
 
@@ -167,7 +166,7 @@
         return notRecordedTypeProbability > 0;
     }
 
-    private Collection<Node> inlineMultipleMethods(StructuredGraph graph, Providers providers, Assumptions assumptions) {
+    private Collection<Node> inlineMultipleMethods(StructuredGraph graph, Providers providers) {
         int numberOfMethods = concretes.size();
         FixedNode continuation = invoke.next();
 
@@ -276,7 +275,7 @@
             if (opportunities > 0) {
                 metricInliningTailDuplication.increment();
                 Debug.log("MultiTypeGuardInlineInfo starting tail duplication (%d opportunities)", opportunities);
-                PhaseContext phaseContext = new PhaseContext(providers, assumptions);
+                PhaseContext phaseContext = new PhaseContext(providers);
                 CanonicalizerPhase canonicalizer = new CanonicalizerPhase(!ImmutableCode.getValue());
                 TailDuplicationPhase.tailDuplicate(returnMerge, TailDuplicationPhase.TRUE_DECISION, replacementNodes, phaseContext, canonicalizer);
             }
@@ -286,7 +285,7 @@
         // do the actual inlining for every invoke
         for (int i = 0; i < numberOfMethods; i++) {
             Invoke invokeForInlining = (Invoke) successors[i].next();
-            canonicalizeNodes.addAll(inline(invokeForInlining, methodAt(i), inlineableElementAt(i), assumptions, false));
+            canonicalizeNodes.addAll(inline(invokeForInlining, methodAt(i), inlineableElementAt(i), false));
         }
         if (returnValuePhi != null) {
             canonicalizeNodes.add(returnValuePhi);
@@ -327,7 +326,7 @@
         return result;
     }
 
-    private Collection<Node> inlineSingleMethod(StructuredGraph graph, MetaAccessProvider metaAccess, Assumptions assumptions, StampProvider stampProvider) {
+    private Collection<Node> inlineSingleMethod(StructuredGraph graph, MetaAccessProvider metaAccess, StampProvider stampProvider) {
         assert concretes.size() == 1 && inlineableElements.length == 1 && ptypes.size() > 1 && !shouldFallbackToInvoke() && notRecordedTypeProbability == 0;
 
         AbstractBeginNode calleeEntryNode = graph.add(new BeginNode());
@@ -338,7 +337,7 @@
 
         calleeEntryNode.setNext(invoke.asNode());
 
-        return inline(invoke, methodAt(0), inlineableElementAt(0), assumptions, false);
+        return inline(invoke, methodAt(0), inlineableElementAt(0), false);
     }
 
     private boolean createDispatchOnTypeBeforeInvoke(StructuredGraph graph, AbstractBeginNode[] successors, boolean invokeIsOnlySuccessor, MetaAccessProvider metaAccess, StampProvider stampProvider) {
@@ -376,7 +375,7 @@
             FixedNode lastSucc = successors[concretes.size()];
             for (int i = concretes.size() - 1; i >= 0; --i) {
                 LoadMethodNode method = graph.add(new LoadMethodNode(stampProvider.createMethodStamp(), concretes.get(i), receiverType, hub));
-                CompareNode methodCheck = CompareNode.createCompareNode(graph, Condition.EQ, method, constantMethods[i]);
+                LogicNode methodCheck = CompareNode.createCompareNode(graph, Condition.EQ, method, constantMethods[i], null);
                 IfNode ifNode = graph.add(new IfNode(methodCheck, successors[i], lastSucc, probability[i]));
                 method.setNext(ifNode);
                 lastSucc = method;
@@ -511,7 +510,7 @@
     }
 
     @Override
-    public void tryToDevirtualizeInvoke(Providers providers, Assumptions assumptions) {
+    public void tryToDevirtualizeInvoke(Providers providers) {
         if (hasSingleMethod()) {
             devirtualizeWithTypeSwitch(graph(), InvokeKind.Special, concretes.get(0), providers.getMetaAccess(), providers.getStampProvider());
         } else {
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/TypeGuardInlineInfo.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/TypeGuardInlineInfo.java	Wed Feb 11 16:08:50 2015 +0100
@@ -24,7 +24,6 @@
 
 import java.util.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.calc.*;
 import com.oracle.graal.graph.*;
@@ -90,13 +89,13 @@
     }
 
     @Override
-    public Collection<Node> inline(Providers providers, Assumptions assumptions) {
+    public Collection<Node> inline(Providers providers) {
         createGuard(graph(), providers);
-        return inline(invoke, concrete, inlineableElement, assumptions, false);
+        return inline(invoke, concrete, inlineableElement, false);
     }
 
     @Override
-    public void tryToDevirtualizeInvoke(Providers providers, Assumptions assumptions) {
+    public void tryToDevirtualizeInvoke(Providers providers) {
         createGuard(graph(), providers);
         InliningUtil.replaceInvokeCallTarget(invoke, graph(), InvokeKind.Special, concrete);
     }
@@ -106,7 +105,7 @@
         LoadHubNode receiverHub = graph.unique(new LoadHubNode(providers.getStampProvider(), nonNullReceiver));
         ConstantNode typeHub = ConstantNode.forConstant(receiverHub.stamp(), type.getObjectHub(), providers.getMetaAccess(), graph);
 
-        CompareNode typeCheck = CompareNode.createCompareNode(graph, Condition.EQ, receiverHub, typeHub);
+        LogicNode typeCheck = CompareNode.createCompareNode(graph, Condition.EQ, receiverHub, typeHub, providers.getConstantReflection());
         FixedGuardNode guard = graph.add(new FixedGuardNode(typeCheck, DeoptimizationReason.TypeCheckedInliningViolated, DeoptimizationAction.InvalidateReprofile));
         assert invoke.predecessor() != null;
 
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/elem/InlineableGraph.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/elem/InlineableGraph.java	Wed Feb 11 16:08:50 2015 +0100
@@ -58,7 +58,7 @@
     private FixedNodeProbabilityCache probabilites = new FixedNodeProbabilityCache();
 
     public InlineableGraph(final ResolvedJavaMethod method, final Invoke invoke, final HighTierContext context, CanonicalizerPhase canonicalizer) {
-        StructuredGraph original = getOriginalGraph(method, context, canonicalizer);
+        StructuredGraph original = getOriginalGraph(method, context, canonicalizer, invoke.asNode().graph());
         // TODO copying the graph is only necessary if it is modified or if it contains any invokes
         this.graph = original.copy();
         specializeGraphToArguments(invoke, context, canonicalizer);
@@ -69,7 +69,7 @@
      * The graph thus obtained is returned, ie the caller is responsible for cloning before
      * modification.
      */
-    private static StructuredGraph getOriginalGraph(final ResolvedJavaMethod method, final HighTierContext context, CanonicalizerPhase canonicalizer) {
+    private static StructuredGraph getOriginalGraph(final ResolvedJavaMethod method, final HighTierContext context, CanonicalizerPhase canonicalizer, StructuredGraph caller) {
         StructuredGraph result = InliningUtil.getIntrinsicGraph(context.getReplacements(), method);
         if (result != null) {
             return result;
@@ -78,7 +78,7 @@
         if (result != null) {
             return result;
         }
-        return parseBytecodes(method, context, canonicalizer);
+        return parseBytecodes(method, context, canonicalizer, caller);
     }
 
     /**
@@ -184,6 +184,8 @@
         if (context.getGraphCache() != null) {
             StructuredGraph cachedGraph = context.getGraphCache().get(method);
             if (cachedGraph != null) {
+                // TODO: check that cachedGraph.getAssumptions() are still valid
+                // instead of waiting for code installation to do it.
                 return cachedGraph;
             }
         }
@@ -195,8 +197,8 @@
      * Provided profiling info is mature, the resulting graph is cached. The caller is responsible
      * for cloning before modification.</p>
      */
-    private static StructuredGraph parseBytecodes(ResolvedJavaMethod method, HighTierContext context, CanonicalizerPhase canonicalizer) {
-        StructuredGraph newGraph = new StructuredGraph(method);
+    private static StructuredGraph parseBytecodes(ResolvedJavaMethod method, HighTierContext context, CanonicalizerPhase canonicalizer, StructuredGraph caller) {
+        StructuredGraph newGraph = new StructuredGraph(method, caller.getAssumptions().useOptimisticAssumptions());
         try (Debug.Scope s = Debug.scope("InlineGraph", newGraph)) {
             if (context.getGraphBuilderSuite() != null) {
                 context.getGraphBuilderSuite().apply(newGraph, context);
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/InliningData.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/InliningData.java	Wed Feb 11 16:08:50 2015 +0100
@@ -100,8 +100,7 @@
         this.inliningPolicy = inliningPolicy;
         this.maxGraphs = 1;
 
-        Assumptions rootAssumptions = context.getAssumptions();
-        invocationQueue.push(new MethodInvocation(null, rootAssumptions, 1.0, 1.0, null));
+        invocationQueue.push(new MethodInvocation(null, 1.0, 1.0, null));
         graphQueue.push(new CallsiteHolderExplorable(rootGraph, 1.0, 1.0, null));
     }
 
@@ -145,7 +144,7 @@
      * @param invoke the invoke that should be inlined
      * @return an instance of InlineInfo, or null if no inlining is possible at the given invoke
      */
-    private InlineInfo getInlineInfo(Invoke invoke, Assumptions assumptions) {
+    private InlineInfo getInlineInfo(Invoke invoke) {
         final String failureMessage = InliningUtil.checkInvokeConditions(invoke);
         if (failureMessage != null) {
             InliningUtil.logNotInlinedMethod(invoke, failureMessage);
@@ -194,7 +193,7 @@
             }
         }
 
-        if (assumptions.useOptimisticAssumptions()) {
+        if (callTarget.graph().getAssumptions().useOptimisticAssumptions()) {
             ResolvedJavaType uniqueSubtype = holder.findUniqueConcreteSubtype();
             if (uniqueSubtype != null) {
                 ResolvedJavaMethod resolvedMethod = uniqueSubtype.resolveConcreteMethod(targetMethod, contextType);
@@ -354,16 +353,15 @@
         return null;
     }
 
-    private void doInline(CallsiteHolderExplorable callerCallsiteHolder, MethodInvocation calleeInvocation, Assumptions callerAssumptions) {
+    private void doInline(CallsiteHolderExplorable callerCallsiteHolder, MethodInvocation calleeInvocation) {
         StructuredGraph callerGraph = callerCallsiteHolder.graph();
         InlineInfo calleeInfo = calleeInvocation.callee();
         try {
             try (Debug.Scope scope = Debug.scope("doInline", callerGraph)) {
                 Set<Node> canonicalizedNodes = Node.newSet();
                 calleeInfo.invoke().asNode().usages().snapshotTo(canonicalizedNodes);
-                Collection<Node> parameterUsages = calleeInfo.inline(new Providers(context), callerAssumptions);
+                Collection<Node> parameterUsages = calleeInfo.inline(new Providers(context));
                 canonicalizedNodes.addAll(parameterUsages);
-                callerAssumptions.record(calleeInvocation.assumptions());
                 metricInliningRuns.increment();
                 Debug.dump(callerGraph, "after %s", calleeInfo);
 
@@ -409,20 +407,19 @@
      *
      * @return true iff inlining was actually performed
      */
-    private boolean tryToInline(MethodInvocation calleeInvocation, MethodInvocation parentInvocation, int inliningDepth) {
+    private boolean tryToInline(MethodInvocation calleeInvocation, int inliningDepth) {
         CallsiteHolderExplorable callerCallsiteHolder = (CallsiteHolderExplorable) currentGraph();
         InlineInfo calleeInfo = calleeInvocation.callee();
         assert callerCallsiteHolder.containsInvoke(calleeInfo.invoke());
-        Assumptions callerAssumptions = parentInvocation.assumptions();
         metricInliningConsidered.increment();
 
         if (inliningPolicy.isWorthInlining(context.getReplacements(), calleeInvocation, inliningDepth, true)) {
-            doInline(callerCallsiteHolder, calleeInvocation, callerAssumptions);
+            doInline(callerCallsiteHolder, calleeInvocation);
             return true;
         }
 
         if (context.getOptimisticOptimizations().devirtualizeInvokes()) {
-            calleeInfo.tryToDevirtualizeInvoke(new Providers(context), callerAssumptions);
+            calleeInfo.tryToDevirtualizeInvoke(new Providers(context));
         }
 
         return false;
@@ -450,22 +447,19 @@
      * <p>
      * The {@link InlineInfo} used to get things rolling is kept around in the
      * {@link MethodInvocation}, it will be needed in case of inlining, see
-     * {@link InlineInfo#inline(Providers, Assumptions)}
+     * {@link InlineInfo#inline(Providers)}
      * </p>
      */
     private void processNextInvoke() {
         CallsiteHolderExplorable callsiteHolder = (CallsiteHolderExplorable) currentGraph();
         Invoke invoke = callsiteHolder.popInvoke();
-        MethodInvocation callerInvocation = currentInvocation();
-        Assumptions parentAssumptions = callerInvocation.assumptions();
-        InlineInfo info = getInlineInfo(invoke, parentAssumptions);
+        InlineInfo info = getInlineInfo(invoke);
 
         if (info != null) {
-            Assumptions calleeAssumptions = new Assumptions(parentAssumptions.useOptimisticAssumptions());
-            info.populateInlinableElements(context, calleeAssumptions, canonicalizer);
+            info.populateInlinableElements(context, currentGraph().graph(), canonicalizer);
             double invokeProbability = callsiteHolder.invokeProbability(invoke);
             double invokeRelevance = callsiteHolder.invokeRelevance(invoke);
-            MethodInvocation methodInvocation = new MethodInvocation(info, calleeAssumptions, invokeProbability, invokeRelevance, freshlyInstantiatedArguments(invoke, callsiteHolder.getFixedParams()));
+            MethodInvocation methodInvocation = new MethodInvocation(info, invokeProbability, invokeRelevance, freshlyInstantiatedArguments(invoke, callsiteHolder.getFixedParams()));
             pushInvocationAndGraphs(methodInvocation);
         }
     }
@@ -640,12 +634,12 @@
      * {@link #processNextInvoke() delve} into one of the callsites hosted in the current graph,
      * such callsite is explored next by {@link #moveForward()}</li>
      * <li>
-     * {@link #tryToInline(MethodInvocation, MethodInvocation, int) try to inline}: move past the
-     * current graph (remove it from the topmost element).
+     * {@link #tryToInline(MethodInvocation, int) try to inline}: move past the current graph
+     * (remove it from the topmost element).
      * <ul>
      * <li>
-     * If that was the last one then {@link #tryToInline(MethodInvocation, MethodInvocation, int)
-     * try to inline} the callsite under consideration (ie, the "current invocation").</li>
+     * If that was the last one then {@link #tryToInline(MethodInvocation, int) try to inline} the
+     * callsite under consideration (ie, the "current invocation").</li>
      * <li>
      * Whether inlining occurs or not, that callsite is removed from the top of {@link InliningData}
      * .</li>
@@ -703,9 +697,8 @@
              * "all concrete methods that come into question already had the callees they contain analyzed for inlining"
              */
             popInvocation();
-            final MethodInvocation parentInvoke = currentInvocation();
             try (Debug.Scope s = Debug.scope("Inlining", inliningContext())) {
-                return tryToInline(currentInvocation, parentInvoke, inliningDepth() + 1);
+                return tryToInline(currentInvocation, inliningDepth() + 1);
             } catch (Throwable e) {
                 throw Debug.handle(e);
             }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/MethodInvocation.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/MethodInvocation.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,16 +22,13 @@
  */
 package com.oracle.graal.phases.common.inlining.walker;
 
-import com.oracle.graal.api.code.Assumptions;
-import com.oracle.graal.api.meta.ResolvedJavaMethod;
-import com.oracle.graal.nodes.CallTargetNode;
-import com.oracle.graal.nodes.java.MethodCallTargetNode;
-import com.oracle.graal.phases.common.inlining.info.InlineInfo;
-import com.oracle.graal.phases.common.inlining.info.elem.Inlineable;
-import com.oracle.graal.phases.common.inlining.info.elem.InlineableGraph;
-import com.oracle.graal.phases.common.inlining.info.elem.InlineableMacroNode;
+import java.util.*;
 
-import java.util.BitSet;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.phases.common.inlining.info.*;
+import com.oracle.graal.phases.common.inlining.info.elem.*;
 
 /**
  * <p>
@@ -47,7 +44,6 @@
 public class MethodInvocation {
 
     private final InlineInfo callee;
-    private final Assumptions assumptions;
     private final double probability;
     private final double relevance;
 
@@ -79,9 +75,8 @@
 
     private final int sizeFreshArgs;
 
-    public MethodInvocation(InlineInfo info, Assumptions assumptions, double probability, double relevance, BitSet freshlyInstantiatedArguments) {
+    public MethodInvocation(InlineInfo info, double probability, double relevance, BitSet freshlyInstantiatedArguments) {
         this.callee = info;
-        this.assumptions = assumptions;
         this.probability = probability;
         this.relevance = relevance;
         this.freshlyInstantiatedArguments = freshlyInstantiatedArguments;
@@ -106,10 +101,6 @@
         return callee;
     }
 
-    public Assumptions assumptions() {
-        return assumptions;
-    }
-
     public double probability() {
         return probability;
     }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/HighTierContext.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/HighTierContext.java	Wed Feb 11 16:08:50 2015 +0100
@@ -24,7 +24,6 @@
 
 import java.util.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.phases.*;
@@ -37,9 +36,8 @@
     private final Map<ResolvedJavaMethod, StructuredGraph> cache;
     private final OptimisticOptimizations optimisticOpts;
 
-    public HighTierContext(Providers providers, Assumptions assumptions, Map<ResolvedJavaMethod, StructuredGraph> cache, PhaseSuite<HighTierContext> graphBuilderSuite,
-                    OptimisticOptimizations optimisticOpts) {
-        super(providers, assumptions);
+    public HighTierContext(Providers providers, Map<ResolvedJavaMethod, StructuredGraph> cache, PhaseSuite<HighTierContext> graphBuilderSuite, OptimisticOptimizations optimisticOpts) {
+        super(providers);
         this.cache = cache;
         this.graphBuilderSuite = graphBuilderSuite;
         this.optimisticOpts = optimisticOpts;
@@ -56,8 +54,4 @@
     public OptimisticOptimizations getOptimisticOptimizations() {
         return optimisticOpts;
     }
-
-    public HighTierContext replaceAssumptions(Assumptions newAssumptions) {
-        return new HighTierContext(new Providers(this), newAssumptions, cache, graphBuilderSuite, optimisticOpts);
-    }
 }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/LowTierContext.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/LowTierContext.java	Wed Feb 11 16:08:50 2015 +0100
@@ -29,8 +29,8 @@
 
     private final TargetDescription target;
 
-    public LowTierContext(Providers copyFrom, Assumptions assumptions, TargetDescription target) {
-        super(copyFrom, assumptions);
+    public LowTierContext(Providers copyFrom, TargetDescription target) {
+        super(copyFrom);
         this.target = target;
     }
 
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/MidTierContext.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/MidTierContext.java	Wed Feb 11 16:08:50 2015 +0100
@@ -34,8 +34,8 @@
     private final ProfilingInfo profilingInfo;
     private final SpeculationLog log;
 
-    public MidTierContext(Providers copyFrom, Assumptions assumptions, TargetDescription target, OptimisticOptimizations optimisticOpts, ProfilingInfo profilingInfo, SpeculationLog log) {
-        super(copyFrom, assumptions);
+    public MidTierContext(Providers copyFrom, TargetDescription target, OptimisticOptimizations optimisticOpts, ProfilingInfo profilingInfo, SpeculationLog log) {
+        super(copyFrom);
         this.target = target;
         this.optimisticOpts = optimisticOpts;
         this.profilingInfo = profilingInfo;
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/PhaseContext.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/PhaseContext.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.phases.tiers;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.phases.util.*;
@@ -33,21 +32,18 @@
     private final ConstantReflectionProvider constantReflection;
     private final LoweringProvider lowerer;
     private final Replacements replacements;
-    private final Assumptions assumptions;
     private final StampProvider stampProvider;
 
-    public PhaseContext(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, LoweringProvider lowerer, Replacements replacements, Assumptions assumptions,
-                    StampProvider stampProvider) {
+    public PhaseContext(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, LoweringProvider lowerer, Replacements replacements, StampProvider stampProvider) {
         this.metaAccess = metaAccess;
         this.constantReflection = constantReflection;
         this.lowerer = lowerer;
         this.replacements = replacements;
-        this.assumptions = assumptions;
         this.stampProvider = stampProvider;
     }
 
-    public PhaseContext(Providers providers, Assumptions assumptions) {
-        this(providers.getMetaAccess(), providers.getConstantReflection(), providers.getLowerer(), providers.getReplacements(), assumptions, providers.getStampProvider());
+    public PhaseContext(Providers providers) {
+        this(providers.getMetaAccess(), providers.getConstantReflection(), providers.getLowerer(), providers.getReplacements(), providers.getStampProvider());
     }
 
     public MetaAccessProvider getMetaAccess() {
@@ -66,10 +62,6 @@
         return replacements;
     }
 
-    public Assumptions getAssumptions() {
-        return assumptions;
-    }
-
     public StampProvider getStampProvider() {
         return stampProvider;
     }
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ArraysSubstitutionsTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ArraysSubstitutionsTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,11 +22,12 @@
  */
 package com.oracle.graal.replacements.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
+
 import java.util.*;
 
 import org.junit.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
@@ -330,11 +331,10 @@
 
     @Test
     public void testCanonicalLength() {
-        StructuredGraph graph = parseEager("testCanonicalLengthSnippet");
-        Assumptions assumptions = new Assumptions(false);
-        HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+        StructuredGraph graph = parseEager("testCanonicalLengthSnippet", DONT_ALLOW_OPTIMISTIC_ASSUMPTIONS);
+        HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
         new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), assumptions));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders()));
 
         Assert.assertTrue(graph.getNodes(ReturnNode.class).first().result().asJavaConstant().asLong() == 0);
     }
@@ -347,11 +347,10 @@
 
     @Test
     public void testCanonicalEqual() {
-        StructuredGraph graph = parseEager("testCanonicalEqualSnippet");
-        Assumptions assumptions = new Assumptions(false);
-        HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+        StructuredGraph graph = parseEager("testCanonicalEqualSnippet", DONT_ALLOW_OPTIMISTIC_ASSUMPTIONS);
+        HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
         new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), assumptions));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders()));
 
         Assert.assertTrue(graph.getNodes(ReturnNode.class).first().result().asJavaConstant().asLong() == 1);
     }
@@ -362,13 +361,12 @@
 
     @Test
     public void testVirtualEqual() {
-        StructuredGraph graph = parseEager("testVirtualEqualSnippet");
-        Assumptions assumptions = new Assumptions(false);
-        HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+        StructuredGraph graph = parseEager("testVirtualEqualSnippet", DONT_ALLOW_OPTIMISTIC_ASSUMPTIONS);
+        HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
         new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), assumptions));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders()));
         new PartialEscapePhase(false, new CanonicalizerPhase(false)).apply(graph, context);
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), assumptions));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders()));
 
         Assert.assertTrue(graph.getNodes(ReturnNode.class).first().result().asJavaConstant().asLong() == 1);
     }
@@ -381,13 +379,12 @@
 
     @Test
     public void testVirtualNotEqual() {
-        StructuredGraph graph = parseEager("testVirtualNotEqualSnippet");
-        Assumptions assumptions = new Assumptions(false);
-        HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+        StructuredGraph graph = parseEager("testVirtualNotEqualSnippet", DONT_ALLOW_OPTIMISTIC_ASSUMPTIONS);
+        HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
         new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), assumptions));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders()));
         new PartialEscapePhase(false, new CanonicalizerPhase(false)).apply(graph, context);
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), assumptions));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders()));
 
         Assert.assertTrue(graph.getNodes(ReturnNode.class).first().result().asJavaConstant().asLong() == 0);
     }
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/BitOpNodesTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/BitOpNodesTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,9 +22,10 @@
  */
 package com.oracle.graal.replacements.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
+
 import org.junit.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.compiler.test.*;
@@ -247,8 +248,8 @@
      * @return the returned value or null if {@code expectedClass} is not found in the graph.
      */
     private ValueNode parseAndInline(String name, Class<? extends ValueNode> expectedClass) {
-        StructuredGraph graph = parseEager(name);
-        HighTierContext context = new HighTierContext(getProviders(), new Assumptions(false), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.NONE);
+        StructuredGraph graph = parseEager(name, ALLOW_OPTIMISTIC_ASSUMPTIONS);
+        HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.NONE);
         CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true);
         canonicalizer.apply(graph, context);
         new InliningPhase(canonicalizer).apply(graph, context);
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/CompiledExceptionHandlerTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/CompiledExceptionHandlerTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -40,8 +40,8 @@
     }
 
     @Override
-    protected StructuredGraph parseEager(ResolvedJavaMethod m) {
-        StructuredGraph graph = super.parseEager(m);
+    protected StructuredGraph parseEager(ResolvedJavaMethod m, boolean allowOptimisticAssumptions) {
+        StructuredGraph graph = super.parseEager(m, allowOptimisticAssumptions);
         int handlers = graph.getNodes().filter(ExceptionObjectNode.class).count();
         Assert.assertEquals(1, handlers);
         return graph;
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/EdgesTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/EdgesTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,11 +22,12 @@
  */
 package com.oracle.graal.replacements.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
+
 import java.lang.reflect.*;
 
 import org.junit.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.test.*;
 import com.oracle.graal.graph.*;
@@ -54,7 +55,7 @@
 
     }
 
-    StructuredGraph graph = new StructuredGraph();
+    StructuredGraph graph = new StructuredGraph(DONT_ALLOW_OPTIMISTIC_ASSUMPTIONS);
     TestNode node;
     ConstantNode i1;
     ConstantNode i2;
@@ -113,9 +114,8 @@
         }
 
         ResolvedJavaMethod javaMethod = getMetaAccess().lookupJavaMethod(method);
-        StructuredGraph g = parseProfiled(javaMethod);
-        Assumptions assumptions = new Assumptions(false);
-        HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+        StructuredGraph g = parseProfiled(javaMethod, DONT_ALLOW_OPTIMISTIC_ASSUMPTIONS);
+        HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
         new InliningPhase(new InlineMethodSubstitutionsPolicy(), new CanonicalizerPhase(true)).apply(g, context);
         new CanonicalizerPhase(false).apply(g, context);
         Assert.assertTrue(g.getNodes().filter(CheckCastNode.class).isEmpty());
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MethodSubstitutionTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MethodSubstitutionTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.replacements.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
 import static org.junit.Assert.*;
 
 import java.lang.reflect.*;
@@ -48,9 +49,8 @@
 
     protected StructuredGraph test(final String snippet) {
         try (Scope s = Debug.scope("MethodSubstitutionTest", getResolvedJavaMethod(snippet))) {
-            StructuredGraph graph = parseEager(snippet);
-            Assumptions assumptions = new Assumptions(true);
-            HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+            StructuredGraph graph = parseEager(snippet, ALLOW_OPTIMISTIC_ASSUMPTIONS);
+            HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
             Debug.dump(graph, "Graph");
             new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
             Debug.dump(graph, "Graph");
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ObjectAccessTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ObjectAccessTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.replacements.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
+
 import org.junit.*;
 
 import com.oracle.graal.api.code.*;
@@ -45,55 +47,55 @@
     private final ReplacementsImpl installer;
 
     public ObjectAccessTest() {
-        installer = new ReplacementsImpl(getProviders(), getSnippetReflection(), new Assumptions(false), getTarget());
+        installer = new ReplacementsImpl(getProviders(), getSnippetReflection(), getTarget());
     }
 
     private static final ThreadLocal<SnippetInliningPolicy> inliningPolicy = new ThreadLocal<>();
 
     @Override
-    protected StructuredGraph parseEager(ResolvedJavaMethod m) {
+    protected StructuredGraph parseEager(ResolvedJavaMethod m, boolean allowOptimisticAssumptions) {
         return installer.makeGraph(m, null, inliningPolicy.get(), FrameStateProcessing.CollapseFrameForSingleSideEffect);
     }
 
     @Test
     public void testRead1() {
         for (Kind kind : KINDS) {
-            assertRead(parseEager("read" + kind.name() + "1"), kind, true, ID);
+            assertRead(parseEager("read" + kind.name() + "1", ALLOW_OPTIMISTIC_ASSUMPTIONS), kind, true, ID);
         }
     }
 
     @Test
     public void testRead2() {
         for (Kind kind : KINDS) {
-            assertRead(parseEager("read" + kind.name() + "2"), kind, true, ID);
+            assertRead(parseEager("read" + kind.name() + "2", ALLOW_OPTIMISTIC_ASSUMPTIONS), kind, true, ID);
         }
     }
 
     @Test
     public void testRead3() {
         for (Kind kind : KINDS) {
-            assertRead(parseEager("read" + kind.name() + "3"), kind, true, LocationIdentity.ANY_LOCATION);
+            assertRead(parseEager("read" + kind.name() + "3", ALLOW_OPTIMISTIC_ASSUMPTIONS), kind, true, LocationIdentity.ANY_LOCATION);
         }
     }
 
     @Test
     public void testWrite1() {
         for (Kind kind : KINDS) {
-            assertWrite(parseEager("write" + kind.name() + "1"), true, ID);
+            assertWrite(parseEager("write" + kind.name() + "1", ALLOW_OPTIMISTIC_ASSUMPTIONS), true, ID);
         }
     }
 
     @Test
     public void testWrite2() {
         for (Kind kind : KINDS) {
-            assertWrite(parseEager("write" + kind.name() + "2"), true, ID);
+            assertWrite(parseEager("write" + kind.name() + "2", ALLOW_OPTIMISTIC_ASSUMPTIONS), true, ID);
         }
     }
 
     @Test
     public void testWrite3() {
         for (Kind kind : KINDS) {
-            assertWrite(parseEager("write" + kind.name() + "3"), true, LocationIdentity.ANY_LOCATION);
+            assertWrite(parseEager("write" + kind.name() + "3", ALLOW_OPTIMISTIC_ASSUMPTIONS), true, LocationIdentity.ANY_LOCATION);
         }
     }
 
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.replacements.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
+
 import org.junit.*;
 
 import com.oracle.graal.api.code.*;
@@ -51,55 +53,55 @@
 
     public PointerTest() {
         target = getCodeCache().getTarget();
-        installer = new ReplacementsImpl(getProviders(), getSnippetReflection(), new Assumptions(false), getTarget());
+        installer = new ReplacementsImpl(getProviders(), getSnippetReflection(), getTarget());
     }
 
     private static final ThreadLocal<SnippetInliningPolicy> inliningPolicy = new ThreadLocal<>();
 
     @Override
-    protected StructuredGraph parseEager(ResolvedJavaMethod m) {
+    protected StructuredGraph parseEager(ResolvedJavaMethod m, boolean allowOptimisticAssumptions) {
         return installer.makeGraph(m, null, inliningPolicy.get(), FrameStateProcessing.CollapseFrameForSingleSideEffect);
     }
 
     @Test
     public void testRead1() {
         for (Kind kind : KINDS) {
-            assertRead(parseEager("read" + kind.name() + "1"), kind, true, ID);
+            assertRead(parseEager("read" + kind.name() + "1", ALLOW_OPTIMISTIC_ASSUMPTIONS), kind, true, ID);
         }
     }
 
     @Test
     public void testRead2() {
         for (Kind kind : KINDS) {
-            assertRead(parseEager("read" + kind.name() + "2"), kind, true, ID);
+            assertRead(parseEager("read" + kind.name() + "2", ALLOW_OPTIMISTIC_ASSUMPTIONS), kind, true, ID);
         }
     }
 
     @Test
     public void testRead3() {
         for (Kind kind : KINDS) {
-            assertRead(parseEager("read" + kind.name() + "3"), kind, true, LocationIdentity.ANY_LOCATION);
+            assertRead(parseEager("read" + kind.name() + "3", ALLOW_OPTIMISTIC_ASSUMPTIONS), kind, true, LocationIdentity.ANY_LOCATION);
         }
     }
 
     @Test
     public void testWrite1() {
         for (Kind kind : KINDS) {
-            assertWrite(parseEager("write" + kind.name() + "1"), true, ID);
+            assertWrite(parseEager("write" + kind.name() + "1", ALLOW_OPTIMISTIC_ASSUMPTIONS), true, ID);
         }
     }
 
     @Test
     public void testWrite2() {
         for (Kind kind : KINDS) {
-            assertWrite(parseEager("write" + kind.name() + "2"), true, ID);
+            assertWrite(parseEager("write" + kind.name() + "2", ALLOW_OPTIMISTIC_ASSUMPTIONS), true, ID);
         }
     }
 
     @Test
     public void testWrite3() {
         for (Kind kind : KINDS) {
-            assertWrite(parseEager("write" + kind.name() + "3"), true, LocationIdentity.ANY_LOCATION);
+            assertWrite(parseEager("write" + kind.name() + "3", ALLOW_OPTIMISTIC_ASSUMPTIONS), true, LocationIdentity.ANY_LOCATION);
         }
     }
 
@@ -399,10 +401,9 @@
     }
 
     private void assertNumWordCasts(String snippetName, int expectedWordCasts) {
-        Assumptions assumptions = new Assumptions(true);
-        HighTierContext context = new HighTierContext(getProviders(), assumptions, null, null, OptimisticOptimizations.ALL);
+        HighTierContext context = new HighTierContext(getProviders(), null, null, OptimisticOptimizations.ALL);
 
-        StructuredGraph graph = parseEager(snippetName);
+        StructuredGraph graph = parseEager(snippetName, ALLOW_OPTIMISTIC_ASSUMPTIONS);
         new CanonicalizerPhase(false).apply(graph, context);
         Assert.assertEquals(expectedWordCasts, graph.getNodes().filter(WordCastNode.class).count());
     }
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/WordTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/WordTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -24,7 +24,6 @@
 
 import org.junit.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.test.*;
 import com.oracle.graal.nodes.*;
@@ -41,13 +40,13 @@
     private final ReplacementsImpl installer;
 
     public WordTest() {
-        installer = new ReplacementsImpl(getProviders(), getSnippetReflection(), new Assumptions(false), getTarget());
+        installer = new ReplacementsImpl(getProviders(), getSnippetReflection(), getTarget());
     }
 
     private static final ThreadLocal<SnippetInliningPolicy> inliningPolicy = new ThreadLocal<>();
 
     @Override
-    protected StructuredGraph parseEager(ResolvedJavaMethod m) {
+    protected StructuredGraph parseEager(ResolvedJavaMethod m, boolean allowOptimisticAssumptions) {
         return installer.makeGraph(m, null, inliningPolicy.get(), FrameStateProcessing.CollapseFrameForSingleSideEffect);
     }
 
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraphKit.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraphKit.java	Wed Feb 11 16:08:50 2015 +0100
@@ -206,7 +206,7 @@
      */
     public void inline(InvokeNode invoke, SnippetReflectionProvider snippetReflection) {
         ResolvedJavaMethod method = ((MethodCallTargetNode) invoke.callTarget()).targetMethod();
-        ReplacementsImpl repl = new ReplacementsImpl(providers, snippetReflection, new Assumptions(false), providers.getCodeCache().getTarget());
+        ReplacementsImpl repl = new ReplacementsImpl(providers, snippetReflection, providers.getCodeCache().getTarget());
         StructuredGraph calleeGraph = repl.makeGraph(method, null, null, FrameStateProcessing.CollapseFrameForSingleSideEffect);
         InliningUtil.inline(invoke, calleeGraph, false, null);
     }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java	Wed Feb 11 16:08:50 2015 +0100
@@ -112,7 +112,7 @@
     public static final class Instantiation {
 
         private ValueNode result;
-        private CompareNode condition;
+        private LogicNode condition;
         private ValueNode trueValue;
         private ValueNode falseValue;
 
@@ -141,9 +141,9 @@
                 assert testValue.isConstant();
                 return LogicConstantNode.forBoolean(result.asConstant().equals(testValue.asConstant()), result.graph());
             }
-            if (condition == null || condition.getY() != testValue) {
+            if (condition == null || (!(condition instanceof CompareNode)) || ((CompareNode) condition).getY() != testValue) {
                 // Re-use previously generated condition if the trueValue for the test is the same
-                condition = createCompareNode(result.graph(), Condition.EQ, result, testValue);
+                condition = createCompareNode(result.graph(), Condition.EQ, result, testValue, null);
             }
             return condition;
         }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.replacements;
 
+import static com.oracle.graal.api.code.Assumptions.*;
 import static com.oracle.graal.api.meta.MetaUtil.*;
 import static com.oracle.graal.compiler.GraalCompiler.*;
 import static com.oracle.graal.compiler.common.GraalOptions.*;
@@ -63,7 +64,6 @@
     public final Providers providers;
     public final SnippetReflectionProvider snippetReflection;
     public final TargetDescription target;
-    public final Assumptions assumptions;
 
     /**
      * The preprocessed replacement graphs.
@@ -219,13 +219,12 @@
     // it is stable across VM executions (in support of replay compilation).
     private final Map<String, SnippetTemplateCache> snippetTemplateCache;
 
-    public ReplacementsImpl(Providers providers, SnippetReflectionProvider snippetReflection, Assumptions assumptions, TargetDescription target) {
+    public ReplacementsImpl(Providers providers, SnippetReflectionProvider snippetReflection, TargetDescription target) {
         this.providers = providers.copyWith(this);
         this.classReplacements = CollectionsFactory.newMap();
         this.internalNameToSubstitutionClasses = CollectionsFactory.newMap();
         this.snippetReflection = snippetReflection;
         this.target = target;
-        this.assumptions = assumptions;
         this.graphs = new ConcurrentHashMap<>();
         this.snippetTemplateCache = CollectionsFactory.newMap();
     }
@@ -287,7 +286,7 @@
         // Do deferred intrinsification of node intrinsics
 
         createNodeIntrinsificationPhase().apply(specializedSnippet);
-        new CanonicalizerPhase(true).apply(specializedSnippet, new PhaseContext(providers, assumptions));
+        new CanonicalizerPhase(true).apply(specializedSnippet, new PhaseContext(providers));
         NodeIntrinsificationVerificationPhase.verify(specializedSnippet);
     }
 
@@ -319,10 +318,6 @@
         return cr == null ? null : cr.macroSubstitutions.get(method);
     }
 
-    public Assumptions getAssumptions() {
-        return assumptions;
-    }
-
     private SubstitutionGuard getGuard(Class<? extends SubstitutionGuard> guardClass) {
         if (guardClass != SubstitutionGuard.class) {
             Constructor<?>[] constructors = guardClass.getConstructors();
@@ -612,20 +607,22 @@
          * Builds the initial graph for a snippet.
          */
         protected StructuredGraph buildInitialGraph(final ResolvedJavaMethod methodToParse) {
-            final StructuredGraph graph = new StructuredGraph(methodToParse);
+            // Replacements cannot have optimistic assumptions since they have
+            // to be valid for the entire run of the VM.
+            final StructuredGraph graph = new StructuredGraph(methodToParse, DONT_ALLOW_OPTIMISTIC_ASSUMPTIONS);
             try (Scope s = Debug.scope("buildInitialGraph", graph)) {
                 MetaAccessProvider metaAccess = replacements.providers.getMetaAccess();
 
                 if (MethodsElidedInSnippets != null && methodToParse.getSignature().getReturnKind() == Kind.Void && MethodFilter.matches(MethodsElidedInSnippets, methodToParse)) {
                     graph.addAfterFixed(graph.start(), graph.add(new ReturnNode(null)));
                 } else {
-                    createGraphBuilder(metaAccess, replacements.providers.getStampProvider(), replacements.assumptions, replacements.providers.getConstantReflection(),
-                                    GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE).apply(graph);
+                    createGraphBuilder(metaAccess, replacements.providers.getStampProvider(), replacements.providers.getConstantReflection(), GraphBuilderConfiguration.getSnippetDefault(),
+                                    OptimisticOptimizations.NONE).apply(graph);
                 }
                 afterParsing(graph);
 
                 if (OptCanonicalizer.getValue()) {
-                    new CanonicalizerPhase(true).apply(graph, new PhaseContext(replacements.providers, replacements.assumptions));
+                    new CanonicalizerPhase(true).apply(graph, new PhaseContext(replacements.providers));
                 }
             } catch (Throwable e) {
                 throw Debug.handle(e);
@@ -633,9 +630,9 @@
             return graph;
         }
 
-        protected Instance createGraphBuilder(MetaAccessProvider metaAccess, StampProvider stampProvider, Assumptions assumptions, ConstantReflectionProvider constantReflection,
-                        GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts) {
-            return new GraphBuilderPhase.Instance(metaAccess, stampProvider, assumptions, constantReflection, graphBuilderConfig, optimisticOpts);
+        protected Instance createGraphBuilder(MetaAccessProvider metaAccess, StampProvider stampProvider, ConstantReflectionProvider constantReflection, GraphBuilderConfiguration graphBuilderConfig,
+                        OptimisticOptimizations optimisticOpts) {
+            return new GraphBuilderPhase.Instance(metaAccess, stampProvider, constantReflection, graphBuilderConfig, optimisticOpts);
         }
 
         protected void afterParsing(StructuredGraph graph) {
@@ -657,7 +654,7 @@
          */
         protected void afterInline(StructuredGraph caller, StructuredGraph callee, Object beforeInlineData) {
             if (OptCanonicalizer.getValue()) {
-                new CanonicalizerPhase(true).apply(caller, new PhaseContext(replacements.providers, replacements.assumptions));
+                new CanonicalizerPhase(true).apply(caller, new PhaseContext(replacements.providers));
             }
         }
 
@@ -668,7 +665,7 @@
             replacements.createNodeIntrinsificationPhase().apply(graph);
             new DeadCodeEliminationPhase(Optional).apply(graph);
             if (OptCanonicalizer.getValue()) {
-                new CanonicalizerPhase(true).apply(graph, new PhaseContext(replacements.providers, replacements.assumptions));
+                new CanonicalizerPhase(true).apply(graph, new PhaseContext(replacements.providers));
             }
         }
 
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.replacements;
 
+import static com.oracle.graal.api.code.Assumptions.*;
 import static com.oracle.graal.api.meta.LocationIdentity.*;
 import static com.oracle.graal.compiler.common.GraalOptions.*;
 import static com.oracle.graal.debug.Debug.*;
@@ -561,10 +562,10 @@
         ResolvedJavaMethod method = snippetGraph.method();
         Signature signature = method.getSignature();
 
-        PhaseContext phaseContext = new PhaseContext(providers, new Assumptions(false));
+        PhaseContext phaseContext = new PhaseContext(providers);
 
         // Copy snippet graph, replacing constant parameters with given arguments
-        final StructuredGraph snippetCopy = new StructuredGraph(snippetGraph.name, snippetGraph.method());
+        final StructuredGraph snippetCopy = new StructuredGraph(snippetGraph.name, snippetGraph.method(), DONT_ALLOW_OPTIMISTIC_ASSUMPTIONS);
         Map<Node, Node> nodeReplacements = Node.newIdentityMap();
         nodeReplacements.put(snippetGraph.start(), snippetCopy.start());
 
@@ -1245,7 +1246,7 @@
 
             // Inline the snippet nodes, replacing parameters with the given args in the process
             String name = snippet.name == null ? "{copy}" : snippet.name + "{copy}";
-            StructuredGraph snippetCopy = new StructuredGraph(name, snippet.method());
+            StructuredGraph snippetCopy = new StructuredGraph(name, snippet.method(), DONT_ALLOW_OPTIMISTIC_ASSUMPTIONS);
             StartNode entryPointNode = snippet.start();
             FixedNode firstCFGNode = entryPointNode.next();
             StructuredGraph replaceeGraph = replacee.graph();
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BasicObjectCloneNode.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BasicObjectCloneNode.java	Wed Feb 11 16:08:50 2015 +0100
@@ -61,7 +61,7 @@
     /*
      * Looks at the given stamp and determines if it is an exact type (or can be assumed to be an
      * exact type) and if it is a cloneable type.
-     * 
+     *
      * If yes, then the exact type is returned, otherwise it returns null.
      */
     protected static ResolvedJavaType getConcreteType(Stamp stamp, Assumptions assumptions, MetaAccessProvider metaAccess) {
@@ -105,7 +105,7 @@
             } else {
                 obj = tool.getReplacedValue(getObject());
             }
-            ResolvedJavaType type = getConcreteType(obj.stamp(), tool.getAssumptions(), tool.getMetaAccessProvider());
+            ResolvedJavaType type = getConcreteType(obj.stamp(), graph().getAssumptions(), tool.getMetaAccessProvider());
             if (type != null && !type.isArray()) {
                 VirtualInstanceNode newVirtual = createVirtualInstanceNode(type, true);
                 ResolvedJavaField[] fields = newVirtual.getFields();
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java	Wed Feb 11 16:08:50 2015 +0100
@@ -129,7 +129,7 @@
      * @param replacementGraph a replacement (i.e., snippet or method substitution) graph
      */
     protected StructuredGraph lowerReplacement(final StructuredGraph replacementGraph, LoweringTool tool) {
-        final PhaseContext c = new PhaseContext(tool.getMetaAccess(), tool.getConstantReflection(), tool.getLowerer(), tool.getReplacements(), tool.assumptions(), tool.getStampProvider());
+        final PhaseContext c = new PhaseContext(tool.getMetaAccess(), tool.getConstantReflection(), tool.getLowerer(), tool.getReplacements(), tool.getStampProvider());
         if (!graph().hasValueProxies()) {
             new RemoveValueProxyPhase().apply(replacementGraph);
         }
--- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.truffle.hotspot;
 
+import static com.oracle.graal.api.code.Assumptions.*;
 import static com.oracle.graal.api.code.CodeUtil.*;
 import static com.oracle.graal.compiler.GraalCompiler.*;
 import static com.oracle.graal.graph.util.CollectionsAccess.*;
@@ -178,9 +179,8 @@
         Suites suites = suitesProvider.createSuites();
         LIRSuites lirSuites = suitesProvider.createLIRSuites();
         removeInliningPhase(suites);
-        StructuredGraph graph = new StructuredGraph(javaMethod);
-        new GraphBuilderPhase.Instance(metaAccess, providers.getStampProvider(), new Assumptions(false), providers.getConstantReflection(), GraphBuilderConfiguration.getEagerDefault(),
-                        OptimisticOptimizations.ALL).apply(graph);
+        StructuredGraph graph = new StructuredGraph(javaMethod, DONT_ALLOW_OPTIMISTIC_ASSUMPTIONS);
+        new GraphBuilderPhase.Instance(metaAccess, providers.getStampProvider(), providers.getConstantReflection(), 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.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,9 +22,10 @@
  */
 package com.oracle.graal.truffle.test;
 
+import static com.oracle.graal.api.code.Assumptions.*;
+
 import org.junit.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.compiler.test.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
@@ -53,18 +54,16 @@
     }
 
     protected OptimizedCallTarget compileHelper(String methodName, RootNode root, Object[] arguments) {
-        Assumptions assumptions = new Assumptions(true);
         final OptimizedCallTarget compilable = (OptimizedCallTarget) Truffle.getRuntime().createCallTarget(root);
-        StructuredGraph actual = partialEval(compilable, arguments, assumptions);
-        truffleCompiler.compileMethodHelper(actual, assumptions, methodName, getSpeculationLog(), compilable);
+        StructuredGraph actual = partialEval(compilable, arguments, ALLOW_OPTIMISTIC_ASSUMPTIONS);
+        truffleCompiler.compileMethodHelper(actual, methodName, null, getSpeculationLog(), compilable);
         return compilable;
     }
 
     protected OptimizedCallTarget assertPartialEvalEquals(String methodName, RootNode root, Object[] arguments) {
-        Assumptions assumptions = new Assumptions(true);
         final OptimizedCallTarget compilable = (OptimizedCallTarget) Truffle.getRuntime().createCallTarget(root);
-        StructuredGraph actual = partialEval(compilable, arguments, assumptions);
-        truffleCompiler.compileMethodHelper(actual, assumptions, methodName, getSpeculationLog(), compilable);
+        StructuredGraph actual = partialEval(compilable, arguments, ALLOW_OPTIMISTIC_ASSUMPTIONS);
+        truffleCompiler.compileMethodHelper(actual, methodName, null, getSpeculationLog(), compilable);
         removeFrameStates(actual);
         StructuredGraph expected = parseForComparison(methodName);
         Assert.assertEquals(getCanonicalGraphString(expected, true, true), getCanonicalGraphString(actual, true, true));
@@ -76,23 +75,22 @@
     }
 
     protected void assertPartialEvalNoInvokes(RootNode root, Object[] arguments) {
-        Assumptions assumptions = new Assumptions(true);
         final OptimizedCallTarget compilable = (OptimizedCallTarget) Truffle.getRuntime().createCallTarget(root);
-        StructuredGraph actual = partialEval(compilable, arguments, assumptions);
+        StructuredGraph actual = partialEval(compilable, arguments, ALLOW_OPTIMISTIC_ASSUMPTIONS);
         removeFrameStates(actual);
         for (MethodCallTargetNode node : actual.getNodes(MethodCallTargetNode.class)) {
             Assert.fail("Found invalid method call target node: " + node);
         }
     }
 
-    protected StructuredGraph partialEval(OptimizedCallTarget compilable, Object[] arguments, final Assumptions assumptions) {
+    protected StructuredGraph partialEval(OptimizedCallTarget compilable, Object[] arguments, boolean allowOptimisticAssumptions) {
         // Executed AST so that all classes are loaded and initialized.
         compilable.call(arguments);
         compilable.call(arguments);
         compilable.call(arguments);
 
         try (Scope s = Debug.scope("TruffleCompilation", new TruffleDebugJavaMethod(compilable))) {
-            return truffleCompiler.getPartialEvaluator().createGraph(compilable, assumptions);
+            return truffleCompiler.getPartialEvaluator().createGraph(compilable, allowOptimisticAssumptions, null);
         } catch (Throwable e) {
             throw Debug.handle(e);
         }
@@ -103,13 +101,13 @@
             frameState.replaceAtUsages(null);
             frameState.safeDelete();
         }
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), new Assumptions(false)));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders()));
         new DeadCodeEliminationPhase().apply(graph);
     }
 
     protected StructuredGraph parseForComparison(final String methodName) {
         try (Scope s = Debug.scope("Truffle", new DebugDumpScope("Comparison: " + methodName))) {
-            StructuredGraph graph = parseEager(methodName);
+            StructuredGraph graph = parseEager(methodName, ALLOW_OPTIMISTIC_ASSUMPTIONS);
             compile(graph.method(), graph);
             return graph;
         } catch (Throwable e) {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedAssumption.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedAssumption.java	Wed Feb 11 16:08:50 2015 +0100
@@ -30,6 +30,7 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.debug.*;
+import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.CompilerDirectives.*;
 import com.oracle.truffle.api.impl.*;
 import com.oracle.truffle.api.nodes.*;
@@ -50,7 +51,8 @@
 
     @Override
     public void check() throws InvalidAssumptionException {
-        if (!isValid) {
+        if (!this.isValid()) {
+            CompilerDirectives.transferToInterpreterAndInvalidate();
             throw new InvalidAssumptionException();
         }
     }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Wed Feb 11 16:08:50 2015 +0100
@@ -30,7 +30,6 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.replacements.*;
-import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.debug.internal.*;
@@ -97,7 +96,7 @@
         }
     }
 
-    public StructuredGraph createGraph(final OptimizedCallTarget callTarget, final Assumptions assumptions) {
+    public StructuredGraph createGraph(final OptimizedCallTarget callTarget, boolean allowOptimisticAssumptions, GraphBuilderPlugins graalPlugins) {
         if (TraceTruffleCompilationHistogram.getValue() || TraceTruffleCompilationDetails.getValue()) {
             constantReceivers = new HashSet<>();
         }
@@ -108,7 +107,7 @@
             throw Debug.handle(e);
         }
 
-        final StructuredGraph graph = new StructuredGraph(callTarget.toString(), callRootMethod);
+        final StructuredGraph graph = new StructuredGraph(callTarget.toString(), callRootMethod, allowOptimisticAssumptions);
         assert graph != null : "no graph for root method";
 
         try (Scope s = Debug.scope("CreateGraph", graph); Indent indent = Debug.logAndIndent("createGraph %s", graph)) {
@@ -117,14 +116,14 @@
             if (CacheGraphs.getValue()) {
                 graphCache = new HashMap<>();
             }
-            PhaseContext baseContext = new PhaseContext(providers, assumptions);
-            HighTierContext tierContext = new HighTierContext(providers, assumptions, graphCache, new PhaseSuite<HighTierContext>(), OptimisticOptimizations.NONE);
+            PhaseContext baseContext = new PhaseContext(providers);
+            HighTierContext tierContext = new HighTierContext(providers, graphCache, new PhaseSuite<HighTierContext>(), OptimisticOptimizations.NONE);
 
             if (TruffleCompilerOptions.FastPE.getValue()) {
-                fastPartialEvaluation(callTarget, assumptions, graph, baseContext, tierContext);
+                fastPartialEvaluation(callTarget, graph, baseContext, tierContext, graalPlugins);
             } else {
                 createRootGraph(graph);
-                partialEvaluation(callTarget, assumptions, graph, baseContext, tierContext);
+                partialEvaluation(callTarget, graph, baseContext, tierContext);
             }
 
             if (Thread.currentThread().isInterrupted()) {
@@ -207,20 +206,18 @@
     }
 
     @SuppressWarnings("unused")
-    private void fastPartialEvaluation(OptimizedCallTarget callTarget, Assumptions assumptions, StructuredGraph graph, PhaseContext baseContext, HighTierContext tierContext) {
+    private void fastPartialEvaluation(OptimizedCallTarget callTarget, StructuredGraph graph, PhaseContext baseContext, HighTierContext tierContext, GraphBuilderPlugins graalPlugins) {
         GraphBuilderConfiguration newConfig = configForRoot.copy();
         newConfig.setLoadFieldPlugin(new InterceptLoadFieldPlugin());
         newConfig.setParameterPlugin(new InterceptReceiverPlugin(callTarget));
         newConfig.setInlineInvokePlugin(new InlineInvokePlugin());
         newConfig.setLoopExplosionPlugin(new LoopExplosionPlugin());
-        DefaultGraphBuilderPlugins plugins = new DefaultGraphBuilderPlugins();
-        Iterable<GraphBuilderPluginsProvider> sl = Services.load(GraphBuilderPluginsProvider.class);
-        for (GraphBuilderPluginsProvider p : sl) {
-            p.registerPlugins(providers.getMetaAccess(), plugins);
-        }
+        DefaultGraphBuilderPlugins plugins = graalPlugins == null ? new DefaultGraphBuilderPlugins() : graalPlugins.copy();
         TruffleGraphBuilderPlugins.registerPlugins(providers.getMetaAccess(), plugins);
-        new GraphBuilderPhase.Instance(providers.getMetaAccess(), providers.getStampProvider(), new Assumptions(false), providers.getConstantReflection(), newConfig, plugins,
+        long ms = System.currentTimeMillis();
+        new GraphBuilderPhase.Instance(providers.getMetaAccess(), providers.getStampProvider(), this.snippetReflection, providers.getConstantReflection(), newConfig, plugins,
                         TruffleCompilerImpl.Optimizations).apply(graph);
+        System.out.println("# ms: " + (System.currentTimeMillis() - ms));
         Debug.dump(graph, "After FastPE");
 
         // Do single partial escape and canonicalization pass.
@@ -232,7 +229,7 @@
         }
     }
 
-    private void partialEvaluation(final OptimizedCallTarget callTarget, final Assumptions assumptions, final StructuredGraph graph, PhaseContext baseContext, HighTierContext tierContext) {
+    private void partialEvaluation(final OptimizedCallTarget callTarget, final StructuredGraph graph, PhaseContext baseContext, HighTierContext tierContext) {
         injectConstantCallTarget(graph, callTarget, baseContext);
 
         Debug.dump(graph, "Before expansion");
@@ -242,7 +239,7 @@
             expansionLogger = new TruffleExpansionLogger(providers, graph);
         }
 
-        expandTree(graph, assumptions, expansionLogger);
+        expandTree(graph, expansionLogger);
 
         TruffleInliningCache inliningCache = null;
         if (TruffleFunctionInlining.getValue()) {
@@ -252,7 +249,7 @@
             }
         }
 
-        expandDirectCalls(graph, assumptions, expansionLogger, callTarget.getInlining(), inliningCache);
+        expandDirectCalls(graph, expansionLogger, callTarget.getInlining(), inliningCache);
 
         if (Thread.currentThread().isInterrupted()) {
             return;
@@ -267,7 +264,7 @@
             } catch (Throwable t) {
                 Debug.handle(t);
             }
-        } while (expandTree(graph, assumptions, expansionLogger));
+        } while (expandTree(graph, expansionLogger));
 
         if (expansionLogger != null) {
             expansionLogger.print(callTarget);
@@ -275,15 +272,13 @@
     }
 
     public StructuredGraph createRootGraph(StructuredGraph graph) {
-        new GraphBuilderPhase.Instance(providers.getMetaAccess(), providers.getStampProvider(), new Assumptions(false), providers.getConstantReflection(), configForRoot,
-                        TruffleCompilerImpl.Optimizations).apply(graph);
+        new GraphBuilderPhase.Instance(providers.getMetaAccess(), providers.getStampProvider(), providers.getConstantReflection(), configForRoot, TruffleCompilerImpl.Optimizations).apply(graph);
         return graph;
     }
 
-    public StructuredGraph createInlineGraph(String name) {
-        StructuredGraph graph = new StructuredGraph(name, callInlinedMethod);
-        new GraphBuilderPhase.Instance(providers.getMetaAccess(), providers.getStampProvider(), new Assumptions(false), providers.getConstantReflection(), configForRoot,
-                        TruffleCompilerImpl.Optimizations).apply(graph);
+    public StructuredGraph createInlineGraph(String name, StructuredGraph caller) {
+        StructuredGraph graph = new StructuredGraph(name, callInlinedMethod, caller.getAssumptions().useOptimisticAssumptions());
+        new GraphBuilderPhase.Instance(providers.getMetaAccess(), providers.getStampProvider(), providers.getConstantReflection(), configForRoot, TruffleCompilerImpl.Optimizations).apply(graph);
         return graph;
     }
 
@@ -339,8 +334,8 @@
         new DebugHistogramAsciiPrinter(TTY.out().out()).print(histogram);
     }
 
-    private boolean expandTree(StructuredGraph graph, Assumptions assumptions, TruffleExpansionLogger expansionLogger) {
-        PhaseContext phaseContext = new PhaseContext(providers, assumptions);
+    private boolean expandTree(StructuredGraph graph, TruffleExpansionLogger expansionLogger) {
+        PhaseContext phaseContext = new PhaseContext(providers);
         boolean changed = false;
         boolean changedInIteration;
         ArrayDeque<MethodCallTargetNode> queue = new ArrayDeque<>();
@@ -481,18 +476,18 @@
         }
     }
 
-    private void expandDirectCalls(StructuredGraph graph, Assumptions assumptions, TruffleExpansionLogger expansionLogger, TruffleInlining inlining, TruffleInliningCache inliningCache) {
-        PhaseContext phaseContext = new PhaseContext(providers, assumptions);
+    private void expandDirectCalls(StructuredGraph graph, TruffleExpansionLogger expansionLogger, TruffleInlining inlining, TruffleInliningCache inliningCache) {
+        PhaseContext phaseContext = new PhaseContext(providers);
 
         for (MethodCallTargetNode methodCallTargetNode : graph.getNodes(MethodCallTargetNode.class).snapshot()) {
-            StructuredGraph inlineGraph = parseDirectCallGraph(phaseContext, assumptions, inlining, inliningCache, methodCallTargetNode);
+            StructuredGraph inlineGraph = parseDirectCallGraph(phaseContext, graph, inlining, inliningCache, methodCallTargetNode);
 
             if (inlineGraph != null) {
                 expandTreeInline(graph, phaseContext, expansionLogger, methodCallTargetNode, inlineGraph);
             }
         }
         // non inlined direct calls need to be expanded until TruffleCallBoundary.
-        expandTree(graph, assumptions, expansionLogger);
+        expandTree(graph, expansionLogger);
         assert noDirectCallsLeft(graph);
     }
 
@@ -505,7 +500,7 @@
         return true;
     }
 
-    private StructuredGraph parseDirectCallGraph(PhaseContext phaseContext, Assumptions assumptions, TruffleInlining inlining, TruffleInliningCache inliningCache,
+    private StructuredGraph parseDirectCallGraph(PhaseContext phaseContext, StructuredGraph caller, TruffleInlining inlining, TruffleInliningCache inliningCache,
                     MethodCallTargetNode methodCallTargetNode) {
         OptimizedDirectCallNode callNode = resolveConstantCallNode(methodCallTargetNode);
         if (callNode == null) {
@@ -534,13 +529,13 @@
         StructuredGraph graph;
         if (decision != null && decision.isInline()) {
             if (inliningCache == null) {
-                graph = createInlineGraph(phaseContext, assumptions, null, decision);
+                graph = createInlineGraph(phaseContext, caller, null, decision);
             } else {
-                graph = inliningCache.getCachedGraph(phaseContext, assumptions, decision);
+                graph = inliningCache.getCachedGraph(phaseContext, caller, decision);
             }
             decision.getProfile().setGraalDeepNodeCount(graph.getNodeCount());
 
-            assumptions.record(new AssumptionValidAssumption((OptimizedAssumption) decision.getTarget().getNodeRewritingAssumption()));
+            caller.getAssumptions().record(new AssumptionValidAssumption((OptimizedAssumption) decision.getTarget().getNodeRewritingAssumption()));
         } else {
             // we continue expansion of callDirect until we reach the callBoundary.
             graph = parseGraph(methodCallTargetNode.targetMethod(), methodCallTargetNode.arguments(), phaseContext);
@@ -589,17 +584,17 @@
         return (OptimizedDirectCallNode) value;
     }
 
-    private StructuredGraph createInlineGraph(PhaseContext phaseContext, Assumptions assumptions, TruffleInliningCache cache, TruffleInliningDecision decision) {
+    private StructuredGraph createInlineGraph(PhaseContext phaseContext, StructuredGraph caller, TruffleInliningCache cache, TruffleInliningDecision decision) {
         try (Scope s = Debug.scope("GuestLanguageInlinedGraph", new DebugDumpScope(decision.getTarget().toString()))) {
             OptimizedCallTarget target = decision.getTarget();
-            StructuredGraph inlineGraph = createInlineGraph(target.toString());
+            StructuredGraph inlineGraph = createInlineGraph(target.toString(), caller);
             injectConstantCallTarget(inlineGraph, decision.getTarget(), phaseContext);
             TruffleExpansionLogger expansionLogger = null;
             if (TraceTruffleExpansion.getValue()) {
                 expansionLogger = new TruffleExpansionLogger(providers, inlineGraph);
             }
-            expandTree(inlineGraph, assumptions, expansionLogger);
-            expandDirectCalls(inlineGraph, assumptions, expansionLogger, decision, cache);
+            expandTree(inlineGraph, expansionLogger);
+            expandDirectCalls(inlineGraph, expansionLogger, decision, cache);
 
             if (expansionLogger != null) {
                 expansionLogger.print(target);
@@ -630,11 +625,11 @@
             this.cache = new HashMap<>();
         }
 
-        public StructuredGraph getCachedGraph(PhaseContext phaseContext, Assumptions assumptions, TruffleInliningDecision decision) {
+        public StructuredGraph getCachedGraph(PhaseContext phaseContext, StructuredGraph caller, TruffleInliningDecision decision) {
             CacheKey cacheKey = new CacheKey(decision);
             StructuredGraph inlineGraph = cache.get(cacheKey);
             if (inlineGraph == null) {
-                inlineGraph = createInlineGraph(phaseContext, assumptions, this, decision);
+                inlineGraph = createInlineGraph(phaseContext, caller, this, decision);
                 cache.put(cacheKey, inlineGraph);
             }
             return inlineGraph;
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,10 +22,11 @@
  */
 package com.oracle.graal.truffle;
 
+import static com.oracle.graal.api.code.Assumptions.*;
+
 import java.util.*;
 import java.util.Map.Entry;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
@@ -60,7 +61,7 @@
 
     private final HashMap<List<Object>, StructuredGraph> cache = new HashMap<>();
     private final HashMap<List<Object>, Long> lastUsed = new HashMap<>();
-    private final StructuredGraph markerGraph = new StructuredGraph();
+    private final StructuredGraph markerGraph = new StructuredGraph(DONT_ALLOW_OPTIMISTIC_ASSUMPTIONS);
 
     private final ResolvedJavaType stringBuilderClass;
     private final ResolvedJavaType runtimeExceptionClass;
@@ -119,11 +120,11 @@
             lookupExceedsMaxSize();
         }
 
-        StructuredGraph graph;
-        PhaseContext phaseContext = new PhaseContext(providers, new Assumptions(false));
+        StructuredGraph graph = new StructuredGraph(method, DONT_ALLOW_OPTIMISTIC_ASSUMPTIONS);
+        PhaseContext phaseContext = new PhaseContext(providers);
         try (Scope s = Debug.scope("TruffleCache", providers.getMetaAccess(), method)) {
 
-            graph = parseGraph(method, phaseContext);
+            graph = parseGraph(graph, phaseContext);
             if (graph == null) {
                 return null;
             }
@@ -268,9 +269,8 @@
         canonicalizer.applyIncremental(graph, phaseContext, canonicalizerUsages);
     }
 
-    protected StructuredGraph parseGraph(final ResolvedJavaMethod method, final PhaseContext phaseContext) {
-        final StructuredGraph graph = new StructuredGraph(method);
-        new GraphBuilderPhase.Instance(phaseContext.getMetaAccess(), phaseContext.getStampProvider(), phaseContext.getAssumptions(), null, config, optimisticOptimizations).apply(graph);
+    protected StructuredGraph parseGraph(StructuredGraph graph, final PhaseContext phaseContext) {
+        new GraphBuilderPhase.Instance(phaseContext.getMetaAccess(), phaseContext.getStampProvider(), null, config, optimisticOptimizations).apply(graph);
         return graph;
     }
 
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.truffle;
 
+import static com.oracle.graal.api.code.Assumptions.*;
 import static com.oracle.graal.api.code.CodeUtil.*;
 import static com.oracle.graal.compiler.GraalCompiler.*;
 
@@ -68,7 +69,8 @@
     private final TruffleCache truffleCache;
     private final GraalTruffleCompilationListener compilationNotify;
 
-    private static final Class<?>[] SKIPPED_EXCEPTION_CLASSES = new Class[]{UnexpectedResultException.class, SlowPathException.class, ArithmeticException.class, IllegalArgumentException.class};
+    private static final Class<?>[] SKIPPED_EXCEPTION_CLASSES = new Class[]{UnexpectedResultException.class, SlowPathException.class, ArithmeticException.class, IllegalArgumentException.class,
+                    VirtualMachineError.class, ClassCastException.class};
 
     public static final OptimisticOptimizations Optimizations = OptimisticOptimizations.ALL.remove(OptimisticOptimizations.Optimization.UseExceptionProbability,
                     OptimisticOptimizations.Optimization.RemoveNeverExecutedCode, OptimisticOptimizations.Optimization.UseTypeCheckedInlining, OptimisticOptimizations.Optimization.UseTypeCheckHints);
@@ -118,10 +120,10 @@
         compilationNotify.notifyCompilationStarted(compilable);
 
         try {
-            Assumptions assumptions = new Assumptions(true);
+            GraphBuilderSuiteInfo info = createGraphBuilderSuite();
 
             try (TimerCloseable a = PartialEvaluationTime.start(); Closeable c = PartialEvaluationMemUse.start()) {
-                graph = partialEvaluator.createGraph(compilable, assumptions);
+                graph = partialEvaluator.createGraph(compilable, ALLOW_OPTIMISTIC_ASSUMPTIONS, info.plugins);
             }
 
             if (Thread.currentThread().isInterrupted()) {
@@ -136,7 +138,7 @@
             }
 
             compilationNotify.notifyCompilationTruffleTierFinished(compilable, graph);
-            CompilationResult compilationResult = compileMethodHelper(graph, assumptions, compilable.toString(), compilable.getSpeculationLog(), compilable);
+            CompilationResult compilationResult = compileMethodHelper(graph, compilable.toString(), info.suite, compilable.getSpeculationLog(), compilable);
             compilationNotify.notifyCompilationSuccess(compilable, graph, compilationResult);
         } catch (Throwable t) {
             compilationNotify.notifyCompilationFailed(compilable, graph, t);
@@ -144,7 +146,7 @@
         }
     }
 
-    public CompilationResult compileMethodHelper(StructuredGraph graph, Assumptions assumptions, String name, SpeculationLog speculationLog, InstalledCode predefinedInstalledCode) {
+    public CompilationResult compileMethodHelper(StructuredGraph graph, String name, PhaseSuite<HighTierContext> graphBuilderSuite, SpeculationLog speculationLog, InstalledCode predefinedInstalledCode) {
         try (Scope s = Debug.scope("TruffleFinal")) {
             Debug.dump(1, graph, "After TruffleTier");
         } catch (Throwable e) {
@@ -156,8 +158,8 @@
             CodeCacheProvider codeCache = providers.getCodeCache();
             CallingConvention cc = getCallingConvention(codeCache, Type.JavaCallee, graph.method(), false);
             CompilationResult compilationResult = new CompilationResult(name);
-            result = compileGraph(graph, cc, graph.method(), providers, backend, codeCache.getTarget(), null, createGraphBuilderSuite(), Optimizations, getProfilingInfo(graph), speculationLog,
-                            suites, lirSuites, compilationResult, CompilationResultBuilderFactory.Default);
+            result = compileGraph(graph, cc, graph.method(), providers, backend, codeCache.getTarget(), null, graphBuilderSuite == null ? createGraphBuilderSuite().suite : graphBuilderSuite,
+                            Optimizations, getProfilingInfo(graph), speculationLog, suites, lirSuites, compilationResult, CompilationResultBuilderFactory.Default);
         } catch (Throwable e) {
             throw Debug.handle(e);
         }
@@ -165,20 +167,18 @@
         compilationNotify.notifyCompilationGraalTierFinished((OptimizedCallTarget) predefinedInstalledCode, graph);
 
         List<AssumptionValidAssumption> validAssumptions = new ArrayList<>();
-        Assumptions newAssumptions = new Assumptions(true);
-        if (assumptions != null) {
-            for (Assumption assumption : assumptions.getAssumptions()) {
+        Set<Assumption> newAssumptions = new HashSet<>();
+        for (Assumption assumption : graph.getAssumptions()) {
+            processAssumption(newAssumptions, assumption, validAssumptions);
+        }
+
+        if (result.getAssumptions() != null) {
+            for (Assumption assumption : result.getAssumptions()) {
                 processAssumption(newAssumptions, assumption, validAssumptions);
             }
         }
 
-        if (result.getAssumptions() != null) {
-            for (Assumption assumption : result.getAssumptions().getAssumptions()) {
-                processAssumption(newAssumptions, assumption, validAssumptions);
-            }
-        }
-
-        result.setAssumptions(newAssumptions);
+        result.setAssumptions(newAssumptions.toArray(new Assumption[newAssumptions.size()]));
 
         InstalledCode installedCode;
         try (Scope s = Debug.scope("CodeInstall", providers.getCodeCache()); TimerCloseable a = CodeInstallationTime.start(); Closeable c = CodeInstallationMemUse.start()) {
@@ -197,22 +197,33 @@
         return result;
     }
 
-    private PhaseSuite<HighTierContext> createGraphBuilderSuite() {
+    static class GraphBuilderSuiteInfo {
+        final PhaseSuite<HighTierContext> suite;
+        final GraphBuilderPlugins plugins;
+
+        public GraphBuilderSuiteInfo(PhaseSuite<HighTierContext> suite, GraphBuilderPlugins plugins) {
+            this.suite = suite;
+            this.plugins = plugins;
+        }
+    }
+
+    private GraphBuilderSuiteInfo createGraphBuilderSuite() {
         PhaseSuite<HighTierContext> suite = backend.getSuites().getDefaultGraphBuilderSuite().copy();
         ListIterator<BasePhase<? super HighTierContext>> iterator = suite.findPhase(GraphBuilderPhase.class);
         GraphBuilderPhase graphBuilderPhase = (GraphBuilderPhase) iterator.previous();
         iterator.remove();
-        iterator.add(new GraphBuilderPhase(config, graphBuilderPhase.getGraphBuilderPlugins()));
-        return suite;
+        GraphBuilderPlugins plugins = graphBuilderPhase.getGraphBuilderPlugins();
+        iterator.add(new GraphBuilderPhase(config, plugins));
+        return new GraphBuilderSuiteInfo(suite, plugins);
     }
 
-    public void processAssumption(Assumptions newAssumptions, Assumption assumption, List<AssumptionValidAssumption> manual) {
+    public void processAssumption(Set<Assumption> newAssumptions, Assumption assumption, List<AssumptionValidAssumption> manual) {
         if (assumption != null) {
             if (assumption instanceof AssumptionValidAssumption) {
                 AssumptionValidAssumption assumptionValidAssumption = (AssumptionValidAssumption) assumption;
                 manual.add(assumptionValidAssumption);
             } else {
-                newAssumptions.record(assumption);
+                newAssumptions.add(assumption);
             }
         }
     }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleReplacements.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleReplacements.java	Wed Feb 11 16:08:50 2015 +0100
@@ -42,7 +42,7 @@
     private final Replacements graalReplacements;
 
     protected TruffleReplacements(Providers providers, SnippetReflectionProvider snippetReflection) {
-        super(providers, snippetReflection, providers.getReplacements().getAssumptions(), providers.getCodeCache().getTarget());
+        super(providers, snippetReflection, providers.getCodeCache().getTarget());
         this.graalReplacements = providers.getReplacements();
 
         registerTruffleSubstitutions();
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/AssumptionNode.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/AssumptionNode.java	Wed Feb 11 16:08:50 2015 +0100
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.truffle.nodes;
 
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.api.runtime.*;
@@ -62,14 +63,15 @@
     @Override
     public void simplify(SimplifierTool tool) {
         ValueNode assumption = getAssumption();
-        if (tool.assumptions() != null && assumption.isConstant()) {
+        Assumptions assumptions = graph().getAssumptions();
+        if (assumption.isConstant()) {
             JavaConstant c = assumption.asJavaConstant();
             assert c.getKind() == Kind.Object;
             Object object = getSnippetReflection().asObject(Object.class, c);
             OptimizedAssumption assumptionObject = (OptimizedAssumption) object;
             StructuredGraph graph = graph();
             if (assumptionObject.isValid()) {
-                tool.assumptions().record(new AssumptionValidAssumption(assumptionObject));
+                assumptions.record(new AssumptionValidAssumption(assumptionObject));
                 if (super.getReturnType().getKind() == Kind.Boolean) {
                     graph.replaceFixedWithFloating(this, ConstantNode.forBoolean(true, graph()));
                 } else {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/AssumptionValidAssumption.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/AssumptionValidAssumption.java	Wed Feb 11 16:08:50 2015 +0100
@@ -25,7 +25,7 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.truffle.*;
 
-public final class AssumptionValidAssumption extends Assumptions.Assumption {
+public final class AssumptionValidAssumption extends Assumptions.OptimisticAssumption {
 
     private static final long serialVersionUID = 2010244979610891262L;
 
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java	Wed Feb 11 16:08:50 2015 +0100
@@ -172,7 +172,7 @@
             for (int i = 0; i < frameSize; i++) {
                 primitiveArrayEntryState[i] = initialPrimitiveValue(frameDescriptor.getSlots().get(i).getKind());
             }
-            tool.getAssumptions().record(new AssumptionValidAssumption((OptimizedAssumption) frameDescriptor.getVersion()));
+            graph().getAssumptions().record(new AssumptionValidAssumption((OptimizedAssumption) frameDescriptor.getVersion()));
         }
 
         tool.createVirtualObject(virtualFrameObjectArray, objectArrayEntryState, Collections.<MonitorIdNode> emptyList());
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadFinalNode.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadFinalNode.java	Wed Feb 11 16:08:50 2015 +0100
@@ -88,7 +88,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        CompareNode compare = CompareNode.createCompareNode(graph(), Condition.EQ, condition, ConstantNode.forBoolean(true, graph()));
+        LogicNode compare = CompareNode.createCompareNode(graph(), Condition.EQ, condition, ConstantNode.forBoolean(true, graph()), tool.getConstantReflection());
         LocationIdentity locationIdentity;
         if (!location.isConstant() || location.isNullConstant()) {
             locationIdentity = LocationIdentity.ANY_LOCATION;
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadMacroNode.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadMacroNode.java	Wed Feb 11 16:08:50 2015 +0100
@@ -63,7 +63,7 @@
             } else {
                 locationIdentity = ObjectLocationIdentity.create(locationArgument.asJavaConstant());
             }
-            CompareNode compare = CompareNode.createCompareNode(Condition.EQ, conditionArgument, ConstantNode.forBoolean(true));
+            LogicNode compare = CompareNode.createCompareNode(Condition.EQ, conditionArgument, ConstantNode.forBoolean(true), tool.getConstantReflection());
             Kind returnKind = this.getTargetMethod().getSignature().getReturnKind();
             return new UnsafeLoadNode(objectArgument, offsetArgument, returnKind, locationIdentity, compare);
         }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeTypeCastMacroNode.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeTypeCastMacroNode.java	Wed Feb 11 16:08:50 2015 +0100
@@ -64,7 +64,7 @@
             } else {
                 Stamp piStamp = StampFactory.declaredTrusted(lookupJavaType, nonNullArgument.asJavaConstant().asInt() != 0);
                 ConditionAnchorNode valueAnchorNode = graph().add(
-                                new ConditionAnchorNode(CompareNode.createCompareNode(graph(), Condition.EQ, conditionArgument, ConstantNode.forBoolean(true, graph()))));
+                                new ConditionAnchorNode(CompareNode.createCompareNode(graph(), Condition.EQ, conditionArgument, ConstantNode.forBoolean(true, graph()), tool.getConstantReflection())));
                 PiNode piCast = graph().unique(new PiNode(objectArgument, piStamp, valueAnchorNode));
                 replaceAtUsages(piCast);
                 graph().replaceFixedWithFixed(this, valueAnchorNode);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/TruffleGraphBuilderPlugins.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/TruffleGraphBuilderPlugins.java	Wed Feb 11 16:08:50 2015 +0100
@@ -28,6 +28,7 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.compiler.common.calc.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.java.*;
@@ -39,6 +40,7 @@
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.truffle.*;
 import com.oracle.graal.truffle.nodes.*;
+import com.oracle.graal.truffle.nodes.arithmetic.*;
 import com.oracle.graal.truffle.nodes.frame.*;
 import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.frame.*;
@@ -49,8 +51,33 @@
 public class TruffleGraphBuilderPlugins {
     public static void registerPlugins(MetaAccessProvider metaAccess, GraphBuilderPlugins plugins) {
 
+        // OptimizedAssumption.class
+        Registration r = new Registration(plugins, metaAccess, OptimizedAssumption.class);
+        r.register1("isValid", Receiver.class, new InvocationPlugin() {
+            public boolean apply(GraphBuilderContext builder, ValueNode arg) {
+                if (arg.isConstant()) {
+                    Constant constant = arg.asConstant();
+                    OptimizedAssumption assumption = builder.getSnippetReflection().asObject(OptimizedAssumption.class, (JavaConstant) constant);
+                    builder.push(Kind.Boolean.getStackKind(), builder.append(ConstantNode.forBoolean(assumption.isValid())));
+                    builder.getAssumptions().record(new AssumptionValidAssumption(assumption));
+                } else {
+                    throw new BailoutException("assumption could not be reduced to a constant");
+                }
+                return true;
+            }
+        });
+
+        // ExactMath.class
+        r = new Registration(plugins, metaAccess, ExactMath.class);
+        r.register2("addExact", Integer.TYPE, Integer.TYPE, new InvocationPlugin() {
+            public boolean apply(GraphBuilderContext builder, ValueNode x, ValueNode y) {
+                builder.push(Kind.Int.getStackKind(), builder.append(new IntegerAddExactNode(x, y)));
+                return true;
+            }
+        });
+
         // CompilerDirectives.class
-        Registration r = new Registration(plugins, metaAccess, CompilerDirectives.class);
+        r = new Registration(plugins, metaAccess, CompilerDirectives.class);
         r.register0("inInterpreter", new InvocationPlugin() {
             public boolean apply(GraphBuilderContext builder) {
                 builder.push(Kind.Boolean.getStackKind(), builder.append(ConstantNode.forBoolean(false)));
@@ -87,7 +114,7 @@
         });
         r.register2("injectBranchProbability", double.class, boolean.class, new InvocationPlugin() {
             public boolean apply(GraphBuilderContext builder, ValueNode probability, ValueNode condition) {
-                builder.append(new BranchProbabilityNode(probability, condition));
+                builder.push(Kind.Boolean.getStackKind(), builder.append(new BranchProbabilityNode(probability, condition)));
                 return true;
             }
         });
@@ -134,6 +161,7 @@
         });
         r.register4("unsafeCast", Object.class, Class.class, boolean.class, boolean.class, new InvocationPlugin() {
             public boolean apply(GraphBuilderContext builder, ValueNode object, ValueNode clazz, ValueNode condition, ValueNode nonNull) {
+                System.out.println("unsafe cast with cond: " + condition + " clazz: " + clazz + " nonNull: " + nonNull);
                 if (clazz.isConstant() && nonNull.isConstant()) {
                     ConstantReflectionProvider constantReflection = builder.getConstantReflection();
                     ResolvedJavaType javaType = constantReflection.asJavaType(clazz.asConstant());
@@ -141,18 +169,36 @@
                         builder.push(Kind.Object, object);
                     } else {
                         Stamp piStamp = StampFactory.declaredTrusted(javaType, nonNull.asJavaConstant().asInt() != 0);
-                        ConditionAnchorNode valueAnchorNode = builder.append(new ConditionAnchorNode(CompareNode.createCompareNode(object.graph(), Condition.EQ, condition,
-                                        ConstantNode.forBoolean(true, object.graph()))));
+                        LogicNode compareNode = CompareNode.createCompareNode(object.graph(), Condition.EQ, condition, ConstantNode.forBoolean(true, object.graph()), constantReflection);
+                        boolean skipAnchor = false;
+                        if (compareNode instanceof LogicConstantNode) {
+                            LogicConstantNode logicConstantNode = (LogicConstantNode) compareNode;
+                            if (logicConstantNode.getValue()) {
+                                skipAnchor = true;
+                            }
+                        }
+                        ConditionAnchorNode valueAnchorNode = null;
+                        if (!skipAnchor) {
+                            valueAnchorNode = builder.append(new ConditionAnchorNode(compareNode));
+                        }
                         PiNode piCast = builder.append(new PiNode(object, piStamp, valueAnchorNode));
                         builder.push(Kind.Object, piCast);
                     }
                     return true;
                 }
-                // TODO: should we throw GraalInternalError.shouldNotReachHere() here?
-                return false;
+                throw GraalInternalError.shouldNotReachHere("unsafeCast arguments could not reduce to a constant: " + clazz + ", " + nonNull);
             }
         });
-        for (Kind kind : new Kind[]{Kind.Boolean, Kind.Byte, Kind.Int, Kind.Long, Kind.Float, Kind.Double, Kind.Object}) {
+
+        registerUnsafeLoadStorePlugins(r, Kind.Boolean, Kind.Byte, Kind.Int, Kind.Long, Kind.Float, Kind.Double, Kind.Object);
+
+        // CompilerDirectives.class
+        r = new Registration(plugins, metaAccess, CompilerDirectives.class);
+        registerUnsafeLoadStorePlugins(r, Kind.Boolean, Kind.Byte, Kind.Int, Kind.Short, Kind.Long, Kind.Float, Kind.Double, Kind.Object);
+    }
+
+    protected static void registerUnsafeLoadStorePlugins(Registration r, Kind... kinds) {
+        for (Kind kind : kinds) {
             String kindName = kind.getJavaName();
             kindName = toUpperCase(kindName.charAt(0)) + kindName.substring(1);
             String getName = "unsafeGet" + kindName;
@@ -178,7 +224,7 @@
                 } else {
                     locationIdentity = ObjectLocationIdentity.create(location.asJavaConstant());
                 }
-                CompareNode compare = builder.append(CompareNode.createCompareNode(Condition.EQ, condition, ConstantNode.forBoolean(true, object.graph())));
+                LogicNode compare = builder.append(CompareNode.createCompareNode(Condition.EQ, condition, ConstantNode.forBoolean(true, object.graph()), builder.getConstantReflection()));
                 builder.push(returnKind.getStackKind(), builder.append(new UnsafeLoadNode(object, offset, returnKind, locationIdentity, compare)));
                 return true;
             }
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java	Wed Feb 11 16:08:50 2015 +0100
@@ -26,7 +26,6 @@
 
 import java.util.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
@@ -39,8 +38,8 @@
 
 public class PEReadEliminationClosure extends PartialEscapeClosure<PEReadEliminationBlockState> {
 
-    public PEReadEliminationClosure(SchedulePhase schedule, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, Assumptions assumptions) {
-        super(schedule, metaAccess, constantReflection, assumptions);
+    public PEReadEliminationClosure(SchedulePhase schedule, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection) {
+        super(schedule, metaAccess, constantReflection);
     }
 
     @Override
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java	Wed Feb 11 16:08:50 2015 +0100
@@ -24,7 +24,6 @@
 
 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.compiler.common.type.*;
@@ -94,8 +93,8 @@
      */
     public static final class Final extends PartialEscapeClosure<PartialEscapeBlockState.Final> {
 
-        public Final(SchedulePhase schedule, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, Assumptions assumptions) {
-            super(schedule, metaAccess, constantReflection, assumptions);
+        public Final(SchedulePhase schedule, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection) {
+            super(schedule, metaAccess, constantReflection);
         }
 
         @Override
@@ -109,10 +108,10 @@
         }
     }
 
-    public PartialEscapeClosure(SchedulePhase schedule, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, Assumptions assumptions) {
+    public PartialEscapeClosure(SchedulePhase schedule, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection) {
         super(schedule, schedule.getCFG());
         this.usages = schedule.getCFG().graph.createNodeBitMap();
-        this.tool = new VirtualizerToolImpl(metaAccess, constantReflection, assumptions, this);
+        this.tool = new VirtualizerToolImpl(metaAccess, constantReflection, this);
     }
 
     /**
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapePhase.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapePhase.java	Wed Feb 11 16:08:50 2015 +0100
@@ -89,9 +89,9 @@
     protected Closure<?> createEffectsClosure(PhaseContext context, SchedulePhase schedule, ControlFlowGraph cfg) {
         assert schedule != null;
         if (readElimination) {
-            return new PEReadEliminationClosure(schedule, context.getMetaAccess(), context.getConstantReflection(), context.getAssumptions());
+            return new PEReadEliminationClosure(schedule, context.getMetaAccess(), context.getConstantReflection());
         } else {
-            return new PartialEscapeClosure.Final(schedule, context.getMetaAccess(), context.getConstantReflection(), context.getAssumptions());
+            return new PartialEscapeClosure.Final(schedule, context.getMetaAccess(), context.getConstantReflection());
         }
     }
 
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java	Wed Feb 11 16:08:50 2015 +0100
@@ -26,7 +26,6 @@
 
 import java.util.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
@@ -41,13 +40,11 @@
 
     private final MetaAccessProvider metaAccess;
     private final ConstantReflectionProvider constantReflection;
-    private final Assumptions assumptions;
     private final PartialEscapeClosure<?> closure;
 
-    VirtualizerToolImpl(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, Assumptions assumptions, PartialEscapeClosure<?> closure) {
+    VirtualizerToolImpl(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, PartialEscapeClosure<?> closure) {
         this.metaAccess = metaAccess;
         this.constantReflection = constantReflection;
-        this.assumptions = assumptions;
         this.closure = closure;
     }
 
@@ -66,11 +63,6 @@
         return constantReflection;
     }
 
-    @Override
-    public Assumptions getAssumptions() {
-        return assumptions;
-    }
-
     public void reset(PartialEscapeBlockState<?> newState, ValueNode newCurrent, FixedNode newPosition, GraphEffectList newEffects) {
         deleted = false;
         state = newState;
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/InstrumentationTest.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/InstrumentationTest.java	Wed Feb 11 16:08:50 2015 +0100
@@ -318,11 +318,11 @@
 
         // Use the "lite-probing" option, limited to a single pass of
         // probing and a single Instrument at each probed node. This
-        // particular test uses a shared event receiver at every
+        // particular test uses a shared event listener at every
         // lite-probed node.
-        final TestEventReceiver receiver = new TestEventReceiver();
+        final TestEventListener listener = new TestEventListener();
 
-        TestASTLiteProber astLiteProber = new TestASTLiteProber(receiver);
+        TestASTLiteProber astLiteProber = new TestASTLiteProber(listener);
         Probe.registerASTProber(astLiteProber);
 
         // Create a simple addition AST
@@ -337,9 +337,9 @@
         final CallTarget callTarget = runtime.createCallTarget(rootNode);
 
         // Check that the instrument is working as expected.
-        assertEquals(0, receiver.counter);
+        assertEquals(0, listener.counter);
         callTarget.call();
-        assertEquals(2, receiver.counter);
+        assertEquals(2, listener.counter);
 
         // Check that you can't probe a node that's already received a probeLite() call
         try {
@@ -409,7 +409,7 @@
         }
 
         // Use reflection to check that each WrapperNode has a ProbeLiteNode with a
-        // SimpleEventReceiver
+        // SimpleEventListener
         try {
             java.lang.reflect.Field probeNodeField = leftWrapper.getClass().getDeclaredField("probeNode");
 
@@ -420,15 +420,15 @@
             // hack: Since ProbeLiteNode is not visible, we do a string compare here
             assertTrue(probeNode.getClass().toString().endsWith("ProbeLiteNode"));
 
-            // Now we do the same to check the type of the eventReceiver in ProbeLiteNode
-            java.lang.reflect.Field eventReceiverField = probeNode.getClass().getDeclaredField("eventReceiver");
-            eventReceiverField.setAccessible(true);
-            TruffleEventReceiver eventReceiver = (TruffleEventReceiver) eventReceiverField.get(probeNode);
-            assertTrue(eventReceiver instanceof SimpleEventReceiver);
+            // Now we do the same to check the type of the eventListener in ProbeLiteNode
+            java.lang.reflect.Field eventListenerField = probeNode.getClass().getDeclaredField("eventListener");
+            eventListenerField.setAccessible(true);
+            TruffleEventListener eventListener = (TruffleEventListener) eventListenerField.get(probeNode);
+            assertTrue(eventListener instanceof SimpleEventListener);
 
             // Reset accessibility
             probeNodeField.setAccessible(false);
-            eventReceiverField.setAccessible(false);
+            eventListenerField.setAccessible(false);
 
         } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
             fail();
@@ -588,7 +588,7 @@
         public final Instrument instrument;
 
         public TestCounter() {
-            instrument = Instrument.create(new SimpleEventReceiver() {
+            instrument = Instrument.create(new SimpleEventListener() {
 
                 @Override
                 public void enter(Node node, VirtualFrame frame) {
@@ -641,19 +641,19 @@
     }
 
     /**
-     * "lite-probes" every value node with a shared event receiver.
+     * "lite-probes" every value node with a shared event listener.
      */
     private static final class TestASTLiteProber implements NodeVisitor, ASTProber {
-        private final TruffleEventReceiver eventReceiver;
+        private final TruffleEventListener eventListener;
 
-        public TestASTLiteProber(SimpleEventReceiver simpleEventReceiver) {
-            this.eventReceiver = simpleEventReceiver;
+        public TestASTLiteProber(SimpleEventListener simpleEventListener) {
+            this.eventListener = simpleEventListener;
         }
 
         public boolean visit(Node node) {
             if (node instanceof TestValueNode) {
                 final TestLanguageNode testNode = (TestValueNode) node;
-                testNode.probeLite(eventReceiver);
+                testNode.probeLite(eventListener);
             }
             return true;
         }
@@ -667,7 +667,7 @@
      * Counts the number of "enter" events at probed nodes.
      *
      */
-    static final class TestEventReceiver extends SimpleEventReceiver {
+    static final class TestEventListener extends SimpleEventListener {
 
         public int counter = 0;
 
@@ -692,7 +692,7 @@
             // where we want to count executions.
             // it will get copied when ASTs cloned, so
             // keep the count in this outer class.
-            probe.attach(Instrument.create(new SimpleEventReceiver() {
+            probe.attach(Instrument.create(new SimpleEventListener() {
 
                 @Override
                 public void enter(Node node, VirtualFrame frame) {
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrument.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrument.java	Wed Feb 11 16:08:50 2015 +0100
@@ -33,37 +33,37 @@
 // TODO (mlvdv) migrate some of this to external documentation.
 /**
  * A dynamically added/removed binding between a {@link Probe}, which provides notification of
- * {@linkplain TruffleEventReceiver execution events} taking place at a {@link Node} in a Guest
- * Language (GL) Truffle AST, and a {@linkplain TruffleEventReceiver receiver}, which consumes
+ * {@linkplain TruffleEventListener execution events} taking place at a {@link Node} in a Guest
+ * Language (GL) Truffle AST, and a {@linkplain TruffleEventListener listener}, which consumes
  * notifications on behalf of an external tool.
  * <p>
  * <h4>Summary: How to "instrument" an AST location:</h4>
  * <ol>
- * <li>Create an implementation of {@link TruffleEventReceiver} that responds to events on behalf of
+ * <li>Create an implementation of {@link TruffleEventListener} that responds to events on behalf of
  * a tool.</li>
- * <li>Create an Instrument via factory method {@link Instrument#create(TruffleEventReceiver)}.</li>
+ * <li>Create an Instrument via factory method {@link Instrument#create(TruffleEventListener)}.</li>
  * <li>"Attach" the Instrument to a Probe via {@link Probe#attach(Instrument)}, at which point event
- * notifications begin to arrive at the receiver.</li>
+ * notifications begin to arrive at the listener.</li>
  * <li>When no longer needed, "detach" the Instrument via {@link Instrument#dispose()}, at which
- * point event notifications to the receiver cease, and the Instrument becomes unusable.</li>
+ * point event notifications to the listener cease, and the Instrument becomes unusable.</li>
  * </ol>
  * <p>
- * <h4>Options for creating receivers:</h4>
+ * <h4>Options for creating listeners:</h4>
  * <p>
  * <ol>
- * <li>Implement the interface {@link TruffleEventReceiver}. The event handling methods account for
+ * <li>Implement the interface {@link TruffleEventListener}. The event handling methods account for
  * both the entry into an AST node (about to call) and several possible kinds of exit from an AST
  * node (just returned).</li>
- * <li>Extend {@link DefaultEventReceiver}, which provides a no-op implementation of every
- * {@link TruffleEventReceiver} method; override the methods of interest.</li>
- * <li>Extend {@link SimpleEventReceiver}, where return values are ignored so only two methods (for
+ * <li>Extend {@link DefaultEventListener}, which provides a no-op implementation of every
+ * {@link TruffleEventListener} method; override the methods of interest.</li>
+ * <li>Extend {@link SimpleEventListener}, where return values are ignored so only two methods (for
  * "enter" and "return") will notify all events.</li>
  * </ol>
  * <p>
- * <h4>General guidelines for receiver implementation:</h4>
+ * <h4>General guidelines for listener implementation:</h4>
  * <p>
- * When an Instrument is attached to a Probe, the receiver effectively becomes part of the executing
- * GL program; performance can be affected by the receiver's implementation.
+ * When an Instrument is attached to a Probe, the listener effectively becomes part of the executing
+ * GL program; performance can be affected by the listener's implementation.
  * <ul>
  * <li>Do not store {@link Frame} or {@link Node} references in fields.</li>
  * <li>Prefer {@code final} fields and (where performance is important) short methods.</li>
@@ -71,7 +71,7 @@
  * possible through code that is expected to be inlined, since this incurs no runtime overhead. When
  * access to frame data is needed, substitute a more expensive {@linkplain Frame#materialize()
  * materialized} representation of the frame.</li>
- * <li>If a receiver calls back to its tool during event handling, and if performance is an issue,
+ * <li>If a listener calls back to its tool during event handling, and if performance is an issue,
  * then this should be through a final "callback" field in the instrument, and the called methods
  * should be minimal.</li>
  * <li>On the other hand, implementations should prevent Truffle from inlining beyond a reasonable
@@ -85,14 +85,14 @@
  * <p>
  * <h4>Allowing for AST cloning:</h4>
  * <p>
- * Truffle routinely <em>clones</em> ASTs, which has consequences for receiver implementation.
+ * Truffle routinely <em>clones</em> ASTs, which has consequences for listener implementation.
  * <ul>
  * <li>Even though a {@link Probe} is uniquely associated with a particular location in the
  * executing Guest Language program, execution events at that location will in general be
  * implemented by different {@link Node} instances, i.e. <em>clones</em> of the originally probed
  * node.</li>
  * <li>Because of <em>cloning</em> the {@link Node} supplied with notifications to a particular
- * receiver will vary, but because they all represent the same GL program location the events should
+ * listener will vary, but because they all represent the same GL program location the events should
  * be treated as equivalent for most purposes.</li>
  * </ul>
  * <p>
@@ -107,8 +107,8 @@
  * </ul>
  * <li>Some global information is available, for example the execution
  * {@linkplain TruffleRuntime#iterateFrames(FrameInstanceVisitor) stack}.</li>
- * <li>Additional information needed by a receiver could be stored when created, preferably
- * {@code final} of course. For example, a reference to the {@link Probe} to which the receiver's
+ * <li>Additional information needed by a listener could be stored when created, preferably
+ * {@code final} of course. For example, a reference to the {@link Probe} to which the listener's
  * Instrument has been attached would give access to its corresponding
  * {@linkplain Probe#getProbedSourceSection() source location} or to the collection of
  * {@linkplain SyntaxTag tags} currently applied to the Probe.</li>
@@ -129,43 +129,43 @@
  * which can trigger deoptimization.</li>
  * </ul>
  * <p>
- * <h4>Sharing receivers:</h4>
+ * <h4>Sharing listeners:</h4>
  * <p>
- * Although an Instrument may only be attached to a single Probe, a receiver can be shared among
+ * Although an Instrument may only be attached to a single Probe, a listener can be shared among
  * multiple Instruments. This can be useful for observing events that might happen at different
  * locations in a single AST, for example all assignments to a particular variable. In this case a
  * new Instrument would be created and attached at each assignment node, but all the Instruments
- * would be created with the same receiver.
+ * would be created with the same listener.
  * <p>
  * <strong>Disclaimer:</strong> experimental; under development.
  *
  * @see Probe
- * @see TruffleEventReceiver
+ * @see TruffleEventListener
  */
 public final class Instrument {
 
     /**
-     * Creates an instrument that will route execution events to a receiver.
+     * Creates an instrument that will route execution events to a listener.
      *
-     * @param receiver a receiver for event generated by the instrument
+     * @param listener a listener for event generated by the instrument
      * @param instrumentInfo optional description of the instrument's role
      * @return a new instrument, ready for attachment at a probe
      */
-    public static Instrument create(TruffleEventReceiver receiver, String instrumentInfo) {
-        return new Instrument(receiver, instrumentInfo);
+    public static Instrument create(TruffleEventListener listener, String instrumentInfo) {
+        return new Instrument(listener, instrumentInfo);
     }
 
     /**
-     * Creates an instrument that will route execution events to a receiver.
+     * Creates an instrument that will route execution events to a listener.
      */
-    public static Instrument create(TruffleEventReceiver receiver) {
-        return new Instrument(receiver, null);
+    public static Instrument create(TruffleEventListener listener) {
+        return new Instrument(listener, null);
     }
 
     /**
-     * Tool-supplied receiver of events.
+     * Tool-supplied listener for events.
      */
-    private final TruffleEventReceiver toolEventreceiver;
+    private final TruffleEventListener toolEventListener;
 
     /**
      * Optional documentation, mainly for debugging.
@@ -179,8 +179,8 @@
 
     private Probe probe = null;
 
-    private Instrument(TruffleEventReceiver receiver, String instrumentInfo) {
-        this.toolEventreceiver = receiver;
+    private Instrument(TruffleEventListener listener, String instrumentInfo) {
+        this.toolEventListener = listener;
         this.instrumentInfo = instrumentInfo;
     }
 
@@ -240,7 +240,7 @@
     }
 
     @NodeInfo(cost = NodeCost.NONE)
-    final class InstrumentNode extends Node implements TruffleEventReceiver, InstrumentationNode {
+    final class InstrumentNode extends Node implements TruffleEventListener, InstrumentationNode {
 
         @Child private InstrumentNode nextInstrument;
 
@@ -287,28 +287,28 @@
         }
 
         public void enter(Node node, VirtualFrame frame) {
-            Instrument.this.toolEventreceiver.enter(node, frame);
+            Instrument.this.toolEventListener.enter(node, frame);
             if (nextInstrument != null) {
                 nextInstrument.enter(node, frame);
             }
         }
 
         public void returnVoid(Node node, VirtualFrame frame) {
-            Instrument.this.toolEventreceiver.returnVoid(node, frame);
+            Instrument.this.toolEventListener.returnVoid(node, frame);
             if (nextInstrument != null) {
                 nextInstrument.returnVoid(node, frame);
             }
         }
 
         public void returnValue(Node node, VirtualFrame frame, Object result) {
-            Instrument.this.toolEventreceiver.returnValue(node, frame, result);
+            Instrument.this.toolEventListener.returnValue(node, frame, result);
             if (nextInstrument != null) {
                 nextInstrument.returnValue(node, frame, result);
             }
         }
 
         public void returnExceptional(Node node, VirtualFrame frame, Exception exception) {
-            Instrument.this.toolEventreceiver.returnExceptional(node, frame, exception);
+            Instrument.this.toolEventListener.returnExceptional(node, frame, exception);
             if (nextInstrument != null) {
                 nextInstrument.returnExceptional(node, frame, exception);
             }
@@ -318,7 +318,7 @@
             if (Instrument.this.instrumentInfo != null) {
                 return Instrument.this.instrumentInfo;
             }
-            return toolEventreceiver.getClass().getSimpleName();
+            return toolEventListener.getClass().getSimpleName();
         }
     }
 
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Probe.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Probe.java	Wed Feb 11 16:08:50 2015 +0100
@@ -40,7 +40,7 @@
  * is intended to persist at the location, even if the specific node instance is
  * {@linkplain Node#replace(Node) replaced}.
  * <p>
- * The effect of a binding is to intercept {@linkplain TruffleEventReceiver execution events}
+ * The effect of a binding is to intercept {@linkplain TruffleEventListener execution events}
  * arriving at the node and notify each attached {@link Instrument} before execution is allowed to
  * proceed to the child.
  * <p>
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeNode.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeNode.java	Wed Feb 11 16:08:50 2015 +0100
@@ -35,7 +35,7 @@
 /**
  * Implementation interfaces and classes for attaching {@link Probe}s to {@link WrapperNode}s.
  */
-public abstract class ProbeNode extends Node implements TruffleEventReceiver, InstrumentationNode {
+public abstract class ProbeNode extends Node implements TruffleEventListener, InstrumentationNode {
 
     /**
      * A node that can be inserted into a Truffle AST, and which enables {@linkplain Instrument
@@ -85,14 +85,14 @@
 
         /**
          * Gets the node being "wrapped", i.e. the AST node for which
-         * {@linkplain TruffleEventReceiver execution events} will be reported through the
+         * {@linkplain TruffleEventListener execution events} will be reported through the
          * Instrumentation Framework.
          */
         Node getChild();
 
         /**
          * Gets the {@link Probe} responsible for installing this wrapper; none if the wrapper
-         * installed via {@linkplain Node#probeLite(TruffleEventReceiver) "lite-Probing"}.
+         * installed via {@linkplain Node#probeLite(TruffleEventListener) "lite-Probing"}.
          */
         Probe getProbe();
 
@@ -120,8 +120,8 @@
      * Creates a new {@link ProbeLiteNode} associated with, and attached to, a Guest Language
      * specific instance of {@link WrapperNode}.
      */
-    public static void insertProbeLite(WrapperNode wrapper, TruffleEventReceiver eventReceiver) {
-        final ProbeLiteNode probeLiteNode = new ProbeLiteNode(eventReceiver);
+    public static void insertProbeLite(WrapperNode wrapper, TruffleEventListener eventListener) {
+        final ProbeLiteNode probeLiteNode = new ProbeLiteNode(eventListener);
         wrapper.insertProbe(probeLiteNode);
     }
 
@@ -277,15 +277,15 @@
     /**
      * Implementation of a probe that only ever has a single "instrument" associated with it. No
      * {@link Instrument} is ever created; instead this method simply delegates the various enter
-     * and return events to a {@link TruffleEventReceiver} passed in during construction.
+     * and return events to a {@link TruffleEventListener} passed in during construction.
      */
     @NodeInfo(cost = NodeCost.NONE)
     private static final class ProbeLiteNode extends ProbeNode {
 
-        private final TruffleEventReceiver eventReceiver;
+        private final TruffleEventListener eventListener;
 
-        private ProbeLiteNode(TruffleEventReceiver eventReceiver) {
-            this.eventReceiver = eventReceiver;
+        private ProbeLiteNode(TruffleEventListener eventListener) {
+            this.eventListener = eventListener;
         }
 
         @Override
@@ -306,19 +306,19 @@
         }
 
         public void enter(Node node, VirtualFrame frame) {
-            eventReceiver.enter(node, frame);
+            eventListener.enter(node, frame);
         }
 
         public void returnVoid(Node node, VirtualFrame frame) {
-            eventReceiver.returnVoid(node, frame);
+            eventListener.returnVoid(node, frame);
         }
 
         public void returnValue(Node node, VirtualFrame frame, Object result) {
-            eventReceiver.returnValue(node, frame, result);
+            eventListener.returnValue(node, frame, result);
         }
 
         public void returnExceptional(Node node, VirtualFrame frame, Exception exception) {
-            eventReceiver.returnExceptional(node, frame, exception);
+            eventListener.returnExceptional(node, frame, exception);
         }
 
         public String instrumentationInfo() {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/TruffleEventListener.java	Wed Feb 11 16:08:50 2015 +0100
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2013, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.truffle.api.instrument;
+
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.nodes.*;
+
+/**
+ * A listener of Truffle AST runtime execution events that can collect information and possibly
+ * intervene on behalf of an external tool.
+ */
+public interface TruffleEventListener {
+
+    /**
+     * Receive notification that an AST node's execute method is about to be called.
+     */
+    void enter(Node node, VirtualFrame frame);
+
+    /**
+     * Receive notification that an AST Node's {@code void}-valued execute method has just returned.
+     */
+    void returnVoid(Node node, VirtualFrame frame);
+
+    /**
+     * Receive notification that an AST Node'sexecute method has just returned a value (boxed if
+     * primitive).
+     */
+    void returnValue(Node node, VirtualFrame frame, Object result);
+
+    /**
+     * Receive notification that an AST Node's execute method has just thrown an exception.
+     */
+    void returnExceptional(Node node, VirtualFrame frame, Exception exception);
+
+}
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/TruffleEventReceiver.java	Wed Feb 11 15:53:27 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2013, 2014, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.truffle.api.instrument;
-
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-
-/**
- * A receiver of Truffle AST runtime execution events that can collect information and possibly
- * intervene on behalf of an external tool.
- */
-public interface TruffleEventReceiver {
-
-    /**
-     * Receive notification that an AST node's execute method is about to be called.
-     */
-    void enter(Node node, VirtualFrame frame);
-
-    /**
-     * Receive notification that an AST Node's {@code void}-valued execute method has just returned.
-     */
-    void returnVoid(Node node, VirtualFrame frame);
-
-    /**
-     * Receive notification that an AST Node'sexecute method has just returned a value (boxed if
-     * primitive).
-     */
-    void returnValue(Node node, VirtualFrame frame, Object result);
-
-    /**
-     * Receive notification that an AST Node's execute method has just thrown an exception.
-     */
-    void returnExceptional(Node node, VirtualFrame frame, Exception exception);
-
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/DefaultEventListener.java	Wed Feb 11 16:08:50 2015 +0100
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2014, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.truffle.api.instrument.impl;
+
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.instrument.*;
+import com.oracle.truffle.api.nodes.*;
+
+/**
+ * A listener for AST {@linkplain TruffleEventListener execution events} that provides a no-op
+ * implementation of every event.
+ */
+public class DefaultEventListener implements TruffleEventListener {
+
+    public void enter(Node node, VirtualFrame frame) {
+    }
+
+    public void returnVoid(Node node, VirtualFrame frame) {
+    }
+
+    public void returnValue(Node node, VirtualFrame frame, Object result) {
+    }
+
+    public void returnExceptional(Node node, VirtualFrame frame, Exception exception) {
+    }
+
+}
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/DefaultEventReceiver.java	Wed Feb 11 15:53:27 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2014, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.truffle.api.instrument.impl;
-
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.instrument.*;
-import com.oracle.truffle.api.nodes.*;
-
-/**
- * A receiver for AST {@linkplain TruffleEventReceiver execution events} that provides a no-op
- * implementation of every event.
- */
-public class DefaultEventReceiver implements TruffleEventReceiver {
-
-    public void enter(Node node, VirtualFrame frame) {
-    }
-
-    public void returnVoid(Node node, VirtualFrame frame) {
-    }
-
-    public void returnValue(Node node, VirtualFrame frame, Object result) {
-    }
-
-    public void returnExceptional(Node node, VirtualFrame frame, Exception exception) {
-    }
-
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/SimpleEventListener.java	Wed Feb 11 16:08:50 2015 +0100
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2014, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.truffle.api.instrument.impl;
+
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.instrument.*;
+import com.oracle.truffle.api.nodes.*;
+
+/**
+ * An abstract listener for AST {@linkplain TruffleEventListener execution events} that ignores
+ * return values and supports handling all events by overriding only two methods:
+ * <ul>
+ * <li>{@link #enter(Node, VirtualFrame)}, and</li>
+ * <li>{@link #returnAny(Node, VirtualFrame)}.</li>
+ * </ul>
+ */
+public abstract class SimpleEventListener implements TruffleEventListener {
+
+    public void enter(Node node, VirtualFrame frame) {
+    }
+
+    /**
+     * Receive notification that one of an AST Node's execute methods has just returned by any
+     * means: with or without a return value (ignored) or via exception (ignored).
+     *
+     * @param node
+     * @param frame
+     */
+    public void returnAny(Node node, VirtualFrame frame) {
+    }
+
+    public final void returnVoid(Node node, VirtualFrame frame) {
+        returnAny(node, frame);
+    }
+
+    public final void returnValue(Node node, VirtualFrame frame, Object result) {
+        returnAny(node, frame);
+    }
+
+    public final void returnExceptional(Node node, VirtualFrame frame, Exception e) {
+        returnAny(node, frame);
+    }
+
+}
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/SimpleEventReceiver.java	Wed Feb 11 15:53:27 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2014, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.truffle.api.instrument.impl;
-
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.instrument.*;
-import com.oracle.truffle.api.nodes.*;
-
-/**
- * An abstract receiver for AST {@linkplain TruffleEventReceiver execution events} that ignores
- * return values and supports handling all events by overriding only two methods:
- * <ul>
- * <li>{@link #enter(Node, VirtualFrame)}, and</li>
- * <li>{@link #returnAny(Node, VirtualFrame)}.</li>
- * </ul>
- */
-public abstract class SimpleEventReceiver implements TruffleEventReceiver {
-
-    public void enter(Node node, VirtualFrame frame) {
-    }
-
-    /**
-     * Receive notification that one of an AST Node's execute methods has just returned by any
-     * means: with or without a return value (ignored) or via exception (ignored).
-     *
-     * @param node
-     * @param frame
-     */
-    public void returnAny(Node node, VirtualFrame frame) {
-    }
-
-    public final void returnVoid(Node node, VirtualFrame frame) {
-        returnAny(node, frame);
-    }
-
-    public final void returnValue(Node node, VirtualFrame frame, Object result) {
-        returnAny(node, frame);
-    }
-
-    public final void returnExceptional(Node node, VirtualFrame frame, Exception e) {
-        returnAny(node, frame);
-    }
-
-}
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java	Wed Feb 11 16:08:50 2015 +0100
@@ -504,16 +504,16 @@
      * its parent; the wrapper node must be provided by implementations of
      * {@link #createWrapperNode()}.
      * <p>
-     * Unlike {@link #probe()}, once {@link #probeLite(TruffleEventReceiver)} is called at a node,
+     * Unlike {@link #probe()}, once {@link #probeLite(TruffleEventListener)} is called at a node,
      * no additional probing can be added and no additional instrumentation can be attached.
      * <p>
      * This restricted form of instrumentation is intended for special cases where only one kind of
      * instrumentation is desired, and for which performance is a concern
      *
-     * @param eventReceiver
+     * @param eventListener
      * @throws ProbeException (unchecked) when a probe cannot be created, leaving the AST unchanged
      */
-    public final void probeLite(TruffleEventReceiver eventReceiver) {
+    public final void probeLite(TruffleEventListener eventListener) {
 
         if (this instanceof WrapperNode) {
             throw new ProbeException(ProbeFailure.Reason.WRAPPER_NODE, null, this, null);
@@ -545,7 +545,7 @@
         }
 
         // Connect it to a Probe
-        ProbeNode.insertProbeLite(wrapper, eventReceiver);
+        ProbeNode.insertProbeLite(wrapper, eventListener);
 
         // Replace this node in the AST with the wrapper
         this.replace(wrapperNode);
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/tools/CoverageTracker.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/tools/CoverageTracker.java	Wed Feb 11 16:08:50 2015 +0100
@@ -29,7 +29,6 @@
 import java.util.Map.Entry;
 import java.util.concurrent.atomic.*;
 
-import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.api.instrument.*;
 import com.oracle.truffle.api.instrument.impl.*;
@@ -52,7 +51,7 @@
  * <p>
  * <ul>
  * <li>"Execution call" on a node is is defined as invocation of a node method that is instrumented
- * to produce the event {@link TruffleEventReceiver#enter(Node, VirtualFrame)};</li>
+ * to produce the event {@link TruffleEventListener#enter(Node, VirtualFrame)};</li>
  * <li>Execution calls are tabulated only at <em>instrumented</em> nodes, i.e. those for which
  * {@linkplain Node#isInstrumentable() isInstrumentable() == true};</li>
  * <li>Execution calls are tabulated only at nodes present in the AST when originally created;
@@ -75,13 +74,13 @@
 public final class CoverageTracker extends InstrumentationTool {
 
     /** Counting data. */
-    private final Map<LineLocation, CoverageCounter> counters = new HashMap<>();
+    private final Map<LineLocation, CoverageRecord> coverageMap = new HashMap<>();
 
-    /** For disposal. */
+    /** Needed for disposal. */
     private final List<Instrument> instruments = new ArrayList<>();
 
     /**
-     * Counting is restricted to nodes holding this tag.
+     * Coverage counting is restricted to nodes holding this tag.
      */
     private final SyntaxTag countingTag;
 
@@ -112,7 +111,7 @@
 
     @Override
     protected void internalReset() {
-        counters.clear();
+        coverageMap.clear();
     }
 
     @Override
@@ -142,22 +141,21 @@
          * every line associated with an appropriately tagged AST node; iterable in order of source
          * name, then line number.
          */
-        final TreeSet<Entry<LineLocation, CoverageCounter>> entries = new TreeSet<>(new LineLocationEntryComparator());
+        final TreeSet<Entry<LineLocation, CoverageRecord>> entries = new TreeSet<>(new LineLocationEntryComparator());
 
-        final Map<Source, Long[]> results = new HashMap<>();
-
-        for (Entry<LineLocation, CoverageCounter> entry : counters.entrySet()) {
+        for (Entry<LineLocation, CoverageRecord> entry : coverageMap.entrySet()) {
             entries.add(entry);
         }
+        final Map<Source, Long[]> result = new HashMap<>();
         Source curSource = null;
         Long[] curLineTable = null;
-        for (Entry<LineLocation, CoverageCounter> entry : entries) {
+        for (Entry<LineLocation, CoverageRecord> entry : entries) {
             final LineLocation key = entry.getKey();
             final Source source = key.getSource();
             final int lineNo = key.getLineNumber();
             if (source != curSource) {
                 if (curSource != null) {
-                    results.put(curSource, curLineTable);
+                    result.put(curSource, curLineTable);
                 }
                 curSource = source;
                 curLineTable = new Long[source.getLineCount()];
@@ -165,9 +163,9 @@
             curLineTable[lineNo - 1] = entry.getValue().count.longValue();
         }
         if (curSource != null) {
-            results.put(curSource, curLineTable);
+            result.put(curSource, curLineTable);
         }
-        return results;
+        return result;
     }
 
     /**
@@ -183,14 +181,14 @@
          * every line associated with an appropriately tagged AST node; iterable in order of source
          * name, then line number.
          */
-        final TreeSet<Entry<LineLocation, CoverageCounter>> entries = new TreeSet<>(new LineLocationEntryComparator());
+        final TreeSet<Entry<LineLocation, CoverageRecord>> entries = new TreeSet<>(new LineLocationEntryComparator());
 
-        for (Entry<LineLocation, CoverageCounter> entry : counters.entrySet()) {
+        for (Entry<LineLocation, CoverageRecord> entry : coverageMap.entrySet()) {
             entries.add(entry);
         }
         Source curSource = null;
         int curLineNo = 1;
-        for (Entry<LineLocation, CoverageCounter> entry : entries) {
+        for (Entry<LineLocation, CoverageRecord> entry : entries) {
             final LineLocation key = entry.getKey();
             final Source source = key.getSource();
             final int lineNo = key.getLineNumber();
@@ -228,9 +226,9 @@
     }
 
     /**
-     * A receiver for events at each instrumented AST location. This receiver counts
-     * "execution calls" to the instrumented node and is <em>stateful</em>. State in receivers must
-     * be considered carefully since ASTs, along with all instrumentation (including event receivers
+     * A listener for events at each instrumented AST location. This listener counts
+     * "execution calls" to the instrumented node and is <em>stateful</em>. State in listeners must
+     * be considered carefully since ASTs, along with all instrumentation (including event listener
      * such as this) are routinely cloned by the Truffle runtime. AST cloning is <em>shallow</em>
      * (for non- {@link Child} nodes), so in this case the actual count <em>is shared</em> among all
      * the clones; the count is also held in a table indexed by source line.
@@ -238,7 +236,7 @@
      * In contrast, a primitive field would <em>not</em> be shared among clones and resulting counts
      * would not be accurate.
      */
-    private final class CoverageEventReceiver extends DefaultEventReceiver {
+    private final class CoverageEventListener extends DefaultEventListener {
 
         /**
          * Shared by all clones of the associated instrument and by the table of counters for the
@@ -246,12 +244,11 @@
          */
         private final AtomicLong count;
 
-        CoverageEventReceiver(AtomicLong count) {
+        CoverageEventListener(AtomicLong count) {
             this.count = count;
         }
 
         @Override
-        @TruffleBoundary
         public void enter(Node node, VirtualFrame frame) {
             if (isEnabled()) {
                 count.getAndIncrement();
@@ -259,9 +256,9 @@
         }
     }
 
-    private static final class LineLocationEntryComparator implements Comparator<Entry<LineLocation, CoverageCounter>> {
+    private static final class LineLocationEntryComparator implements Comparator<Entry<LineLocation, CoverageRecord>> {
 
-        public int compare(Entry<LineLocation, CoverageCounter> e1, Entry<LineLocation, CoverageCounter> e2) {
+        public int compare(Entry<LineLocation, CoverageRecord> e1, Entry<LineLocation, CoverageRecord> e2) {
             return LineLocation.COMPARATOR.compare(e1.getKey(), e2.getKey());
         }
     }
@@ -279,35 +276,37 @@
                 if (srcSection == null) {
                     // TODO (mlvdv) report this?
                 } else {
+                    // Get the source line where the
                     final LineLocation lineLocation = srcSection.getLineLocation();
-                    CoverageCounter counter = counters.get(lineLocation);
-                    if (counter != null) {
+                    CoverageRecord record = coverageMap.get(lineLocation);
+                    if (record != null) {
                         // Another node starts on same line; count only the first (textually)
-                        if (srcSection.getCharIndex() > counter.srcSection.getCharIndex()) {
-                            // Counter already in place, corresponds to code earlier on line
+                        if (srcSection.getCharIndex() > record.srcSection.getCharIndex()) {
+                            // Record already in place, corresponds to code earlier on line
                             return;
                         } else {
-                            // Counter already in place, corresponds to later code; replace it
-                            counter.instrument.dispose();
+                            // Record already in place, corresponds to later code; replace it
+                            record.instrument.dispose();
                         }
                     }
                     final AtomicLong count = new AtomicLong();
-                    final CoverageEventReceiver eventReceiver = new CoverageEventReceiver(count);
-                    final Instrument instrument = Instrument.create(eventReceiver, CoverageTracker.class.getSimpleName());
+                    final CoverageEventListener eventListener = new CoverageEventListener(count);
+                    final Instrument instrument = Instrument.create(eventListener, CoverageTracker.class.getSimpleName());
                     instruments.add(instrument);
                     probe.attach(instrument);
-                    counters.put(lineLocation, new CoverageCounter(srcSection, instrument, count));
+                    coverageMap.put(lineLocation, new CoverageRecord(srcSection, instrument, count));
                 }
             }
         }
     }
 
-    private class CoverageCounter {
-        final SourceSection srcSection;
-        final Instrument instrument;
+    private class CoverageRecord {
+
+        final SourceSection srcSection; // The text of the code being counted
+        final Instrument instrument;  // The attached Instrument, in case need to remove.
         final AtomicLong count;
 
-        CoverageCounter(SourceSection srcSection, Instrument instrument, AtomicLong count) {
+        CoverageRecord(SourceSection srcSection, Instrument instrument, AtomicLong count) {
             this.srcSection = srcSection;
             this.instrument = instrument;
             this.count = count;
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/tools/NodeExecCounter.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/tools/NodeExecCounter.java	Wed Feb 11 16:08:50 2015 +0100
@@ -49,7 +49,7 @@
  * <p>
  * <ul>
  * <li>"Execution call" on a node is is defined as invocation of a node method that is instrumented
- * to produce the event {@link TruffleEventReceiver#enter(Node, VirtualFrame)};</li>
+ * to produce the event {@link TruffleEventListener#enter(Node, VirtualFrame)};</li>
  * <li>Execution calls are tabulated only at <em>instrumented</em> nodes, i.e. those for which
  * {@linkplain Node#isInstrumentable() isInstrumentable() == true};</li>
  * <li>Execution calls are tabulated only at nodes present in the AST when originally created;
@@ -92,26 +92,38 @@
     }
 
     /**
-     * Receiver for events at instrumented nodes. Counts are maintained in a shared table, so the
-     * receiver is stateless and can be shared by every {@link Instrument}.
+     * Listener for events at instrumented nodes. Counts are maintained in a shared table, so the
+     * listener is stateless and can be shared by every {@link Instrument}.
      */
-    private final TruffleEventReceiver eventReceiver = new DefaultEventReceiver() {
+    private final TruffleEventListener eventListener = new DefaultEventListener() {
         @Override
         public void enter(Node node, VirtualFrame frame) {
-            internalReceive(node);
+            if (isEnabled()) {
+                final Class<?> nodeClass = node.getClass();
+                /*
+                 * Everything up to here is inlined by Truffle compilation. Delegate the next part
+                 * to a method behind an inlining boundary.
+                 *
+                 * Note that it is not permitted to pass a {@link VirtualFrame} across an inlining
+                 * boundary; they are truly virtual in inlined code.
+                 */
+                AtomicLong nodeCounter = getCounter(nodeClass);
+                nodeCounter.getAndIncrement();
+            }
         }
 
+        /**
+         * Mark this method as a boundary that will stop Truffle inlining, which should not be
+         * allowed to inline the hash table method or any other complex library code.
+         */
         @TruffleBoundary
-        private void internalReceive(Node node) {
-            if (isEnabled()) {
-                final Class<?> nodeClass = node.getClass();
-                AtomicLong nodeCounter = counters.get(nodeClass);
-                if (nodeCounter == null) {
-                    nodeCounter = new AtomicLong();
-                    counters.put(nodeClass, nodeCounter);
-                }
-                nodeCounter.getAndIncrement();
+        private AtomicLong getCounter(Class<?> nodeClass) {
+            AtomicLong nodeCounter = counters.get(nodeClass);
+            if (nodeCounter == null) {
+                nodeCounter = new AtomicLong();
+                counters.put(nodeClass, nodeCounter);
             }
+            return nodeCounter;
         }
     };
 
@@ -268,7 +280,7 @@
 
             if (node.isInstrumentable()) {
                 try {
-                    final Instrument instrument = Instrument.create(eventReceiver, "NodeExecCounter");
+                    final Instrument instrument = Instrument.create(eventListener, "NodeExecCounter");
                     instruments.add(instrument);
                     node.probe().attach(instrument);
                 } catch (ProbeException ex) {
@@ -292,7 +304,7 @@
         @Override
         public void probeTaggedAs(Probe probe, SyntaxTag tag, Object tagValue) {
             if (countingTag == tag) {
-                final Instrument instrument = Instrument.create(eventReceiver, NodeExecCounter.class.getSimpleName());
+                final Instrument instrument = Instrument.create(eventListener, NodeExecCounter.class.getSimpleName());
                 instruments.add(instrument);
                 probe.attach(instrument);
             }
--- a/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/instrument/SLInstrumentTestRunner.java	Wed Feb 11 15:53:27 2015 +0100
+++ b/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/instrument/SLInstrumentTestRunner.java	Wed Feb 11 16:08:50 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -218,8 +218,8 @@
 
                 // Attach an instrument to every probe tagged as an assignment
                 for (Probe probe : Probe.findProbesTaggedAs(StandardSyntaxTag.ASSIGNMENT)) {
-                    SLPrintAssigmentValueReciever slPrintAssigmentValueReceiver = new SLPrintAssigmentValueReciever(printer);
-                    probe.attach(Instrument.create(slPrintAssigmentValueReceiver, "SL print assignment value"));
+                    SLPrintAssigmentValueListener slPrintAssigmentValueListener = new SLPrintAssigmentValueListener(printer);
+                    probe.attach(Instrument.create(slPrintAssigmentValueListener, "SL print assignment value"));
                 }
 
                 SLFunction main = slContext.getFunctionRegistry().lookup("main");
@@ -271,16 +271,16 @@
     }
 
     /**
-     * This sample instrument receiver provides prints the value of an assignment (after the
+     * This sample instrument listener provides prints the value of an assignment (after the
      * assignment is complete) to the {@link PrintStream} specified in the constructor. This
      * instrument can only be attached to a wrapped {@link SLWriteLocalVariableNode}, but provides
      * no guards to protect it from being attached elsewhere.
      */
-    public final class SLPrintAssigmentValueReciever extends DefaultEventReceiver {
+    public final class SLPrintAssigmentValueListener extends DefaultEventListener {
 
         private PrintStream output;
 
-        public SLPrintAssigmentValueReciever(PrintStream output) {
+        public SLPrintAssigmentValueListener(PrintStream output) {
             this.output = output;
         }
 
--- a/src/share/vm/classfile/systemDictionary.hpp	Wed Feb 11 15:53:27 2015 +0100
+++ b/src/share/vm/classfile/systemDictionary.hpp	Wed Feb 11 16:08:50 2015 +0100
@@ -204,7 +204,6 @@
   GRAAL_ONLY(do_klass(HotSpotMetaspaceConstantImpl_klass,    com_oracle_graal_hotspot_meta_HotSpotMetaspaceConstantImpl,   Graal)) \
   GRAAL_ONLY(do_klass(HotSpotStackFrameReference_klass,      com_oracle_graal_hotspot_HotSpotStackFrameReference,          Graal)) \
   GRAAL_ONLY(do_klass(CompilationTask_klass,                 com_oracle_graal_hotspot_CompilationTask,                     Graal)) \
-  GRAAL_ONLY(do_klass(Assumptions_klass,                     com_oracle_graal_api_code_Assumptions,                        Graal)) \
   GRAAL_ONLY(do_klass(Assumptions_ConcreteMethod_klass,      com_oracle_graal_api_code_Assumptions_ConcreteMethod,         Graal)) \
   GRAAL_ONLY(do_klass(Assumptions_NoFinalizableSubclass_klass, com_oracle_graal_api_code_Assumptions_NoFinalizableSubclass, Graal))\
   GRAAL_ONLY(do_klass(Assumptions_ConcreteSubtype_klass,     com_oracle_graal_api_code_Assumptions_ConcreteSubtype,        Graal)) \
--- a/src/share/vm/classfile/vmSymbols.hpp	Wed Feb 11 15:53:27 2015 +0100
+++ b/src/share/vm/classfile/vmSymbols.hpp	Wed Feb 11 16:08:50 2015 +0100
@@ -321,7 +321,6 @@
   GRAAL_ONLY(template(com_oracle_graal_api_meta_Kind,                           "com/oracle/graal/api/meta/Kind"))                                \
   GRAAL_ONLY(template(com_oracle_graal_api_meta_LIRKind,                        "com/oracle/graal/api/meta/LIRKind"))                             \
   GRAAL_ONLY(template(com_oracle_graal_api_meta_AbstractValue,                  "com/oracle/graal/api/meta/AbstractValue"))                       \
-  GRAAL_ONLY(template(com_oracle_graal_api_code_Assumptions,                    "com/oracle/graal/api/code/Assumptions"))                         \
   GRAAL_ONLY(template(com_oracle_graal_api_code_Assumptions_MethodContents,     "com/oracle/graal/api/code/Assumptions$MethodContents"))          \
   GRAAL_ONLY(template(com_oracle_graal_api_code_Assumptions_ConcreteSubtype,    "com/oracle/graal/api/code/Assumptions$ConcreteSubtype"))         \
   GRAAL_ONLY(template(com_oracle_graal_api_code_Assumptions_NoFinalizableSubclass, "com/oracle/graal/api/code/Assumptions$NoFinalizableSubclass")) \
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Wed Feb 11 15:53:27 2015 +0100
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Wed Feb 11 16:08:50 2015 +0100
@@ -389,9 +389,8 @@
   CompilerThread* compilerThread = thread->is_Compiler_thread() ? thread->as_CompilerThread() : NULL;
   _oop_recorder = new OopRecorder(&_arena, true);
   _dependencies = new Dependencies(&_arena, _oop_recorder, compilerThread != NULL ? compilerThread->log() : NULL);
-  Handle assumptions_handle = CompilationResult::assumptions(HotSpotCompiledCode::comp(compiled_code));
-  if (!assumptions_handle.is_null()) {
-    objArrayHandle assumptions(Thread::current(), Assumptions::list(assumptions_handle()));
+  objArrayHandle assumptions = CompilationResult::assumptions(HotSpotCompiledCode::comp(compiled_code));
+  if (!assumptions.is_null()) {
     int length = assumptions->length();
     for (int i = 0; i < length; ++i) {
       Handle assumption = assumptions->obj_at(i);
--- a/src/share/vm/graal/graalJavaAccess.hpp	Wed Feb 11 15:53:27 2015 +0100
+++ b/src/share/vm/graal/graalJavaAccess.hpp	Wed Feb 11 16:08:50 2015 +0100
@@ -96,12 +96,9 @@
     int_field(CompilationResult, totalFrameSize)                                                                                                               \
     int_field(CompilationResult, customStackAreaOffset)                                                                                                        \
     typeArrayOop_field(CompilationResult, targetCode, "[B")                                                                                                    \
-    oop_field(CompilationResult, assumptions, "Lcom/oracle/graal/api/code/Assumptions;")                                                                       \
+    objArrayOop_field(CompilationResult, assumptions, "[Lcom/oracle/graal/api/code/Assumptions$Assumption;")                                                                \
     int_field(CompilationResult, targetCodeSize)                                                                                                               \
   end_class                                                                                                                                                    \
-  start_class(Assumptions)                                                                                                                                     \
-    objArrayOop_field(Assumptions, list, "[Lcom/oracle/graal/api/code/Assumptions$Assumption;")                                                                \
-  end_class                                                                                                                                                    \
   start_class(Assumptions_MethodContents)                                                                                                                      \
     oop_field(Assumptions_MethodContents, method, "Lcom/oracle/graal/api/meta/ResolvedJavaMethod;")                                                            \
   end_class                                                                                                                                                    \