changeset 21915:3fe55394241c

Merge
author Stefan Anzinger <stefan.anzinger@oracle.com>
date Wed, 10 Jun 2015 19:27:05 +0200
parents 3ad681417bd6 (current diff) 4663ad4f9fbf (diff)
children 3df76a0300f3
files
diffstat 30 files changed, 177 insertions(+), 86 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java	Wed Jun 10 19:26:28 2015 +0200
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java	Wed Jun 10 19:27:05 2015 +0200
@@ -353,7 +353,7 @@
         return null;
     }
 
-    private static boolean addOverflowsPositively(long x, long y, int bits) {
+    public static boolean addOverflowsPositively(long x, long y, int bits) {
         long result = x + y;
         if (bits == 64) {
             return (~x & ~y & result) < 0;
@@ -362,7 +362,7 @@
         }
     }
 
-    private static boolean addOverflowsNegatively(long x, long y, int bits) {
+    public static boolean addOverflowsNegatively(long x, long y, int bits) {
         long result = x + y;
         if (bits == 64) {
             return (x & y & ~result) < 0;
@@ -371,7 +371,7 @@
         }
     }
 
-    private static long carryBits(long x, long y) {
+    public static long carryBits(long x, long y) {
         return (x + y) ^ x ^ y;
     }
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java	Wed Jun 10 19:26:28 2015 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java	Wed Jun 10 19:27:05 2015 +0200
@@ -90,7 +90,7 @@
         PhaseSuite<HighTierContext> graphBuilderSuite = new PhaseSuite<>();
         GraphBuilderConfiguration config = GraphBuilderConfiguration.getEagerDefault(new Plugins(new InvocationPlugins(metaAccess)));
         graphBuilderSuite.appendPhase(new GraphBuilderPhase(config));
-        HighTierContext context = new HighTierContext(providers, graphBuilderSuite, OptimisticOptimizations.NONE);
+        HighTierContext context = new HighTierContext(providers, graphBuilderSuite, OptimisticOptimizations.NONE, null);
 
         Assume.assumeTrue(VerifyPhase.class.desiredAssertionStatus());
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java	Wed Jun 10 19:26:28 2015 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java	Wed Jun 10 19:27:05 2015 +0200
@@ -70,7 +70,7 @@
 
         GraphBuilderConfiguration conf = GraphBuilderConfiguration.getSnippetDefault(getDefaultGraphBuilderPlugins());
         new GraphBuilderPhase.Instance(getMetaAccess(), getProviders().getStampProvider(), getProviders().getConstantReflection(), conf, OptimisticOptimizations.ALL, null).apply(graph);
-        HighTierContext context = new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+        HighTierContext context = new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL, null);
         new InliningPhase(new CanonicalizerPhase()).apply(graph, context);
         new CanonicalizerPhase().apply(graph, context);
         return graph;
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Wed Jun 10 19:26:28 2015 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Wed Jun 10 19:27:05 2015 +0200
@@ -369,7 +369,7 @@
     }
 
     protected HighTierContext getDefaultHighTierContext() {
-        return new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+        return new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL, null);
     }
 
     protected SnippetReflectionProvider getSnippetReflection() {
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StaticInterfaceFieldTest.java	Wed Jun 10 19:26:28 2015 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StaticInterfaceFieldTest.java	Wed Jun 10 19:27:05 2015 +0200
@@ -75,7 +75,7 @@
         PhaseSuite<HighTierContext> graphBuilderSuite = new PhaseSuite<>();
         GraphBuilderConfiguration config = GraphBuilderConfiguration.getEagerDefault(new Plugins(new InvocationPlugins(metaAccess)));
         graphBuilderSuite.appendPhase(new GraphBuilderPhase(config));
-        HighTierContext context = new HighTierContext(providers, graphBuilderSuite, OptimisticOptimizations.NONE);
+        HighTierContext context = new HighTierContext(providers, graphBuilderSuite, OptimisticOptimizations.NONE, null);
 
         Assume.assumeTrue(VerifyPhase.class.desiredAssertionStatus());
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java	Wed Jun 10 19:26:28 2015 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java	Wed Jun 10 19:27:05 2015 +0200
@@ -233,7 +233,7 @@
             StructuredGraph graph = eagerInfopointMode ? parseDebug(method, AllowAssumptions.YES) : parseEager(method, AllowAssumptions.YES);
             PhaseSuite<HighTierContext> graphBuilderSuite = eagerInfopointMode ? getCustomGraphBuilderSuite(GraphBuilderConfiguration.getFullDebugDefault(getDefaultGraphBuilderPlugins()))
                             : getDefaultGraphBuilderSuite();
-            HighTierContext context = new HighTierContext(getProviders(), graphBuilderSuite, OptimisticOptimizations.ALL);
+            HighTierContext context = new HighTierContext(getProviders(), graphBuilderSuite, OptimisticOptimizations.ALL, null);
             Debug.dump(graph, "Graph");
             new CanonicalizerPhase().apply(graph, context);
             new InliningPhase(new CanonicalizerPhase()).apply(graph, context);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Wed Jun 10 19:26:28 2015 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Wed Jun 10 19:27:05 2015 +0200
@@ -197,7 +197,7 @@
                 speculationLog.collectFailedSpeculations();
             }
 
