# HG changeset patch # User Stefan Anzinger # Date 1433957225 -7200 # Node ID 3fe55394241c2eb98e8ecab8c5c6c5a89120f20f # Parent 3ad681417bd60fda39453ed362c29cca44acace8# Parent 4663ad4f9fbf7439f2060a11cb54409e6dabadec Merge diff -r 3ad681417bd6 -r 3fe55394241c graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java --- 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; } diff -r 3ad681417bd6 -r 3fe55394241c graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java --- 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 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()); diff -r 3ad681417bd6 -r 3fe55394241c graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java --- 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; diff -r 3ad681417bd6 -r 3fe55394241c graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java --- 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() { diff -r 3ad681417bd6 -r 3fe55394241c graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StaticInterfaceFieldTest.java --- 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 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()); diff -r 3ad681417bd6 -r 3fe55394241c graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java --- 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 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); diff -r 3ad681417bd6 -r 3fe55394241c graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java --- 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); diff -r 3ad681417bd6 -r 3fe55394241c graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractFixedGuardNode.java --- 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 c, LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated) { + protected AbstractFixedGuardNode(NodeClass 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; } diff -r 3ad681417bd6 -r 3fe55394241c graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java --- 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; diff -r 3ad681417bd6 -r 3fe55394241c graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java --- 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 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); diff -r 3ad681417bd6 -r 3fe55394241c graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessArrayNode.java --- 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; + } } diff -r 3ad681417bd6 -r 3fe55394241c graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java --- 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); diff -r 3ad681417bd6 -r 3fe55394241c graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringTool.java --- 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. diff -r 3ad681417bd6 -r 3fe55394241c graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java --- 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()) { diff -r 3ad681417bd6 -r 3fe55394241c graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DominatorConditionalEliminationPhase.java --- 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); diff -r 3ad681417bd6 -r 3fe55394241c graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java --- 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 && alwaysReachedBlock.getDominator() == block) { * processBlock(alwaysReachedBlock); * } - * + * * // Now go for the other dominators. * for (Block dominated : block.getDominated()) { * if (dominated != alwaysReachedBlock) { diff -r 3ad681417bd6 -r 3fe55394241c graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/HighTierContext.java --- 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 graphBuilderSuite, OptimisticOptimizations optimisticOpts) { + private SpeculationLog speculationLog; + + public HighTierContext(Providers providers, PhaseSuite graphBuilderSuite, OptimisticOptimizations optimisticOpts, SpeculationLog speculationLog) { super(providers); this.graphBuilderSuite = graphBuilderSuite; this.optimisticOpts = optimisticOpts; + this.speculationLog = speculationLog; } public PhaseSuite getGraphBuilderSuite() { @@ -44,4 +48,8 @@ public OptimisticOptimizations getOptimisticOptimizations() { return optimisticOpts; } + + public SpeculationLog getSpeculationLog() { + return speculationLog; + } } diff -r 3ad681417bd6 -r 3fe55394241c graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ArraysSubstitutionsTest.java --- 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); diff -r 3ad681417bd6 -r 3fe55394241c graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java --- 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); diff -r 3ad681417bd6 -r 3fe55394241c graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java --- 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 diff -r 3ad681417bd6 -r 3fe55394241c graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/arithmetic/IntegerAddExactNode.java --- 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 diff -r 3ad681417bd6 -r 3fe55394241c graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/nfi/HotSpotNativeFunctionInterfaceAccess.java --- 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() { diff -r 3ad681417bd6 -r 3fe55394241c graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java --- 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(), OptimisticOptimizations.NONE); + HighTierContext tierContext = new HighTierContext(providers, new PhaseSuite(), OptimisticOptimizations.NONE, null); fastPartialEvaluation(callTarget, graph, baseContext, tierContext); diff -r 3ad681417bd6 -r 3fe55394241c graal/com.oracle.nfi/src/com/oracle/nfi/NativeFunctionInterfaceRuntime.java --- 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(); } diff -r 3ad681417bd6 -r 3fe55394241c graal/com.oracle.nfi/src/com/oracle/nfi/api/NativeFunctionInterface.java --- 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 diff -r 3ad681417bd6 -r 3fe55394241c graal/com.oracle.nfi/src/com/oracle/nfi/api/NativeFunctionInterfaceAccess.java --- 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. diff -r 3ad681417bd6 -r 3fe55394241c jvmci/com.oracle.jvmci.service/src/com/oracle/jvmci/service/Service.java --- 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 S as opposed to a service + * provider, then all providers implementing S have the semantics described above. + * * @see Services * @see ServiceProvider */ diff -r 3ad681417bd6 -r 3fe55394241c jvmci/com.oracle.jvmci.service/src/com/oracle/jvmci/service/ServiceProvider.java --- 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) diff -r 3ad681417bd6 -r 3fe55394241c jvmci/com.oracle.jvmci.service/src/com/oracle/jvmci/service/Services.java --- 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 /jvmci/services/*} file is missing. + * Determines whether to suppress the {@link NoClassDefFoundError} raised if a service provider + * class specified in a {@code /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 * {@link RuntimePermission}("jvmciServices") @@ -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 * {@link RuntimePermission}("jvmciServices") */ @@ -95,21 +94,21 @@ if (sm != null) { sm.checkPermission(new RuntimePermission("jvmciServices")); } - Iterable impls; + Iterable providers; try { - impls = (Iterable) cache.get(service); + providers = (Iterable) 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 { diff -r 3ad681417bd6 -r 3fe55394241c mx/suite.py --- 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" : {