-            HighTierContext highTierContext = new HighTierContext(providers, graphBuilderSuite, optimisticOpts);
+            HighTierContext highTierContext = new HighTierContext(providers, graphBuilderSuite, optimisticOpts, speculationLog);
             if (graph.start().next() == null) {
                 graphBuilderSuite.apply(graph, highTierContext);
                 new DeadCodeEliminationPhase(Optional).apply(graph);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractFixedGuardNode.java	Wed Jun 10 19:26:28 2015 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractFixedGuardNode.java	Wed Jun 10 19:27:05 2015 +0200
@@ -37,6 +37,7 @@
     @Input(InputType.Condition) protected LogicNode condition;
     protected final DeoptimizationReason reason;
     protected final DeoptimizationAction action;
+    protected JavaConstant speculation;
     protected boolean negated;
 
     public LogicNode condition() {
@@ -48,9 +49,11 @@
         condition = x;
     }
 
-    protected AbstractFixedGuardNode(NodeClass<? extends AbstractFixedGuardNode> c, LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated) {
+    protected AbstractFixedGuardNode(NodeClass<? extends AbstractFixedGuardNode> c, LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, JavaConstant speculation,
+                    boolean negated) {
         super(c, StampFactory.forVoid());
         this.action = action;
+        this.speculation = speculation;
         this.negated = negated;
         this.condition = condition;
         this.reason = deoptReason;
@@ -64,6 +67,10 @@
         return action;
     }
 
+    public JavaConstant getSpeculation() {
+        return speculation;
+    }
+
     public boolean isNegated() {
         return negated;
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java	Wed Jun 10 19:26:28 2015 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java	Wed Jun 10 19:27:05 2015 +0200
@@ -42,6 +42,10 @@
         this(action, reason, DEFAULT_DEBUG_ID, JavaConstant.NULL_POINTER, null);
     }
 
+    public DeoptimizeNode(DeoptimizationAction action, DeoptimizationReason reason, JavaConstant speculation) {
+        this(action, reason, DEFAULT_DEBUG_ID, speculation, null);
+    }
+
     public DeoptimizeNode(DeoptimizationAction action, DeoptimizationReason reason, int debugId, JavaConstant speculation, FrameState stateBefore) {
         super(TYPE, stateBefore);
         assert action != null;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java	Wed Jun 10 19:26:28 2015 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java	Wed Jun 10 19:27:05 2015 +0200
@@ -34,11 +34,15 @@
     public static final NodeClass<FixedGuardNode> TYPE = NodeClass.create(FixedGuardNode.class);
 
     public FixedGuardNode(LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action) {
-        this(condition, deoptReason, action, false);
+        this(condition, deoptReason, action, JavaConstant.NULL_POINTER, false);
     }
 
     public FixedGuardNode(LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated) {
-        super(TYPE, condition, deoptReason, action, negated);
+        this(condition, deoptReason, action, JavaConstant.NULL_POINTER, negated);
+    }
+
+    public FixedGuardNode(LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, JavaConstant speculation, boolean negated) {
+        super(TYPE, condition, deoptReason, action, speculation, negated);
     }
 
     @Override
@@ -53,7 +57,7 @@
                     tool.deleteBranch(currentNext);
                 }
 
-                DeoptimizeNode deopt = graph().add(new DeoptimizeNode(getAction(), getReason()));
+                DeoptimizeNode deopt = graph().add(new DeoptimizeNode(getAction(), getReason(), getSpeculation()));
                 deopt.setStateBefore(stateBefore());
                 setNext(deopt);
             }
@@ -62,8 +66,8 @@
         } else if (condition() instanceof ShortCircuitOrNode) {
             ShortCircuitOrNode shortCircuitOr = (ShortCircuitOrNode) condition();
             if (isNegated() && hasNoUsages()) {
-                graph().addAfterFixed(this, graph().add(new FixedGuardNode(shortCircuitOr.getY(), getReason(), getAction(), !shortCircuitOr.isYNegated())));
-                graph().replaceFixedWithFixed(this, graph().add(new FixedGuardNode(shortCircuitOr.getX(), getReason(), getAction(), !shortCircuitOr.isXNegated())));
+                graph().addAfterFixed(this, graph().add(new FixedGuardNode(shortCircuitOr.getY(), getReason(), getAction(), getSpeculation(), !shortCircuitOr.isYNegated())));
+                graph().replaceFixedWithFixed(this, graph().add(new FixedGuardNode(shortCircuitOr.getX(), getReason(), getAction(), getSpeculation(), !shortCircuitOr.isXNegated())));
             }
         }
     }
@@ -80,7 +84,7 @@
              * case.
              */
             if (getAction() != DeoptimizationAction.None || getReason() != DeoptimizationReason.RuntimeConstraint) {
-                ValueNode guard = tool.createGuard(this, condition(), getReason(), getAction(), isNegated()).asNode();
+                ValueNode guard = tool.createGuard(this, condition(), getReason(), getAction(), getSpeculation(), isNegated()).asNode();
                 this.replaceAtUsages(guard);
                 ValueAnchorNode newAnchor = graph().add(new ValueAnchorNode(guard.asNode()));
                 graph().replaceFixedWithFixed(this, newAnchor);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessArrayNode.java	Wed Jun 10 19:26:28 2015 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessArrayNode.java	Wed Jun 10 19:27:05 2015 +0200
@@ -50,4 +50,8 @@
         this.array = array;
     }
 
+    public void setArray(ValueNode array) {
+        updateUsages(this.array, array);
+        this.array = array;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java	Wed Jun 10 19:26:28 2015 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java	Wed Jun 10 19:27:05 2015 +0200
@@ -131,7 +131,7 @@
             innerNode = condition;
         } else {
             if (profile != null && profile.getNullSeen() == TriState.FALSE) {
-                FixedGuardNode nullCheck = graph().add(new FixedGuardNode(graph().unique(new IsNullNode(object)), UnreachedCode, InvalidateReprofile, true));
+                FixedGuardNode nullCheck = graph().add(new FixedGuardNode(graph().unique(new IsNullNode(object)), UnreachedCode, InvalidateReprofile, JavaConstant.NULL_POINTER, true));
                 PiNode nullGuarded = graph().unique(new PiNode(object, object().stamp().join(StampFactory.objectNonNull()), nullCheck));
                 LogicNode typeTest = graph().addWithoutUnique(InstanceOfNode.create(type, nullGuarded, profile));
                 innerNode = typeTest;
@@ -153,7 +153,7 @@
                 condition = LogicNode.or(graph().unique(new IsNullNode(object)), typeTest, shortCircuitProbability);
             }
         }
-        GuardingNode guard = tool.createGuard(next(), condition, forStoreCheck ? ArrayStoreException : ClassCastException, InvalidateReprofile, false);
+        GuardingNode guard = tool.createGuard(next(), condition, forStoreCheck ? ArrayStoreException : ClassCastException, InvalidateReprofile);
         ValueAnchorNode valueAnchor = graph().add(new ValueAnchorNode((ValueNode) guard));
         PiNode piNode = graph().unique(new PiNode(theValue, newStamp, (ValueNode) guard));
         this.replaceAtUsages(piNode);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringTool.java	Wed Jun 10 19:26:28 2015 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringTool.java	Wed Jun 10 19:27:05 2015 +0200
@@ -40,7 +40,7 @@
 
     GuardingNode createGuard(FixedNode before, LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action);
 
-    GuardingNode createGuard(FixedNode before, LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated);
+    GuardingNode createGuard(FixedNode before, LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, JavaConstant speculation, boolean negated);
 
     /**
      * Gets the closest fixed node preceding the node currently being lowered.
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java	Wed Jun 10 19:26:28 2015 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java	Wed Jun 10 19:27:05 2015 +0200
@@ -22,9 +22,8 @@
  */
 package com.oracle.graal.phases.common;
 
-import com.oracle.jvmci.meta.DeoptimizationReason;
-import com.oracle.jvmci.meta.Constant;
-import com.oracle.jvmci.meta.DeoptimizationAction;
+import com.oracle.jvmci.meta.*;
+
 import static com.oracle.graal.phases.common.DeadCodeEliminationPhase.Optionality.*;
 
 import java.util.*;
@@ -67,7 +66,7 @@
         }
         for (DeoptimizeNode d : graph.getNodes(DeoptimizeNode.TYPE)) {
             assert d.isAlive();
-            visitDeoptBegin(AbstractBeginNode.prevBegin(d), d.action(), d.reason(), graph);
+            visitDeoptBegin(AbstractBeginNode.prevBegin(d), d.action(), d.reason(), d.getSpeculation(), graph);
         }
 
         if (context != null) {
@@ -130,12 +129,12 @@
                 ys = yPhi.valueAt(mergePredecessor).asConstant();
             }
             if (xs != null && ys != null && compare.condition().foldCondition(xs, ys, context.getConstantReflection(), compare.unorderedIsTrue()) == fixedGuard.isNegated()) {
-                visitDeoptBegin(AbstractBeginNode.prevBegin(mergePredecessor), fixedGuard.getAction(), fixedGuard.getReason(), fixedGuard.graph());
+                visitDeoptBegin(AbstractBeginNode.prevBegin(mergePredecessor), fixedGuard.getAction(), fixedGuard.getReason(), fixedGuard.getSpeculation(), fixedGuard.graph());
             }
         }
     }
 
-    private void visitDeoptBegin(AbstractBeginNode deoptBegin, DeoptimizationAction deoptAction, DeoptimizationReason deoptReason, StructuredGraph graph) {
+    private void visitDeoptBegin(AbstractBeginNode deoptBegin, DeoptimizationAction deoptAction, DeoptimizationReason deoptReason, JavaConstant speculation, StructuredGraph graph) {
         if (deoptBegin instanceof AbstractMergeNode) {
             AbstractMergeNode mergeNode = (AbstractMergeNode) deoptBegin;
             Debug.log("Visiting %s", mergeNode);
@@ -143,17 +142,17 @@
             while (mergeNode.isAlive()) {
                 AbstractEndNode end = mergeNode.forwardEnds().first();
                 AbstractBeginNode newBeginNode = findBeginNode(end);
-                visitDeoptBegin(newBeginNode, deoptAction, deoptReason, graph);
+                visitDeoptBegin(newBeginNode, deoptAction, deoptReason, speculation, graph);
             }
             assert next.isAlive();
             AbstractBeginNode newBeginNode = findBeginNode(next);
-            visitDeoptBegin(newBeginNode, deoptAction, deoptReason, graph);
+            visitDeoptBegin(newBeginNode, deoptAction, deoptReason, speculation, graph);
             return;
         } else if (deoptBegin.predecessor() instanceof IfNode) {
             IfNode ifNode = (IfNode) deoptBegin.predecessor();
             AbstractBeginNode otherBegin = ifNode.trueSuccessor();
             LogicNode conditionNode = ifNode.condition();
-            FixedGuardNode guard = graph.add(new FixedGuardNode(conditionNode, deoptReason, deoptAction, deoptBegin == ifNode.trueSuccessor()));
+            FixedGuardNode guard = graph.add(new FixedGuardNode(conditionNode, deoptReason, deoptAction, speculation, deoptBegin == ifNode.trueSuccessor()));
             FixedWithNextNode pred = (FixedWithNextNode) ifNode.predecessor();
             AbstractBeginNode survivingSuccessor;
             if (deoptBegin == ifNode.trueSuccessor()) {
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DominatorConditionalEliminationPhase.java	Wed Jun 10 19:26:28 2015 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DominatorConditionalEliminationPhase.java	Wed Jun 10 19:27:05 2015 +0200
@@ -460,7 +460,7 @@
                     GraphUtil.unlinkFixedNode(node);
                     GraphUtil.killWithUnusedFloatingInputs(node);
                 } else {
-                    DeoptimizeNode deopt = node.graph().add(new DeoptimizeNode(node.getAction(), node.getReason()));
+                    DeoptimizeNode deopt = node.graph().add(new DeoptimizeNode(node.getAction(), node.getReason(), node.getSpeculation()));
                     deopt.setStateBefore(node.stateBefore());
                     node.replaceAtPredecessor(deopt);
                     GraphUtil.killCFG(node);
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java	Wed Jun 10 19:26:28 2015 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java	Wed Jun 10 19:27:05 2015 +0200
@@ -123,7 +123,7 @@
 
         @Override
         public GuardingNode createGuard(FixedNode before, LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action) {
-            return createGuard(before, condition, deoptReason, action, false);
+            return createGuard(before, condition, deoptReason, action, JavaConstant.NULL_POINTER, false);
         }
 
         public StampProvider getStampProvider() {
@@ -131,7 +131,7 @@
         }
 
         @Override
-        public GuardingNode createGuard(FixedNode before, LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated) {
+        public GuardingNode createGuard(FixedNode before, LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, JavaConstant speculation, boolean negated) {
             if (OptEliminateGuards.getValue()) {
                 for (Node usage : condition.usages()) {
                     if (!activeGuards.isNew(usage) && activeGuards.isMarked(usage) && ((GuardNode) usage).isNegated() == negated) {
@@ -141,7 +141,7 @@
             }
             StructuredGraph graph = before.graph();
             if (!condition.graph().getGuardsStage().allowsFloatingGuards()) {
-                FixedGuardNode fixedGuard = graph.add(new FixedGuardNode(condition, deoptReason, action, negated));
+                FixedGuardNode fixedGuard = graph.add(new FixedGuardNode(condition, deoptReason, action, speculation, negated));
                 graph.addBeforeFixed(before, fixedGuard);
                 DummyGuardHandle handle = graph.add(new DummyGuardHandle(fixedGuard));
                 fixedGuard.lower(this);
@@ -149,7 +149,7 @@
                 handle.safeDelete();
                 return result;
             } else {
-                GuardNode newGuard = graph.unique(new GuardNode(condition, guardAnchor, deoptReason, action, negated, JavaConstant.NULL_POINTER));
+                GuardNode newGuard = graph.unique(new GuardNode(condition, guardAnchor, deoptReason, action, negated, speculation));
                 if (OptEliminateGuards.getValue()) {
                     activeGuards.markAndGrow(newGuard);
                 }
@@ -407,7 +407,7 @@
      *     if (alwaysReachedBlock != null &amp;&amp; alwaysReachedBlock.getDominator() == block) {
      *         processBlock(alwaysReachedBlock);
      *     }
-     *
+     * 
      *     // Now go for the other dominators.
      *     for (Block dominated : block.getDominated()) {
      *         if (dominated != alwaysReachedBlock) {
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/HighTierContext.java	Wed Jun 10 19:26:28 2015 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/HighTierContext.java	Wed Jun 10 19:27:05 2015 +0200
@@ -24,6 +24,7 @@
 
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.util.*;
+import com.oracle.jvmci.meta.*;
 
 public class HighTierContext extends PhaseContext {
 
@@ -31,10 +32,13 @@
 
     private final OptimisticOptimizations optimisticOpts;
 
-    public HighTierContext(Providers providers, PhaseSuite<HighTierContext> graphBuilderSuite, OptimisticOptimizations optimisticOpts) {
+    private SpeculationLog speculationLog;
+
+    public HighTierContext(Providers providers, PhaseSuite<HighTierContext> graphBuilderSuite, OptimisticOptimizations optimisticOpts, SpeculationLog speculationLog) {
         super(providers);
         this.graphBuilderSuite = graphBuilderSuite;
         this.optimisticOpts = optimisticOpts;
+        this.speculationLog = speculationLog;
     }
 
     public PhaseSuite<HighTierContext> getGraphBuilderSuite() {
@@ -44,4 +48,8 @@
     public OptimisticOptimizations getOptimisticOptimizations() {
         return optimisticOpts;
     }
+
+    public SpeculationLog getSpeculationLog() {
+        return speculationLog;
+    }
 }
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ArraysSubstitutionsTest.java	Wed Jun 10 19:26:28 2015 +0200
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ArraysSubstitutionsTest.java	Wed Jun 10 19:27:05 2015 +0200
@@ -331,7 +331,7 @@
     @Test
     public void testCanonicalLength() {
         StructuredGraph graph = parseEager("testCanonicalLengthSnippet", AllowAssumptions.NO);
-        HighTierContext context = new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+        HighTierContext context = new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL, null);
         new InliningPhase(new CanonicalizerPhase()).apply(graph, context);
         new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
 
@@ -347,7 +347,7 @@
     @Test
     public void testCanonicalEqual() {
         StructuredGraph graph = parseEager("testCanonicalEqualSnippet", AllowAssumptions.NO);
-        HighTierContext context = new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+        HighTierContext context = new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL, null);
         new InliningPhase(new CanonicalizerPhase()).apply(graph, context);
         new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
 
@@ -361,7 +361,7 @@
     @Test
     public void testVirtualEqual() {
         StructuredGraph graph = parseEager("testVirtualEqualSnippet", AllowAssumptions.NO);
-        HighTierContext context = new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+        HighTierContext context = new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL, null);
         new InliningPhase(new CanonicalizerPhase()).apply(graph, context);
         new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
         new PartialEscapePhase(false, new CanonicalizerPhase()).apply(graph, context);
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java	Wed Jun 10 19:26:28 2015 +0200
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java	Wed Jun 10 19:27:05 2015 +0200
@@ -395,7 +395,7 @@
     }
 
     private void assertNumWordCasts(String snippetName, int expectedWordCasts) {
-        HighTierContext context = new HighTierContext(getProviders(), null, OptimisticOptimizations.ALL);
+        HighTierContext context = new HighTierContext(getProviders(), null, OptimisticOptimizations.ALL, null);
 
         StructuredGraph graph = parseEager(snippetName, AllowAssumptions.YES);
         new CanonicalizerPhase().apply(graph, context);
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java	Wed Jun 10 19:26:28 2015 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java	Wed Jun 10 19:27:05 2015 +0200
@@ -253,9 +253,13 @@
             if (arrayType != null && StampTool.isExactType(array)) {
                 ResolvedJavaType elementType = arrayType.getComponentType();
                 if (!elementType.isJavaLangObject()) {
-                    checkCastNode = graph.add(new CheckCastNode(elementType, value, null, true));
-                    graph.addBeforeFixed(storeIndexed, checkCastNode);
-                    value = checkCastNode;
+                    ValueNode storeCheck = CheckCastNode.create(elementType, value, null, true, graph.getAssumptions());
+                    if (storeCheck.graph() == null) {
+                        checkCastNode = (CheckCastNode) storeCheck;
+                        checkCastNode = graph.add(checkCastNode);
+                        graph.addBeforeFixed(storeIndexed, checkCastNode);
+                    }
+                    value = storeCheck;
                 }
             } else {
                 ValueNode arrayClass = createReadHub(graph, array, boundsCheck);
@@ -698,7 +702,8 @@
         if (StampTool.isPointerNonNull(object)) {
             return null;
         }
-        return tool.createGuard(before, before.graph().unique(new IsNullNode(object)), DeoptimizationReason.NullCheckException, DeoptimizationAction.InvalidateReprofile, true);
+        return tool.createGuard(before, before.graph().unique(new IsNullNode(object)), DeoptimizationReason.NullCheckException, DeoptimizationAction.InvalidateReprofile, JavaConstant.NULL_POINTER,
+                        true);
     }
 
     @Override
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/arithmetic/IntegerAddExactNode.java	Wed Jun 10 19:26:28 2015 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/arithmetic/IntegerAddExactNode.java	Wed Jun 10 19:27:05 2015 +0200
@@ -29,8 +29,11 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.jvmci.code.*;
 import com.oracle.jvmci.meta.*;
 
+import static com.oracle.graal.compiler.common.type.IntegerStamp.*;
+
 /**
  * Node representing an exact integer addition that will throw an {@link ArithmeticException} in
  * case the addition would overflow the 32 bit range.
@@ -41,14 +44,59 @@
 
     public IntegerAddExactNode(ValueNode x, ValueNode y) {
         super(TYPE, x, y);
-        setStamp(x.stamp().unrestricted());
+        setStamp(foldStamp(x.stamp(), y.stamp()));
         assert x.stamp().isCompatible(y.stamp()) && x.stamp() instanceof IntegerStamp;
     }
 
     @Override
     public boolean inferStamp() {
-        // TODO Should probably use a specialized version which understands that it can't overflow
-        return false;
+        return updateStamp(foldStamp(x.stamp(), y.stamp()));
+    }
+
+    private static Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
+        IntegerStamp a = (IntegerStamp) stamp1;
+        IntegerStamp b = (IntegerStamp) stamp2;
+
+        int bits = a.getBits();
+        assert bits == b.getBits();
+
+        long defaultMask = CodeUtil.mask(bits);
+        long variableBits = (a.downMask() ^ a.upMask()) | (b.downMask() ^ b.upMask());
+        long variableBitsWithCarry = variableBits | (carryBits(a.downMask(), b.downMask()) ^ carryBits(a.upMask(), b.upMask()));
+        long newDownMask = (a.downMask() + b.downMask()) & ~variableBitsWithCarry;
+        long newUpMask = (a.downMask() + b.downMask()) | variableBitsWithCarry;
+
+        newDownMask &= defaultMask;
+        newUpMask &= defaultMask;
+
+        long newLowerBound;
+        long newUpperBound;
+        boolean lowerOverflowsPositively = addOverflowsPositively(a.lowerBound(), b.lowerBound(), bits);
+        boolean upperOverflowsPositively = addOverflowsPositively(a.upperBound(), b.upperBound(), bits);
+        boolean lowerOverflowsNegatively = addOverflowsNegatively(a.lowerBound(), b.lowerBound(), bits);
+        boolean upperOverflowsNegatively = addOverflowsNegatively(a.upperBound(), b.upperBound(), bits);
+        if (lowerOverflowsPositively) {
+            newLowerBound = CodeUtil.maxValue(bits);
+        } else if (lowerOverflowsNegatively) {
+            newLowerBound = CodeUtil.minValue(bits);
+        } else {
+            newLowerBound = CodeUtil.signExtend((a.lowerBound() + b.lowerBound()) & defaultMask, bits);
+        }
+
+        if (upperOverflowsPositively) {
+            newUpperBound = CodeUtil.maxValue(bits);
+        } else if (upperOverflowsNegatively) {
+            newUpperBound = CodeUtil.minValue(bits);
+        } else {
+            newUpperBound = CodeUtil.signExtend((a.upperBound() + b.upperBound()) & defaultMask, bits);
+        }
+
+        IntegerStamp limit = StampFactory.forInteger(bits, newLowerBound, newUpperBound);
+        newUpMask &= limit.upMask();
+        newUpperBound = CodeUtil.signExtend(newUpperBound & newUpMask, bits);
+        newDownMask |= limit.downMask();
+        newLowerBound |= newDownMask;
+        return new IntegerStamp(bits, newLowerBound, newUpperBound, newDownMask, newUpMask);
     }
 
     @Override
--- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/nfi/HotSpotNativeFunctionInterfaceAccess.java	Wed Jun 10 19:26:28 2015 +0200
+++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/nfi/HotSpotNativeFunctionInterfaceAccess.java	Wed Jun 10 19:27:05 2015 +0200
@@ -27,7 +27,7 @@
 import com.oracle.nfi.api.*;
 
 @ServiceProvider(NativeFunctionInterfaceAccess.class)
-public class HotSpotNativeFunctionInterfaceAccess implements NativeFunctionInterfaceAccess {
+public class HotSpotNativeFunctionInterfaceAccess implements NativeFunctionInterfaceAccess, Service {
     private final NativeFunctionInterface instance = HotSpotTruffleRuntime.createNativeFunctionInterface();
 
     public NativeFunctionInterface getNativeFunctionInterface() {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Wed Jun 10 19:26:28 2015 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Wed Jun 10 19:27:05 2015 +0200
@@ -109,7 +109,7 @@
         try (Scope s = Debug.scope("CreateGraph", graph); Indent indent = Debug.logAndIndent("createGraph %s", graph)) {
 
             PhaseContext baseContext = new PhaseContext(providers);
-            HighTierContext tierContext = new HighTierContext(providers, new PhaseSuite<HighTierContext>(), OptimisticOptimizations.NONE);
+            HighTierContext tierContext = new HighTierContext(providers, new PhaseSuite<HighTierContext>(), OptimisticOptimizations.NONE, null);
 
             fastPartialEvaluation(callTarget, graph, baseContext, tierContext);
 
--- a/graal/com.oracle.nfi/src/com/oracle/nfi/NativeFunctionInterfaceRuntime.java	Wed Jun 10 19:26:28 2015 +0200
+++ b/graal/com.oracle.nfi/src/com/oracle/nfi/NativeFunctionInterfaceRuntime.java	Wed Jun 10 19:27:05 2015 +0200
@@ -22,7 +22,8 @@
  */
 package com.oracle.nfi;
 
-import com.oracle.jvmci.service.*;
+import java.lang.reflect.*;
+
 import com.oracle.nfi.api.*;
 
 /**
@@ -43,7 +44,24 @@
     static {
 
         NativeFunctionInterface instance = null;
-        NativeFunctionInterfaceAccess access = Services.loadSingle(NativeFunctionInterfaceAccess.class, false);
+
+        NativeFunctionInterfaceAccess access = null;
+        Class<?> servicesClass = null;
+        try {
+            servicesClass = Class.forName("com.oracle.jvmci.service.Services");
+        } catch (ClassNotFoundException e) {
+            // JVMCI is unavailable
+        }
+        if (servicesClass != null) {
+            try {
+                Method m = servicesClass.getDeclaredMethod("loadSingle", Class.class, boolean.class);
+                access = (NativeFunctionInterfaceAccess) m.invoke(null, NativeFunctionInterfaceAccess.class, false);
+            } catch (Throwable e) {
+                // Fail fast for other errors
+                throw (InternalError) new InternalError().initCause(e);
+            }
+        }
+        // TODO: try standard ServiceLoader?
         if (access != null) {
             instance = access.getNativeFunctionInterface();
         }
--- a/graal/com.oracle.nfi/src/com/oracle/nfi/api/NativeFunctionInterface.java	Wed Jun 10 19:26:28 2015 +0200
+++ b/graal/com.oracle.nfi/src/com/oracle/nfi/api/NativeFunctionInterface.java	Wed Jun 10 19:27:05 2015 +0200
@@ -22,14 +22,12 @@
  */
 package com.oracle.nfi.api;
 
-import com.oracle.jvmci.service.*;
-
 /**
  * Interface to get a {@linkplain NativeFunctionHandle handle} or {@linkplain NativeFunctionPointer
  * pointer} to a native function or a {@linkplain NativeLibraryHandle handle} to an open native
  * library.
  */
-public interface NativeFunctionInterface extends Service {
+public interface NativeFunctionInterface {
 
     /**
      * Resolves and returns a handle to an open native library. This method will open the library
--- a/graal/com.oracle.nfi/src/com/oracle/nfi/api/NativeFunctionInterfaceAccess.java	Wed Jun 10 19:26:28 2015 +0200
+++ b/graal/com.oracle.nfi/src/com/oracle/nfi/api/NativeFunctionInterfaceAccess.java	Wed Jun 10 19:27:05 2015 +0200
@@ -22,13 +22,10 @@
  */
 package com.oracle.nfi.api;
 
-import com.oracle.jvmci.service.*;
-
 /**
- * A {@linkplain Service JVMCI service} that provides access to a {@link NativeFunctionInterface}
- * implementation.
+ * A service that provides access to a {@link NativeFunctionInterface} implementation.
  */
-public interface NativeFunctionInterfaceAccess extends Service {
+public interface NativeFunctionInterfaceAccess {
 
     /**
      * Gets the {@link NativeFunctionInterface} implementation available via this access object.
--- a/jvmci/com.oracle.jvmci.service/src/com/oracle/jvmci/service/Service.java	Wed Jun 10 19:26:28 2015 +0200
+++ b/jvmci/com.oracle.jvmci.service/src/com/oracle/jvmci/service/Service.java	Wed Jun 10 19:27:05 2015 +0200
@@ -23,11 +23,14 @@
 package com.oracle.jvmci.service;
 
 /**
- * Marker interface for a service implementation that can be loaded by {@link Services#load(Class)}
- * or {@link Services#loadSingle(Class, boolean)}. These implementations are hidden behind a class
- * loader not accessible to applications. For this reason, {@link Services#load(Class)} and
+ * Marker interface for a service provider that can be loaded by {@link Services#load(Class)} or
+ * {@link Services#loadSingle(Class, boolean)}. These providers are hidden behind a class loader not
+ * accessible to applications. For this reason, {@link Services#load(Class)} and
  * {@link Services#loadSingle(Class, boolean)} perform {@link SecurityManager} checks.
  *
+ * If this marker interface is applied to a service interface <i>S</I> as opposed to a service
+ * provider, then all providers implementing <i>S</i> have the semantics described above.
+ *
  * @see Services
  * @see ServiceProvider
  */
--- a/jvmci/com.oracle.jvmci.service/src/com/oracle/jvmci/service/ServiceProvider.java	Wed Jun 10 19:26:28 2015 +0200
+++ b/jvmci/com.oracle.jvmci.service/src/com/oracle/jvmci/service/ServiceProvider.java	Wed Jun 10 19:27:05 2015 +0200
@@ -25,8 +25,8 @@
 import java.lang.annotation.*;
 
 /**
- * Annotates a JVMCI implementation of a service. This annotation is used by the JVMCI build system
- * to deploy the necessary files used to {@linkplain Services#load(Class) load} services at runtime.
+ * Annotates a JVMCI provider of a service. This annotation is used by the JVMCI build system to
+ * deploy the necessary files used to {@linkplain Services#load(Class) load} services at runtime.
  */
 @Retention(RetentionPolicy.CLASS)
 @Target(ElementType.TYPE)
--- a/jvmci/com.oracle.jvmci.service/src/com/oracle/jvmci/service/Services.java	Wed Jun 10 19:26:28 2015 +0200
+++ b/jvmci/com.oracle.jvmci.service/src/com/oracle/jvmci/service/Services.java	Wed Jun 10 19:27:05 2015 +0200
@@ -27,15 +27,15 @@
 import sun.reflect.*;
 
 /**
- * An mechanism for loading services that have a {@linkplain Service JVMCI implementation}.
+ * An mechanism for accessing {@link Service JVMCI service providers}.
  */
 public class Services {
 
     private static final String SUPPRESS_PROPERTY_NAME = "jvmci.service.suppressNoClassDefFoundError";
 
     /**
-     * Determines whether to suppress the {@link NoClassDefFoundError} raised if a service
-     * implementation class specified in a {@code <jre>/jvmci/services/*} file is missing.
+     * Determines whether to suppress the {@link NoClassDefFoundError} raised if a service provider
+     * class specified in a {@code <jre>/jvmci/services/*} file is missing.
      */
     private static final boolean SuppressNoClassDefFoundError = Boolean.getBoolean(SUPPRESS_PROPERTY_NAME);
 
@@ -59,7 +59,7 @@
     };
 
     /**
-     * Gets an {@link Iterable} of the JVMCI implementations available for a given service.
+     * Gets an {@link Iterable} of the JVMCI providers available for a given service.
      *
      * @throws SecurityException if a security manager is present and it denies
      *             <tt>{@link RuntimePermission}("jvmciServices")</tt>
@@ -79,12 +79,11 @@
     }
 
     /**
-     * Gets the JVMCI implementation for a given service for which at most one implementation must
-     * be available.
+     * Gets the JVMCI provider for a given service for which at most one provider must be available.
      *
-     * @param service the service whose implementation is being requested
-     * @param required specifies if an {@link InternalError} should be thrown if no implementation
-     *            of {@code service} is available
+     * @param service the service whose provider is being requested
+     * @param required specifies if an {@link InternalError} should be thrown if no provider of
+     *            {@code service} is available
      * @throws SecurityException if a security manager is present and it denies
      *             <tt>{@link RuntimePermission}("jvmciServices")</tt>
      */
@@ -95,21 +94,21 @@
         if (sm != null) {
             sm.checkPermission(new RuntimePermission("jvmciServices"));
         }
-        Iterable<S> impls;
+        Iterable<S> providers;
         try {
-            impls = (Iterable<S>) cache.get(service);
+            providers = (Iterable<S>) cache.get(service);
         } catch (UnsatisfiedLinkError e) {
-            impls = Collections.emptyList();
+            providers = Collections.emptyList();
         }
 
-        S singleImpl = null;
-        for (S impl : impls) {
-            if (singleImpl != null) {
-                throw new InternalError(String.format("Multiple %s implementations found: %s, %s", service.getName(), singleImpl.getClass().getName(), impl.getClass().getName()));
+        S singleProvider = null;
+        for (S provider : providers) {
+            if (singleProvider != null) {
+                throw new InternalError(String.format("Multiple %s providers found: %s, %s", service.getName(), singleProvider.getClass().getName(), provider.getClass().getName()));
             }
-            singleImpl = impl;
+            singleProvider = provider;
         }
-        if (singleImpl == null && required) {
+        if (singleProvider == null && required) {
             String javaHome = System.getProperty("java.home");
             String vmName = System.getProperty("java.vm.name");
             Formatter errorMessage = new Formatter();
@@ -118,7 +117,7 @@
             errorMessage.format("Currently used VM configuration is: %s", vmName);
             throw new UnsupportedOperationException(errorMessage.toString());
         }
-        return singleImpl;
+        return singleProvider;
     }
 
     static {
--- a/mx/suite.py	Wed Jun 10 19:26:28 2015 +0200
+++ b/mx/suite.py	Wed Jun 10 19:27:05 2015 +0200
@@ -398,7 +398,6 @@
     "com.oracle.nfi" : {
       "subDir" : "graal",
       "sourceDirs" : ["src"],
-      "dependencies" : ["com.oracle.jvmci.service"],
       "checkstyle" : "com.oracle.graal.graph",
       "javaCompliance" : "1.7",
     },
@@ -1359,6 +1358,7 @@
       ],
       "exclude" : ["FINDBUGS"],
       "distDependencies" : [
+        "JVMCI_SERVICE",
         "JVMCI_HOTSPOT",
         "TRUFFLE",
       ],
@@ -1375,9 +1375,6 @@
         "com.oracle.truffle.object.basic",
         "com.oracle.truffle.tools"
       ],
-      "distDependencies" : [
-        "JVMCI_SERVICE",
-      ],
     },
 
     "GRAAL_TRUFFLE" : {