# HG changeset patch # User Gilles Duboscq # Date 1382026685 -7200 # Node ID 2d8a8980eda89434b07f063a844ce48330dac004 # Parent 134671fbf9735045091f99a2e0b60d8d83cf1ca6 Canonicalize DynamicDeoptimize nodes back to Deoptimize when used with a constant reason&action diff -r 134671fbf973 -r 2d8a8980eda8 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java Thu Oct 17 18:18:05 2013 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java Thu Oct 17 18:18:05 2013 +0200 @@ -73,4 +73,8 @@ * @return the encoded value as an integer */ Constant encodeDeoptActionAndReason(DeoptimizationAction action, DeoptimizationReason reason); + + DeoptimizationReason decodeDeoptReason(Constant constant); + + DeoptimizationAction decodeDeoptAction(Constant constant); } diff -r 134671fbf973 -r 2d8a8980eda8 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java Thu Oct 17 18:18:05 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java Thu Oct 17 18:18:05 2013 +0200 @@ -79,14 +79,29 @@ return runtime.getCompilerToVM().getJavaField(reflectionField); } + private static final int ACTION_SHIFT = 0; + private static final int ACTION_MASK = 0x07; + private static final int REASON_SHIFT = 3; + private static final int REASON_MASK = 0x1f; + @Override public Constant encodeDeoptActionAndReason(DeoptimizationAction action, DeoptimizationReason reason) { - final int actionShift = 0; - final int reasonShift = 3; - int actionValue = convertDeoptAction(action); int reasonValue = convertDeoptReason(reason); - return Constant.forInt(~(((reasonValue) << reasonShift) + ((actionValue) << actionShift))); + Constant c = Constant.forInt(~(((reasonValue) << REASON_SHIFT) + ((actionValue) << ACTION_SHIFT))); + return c; + } + + public DeoptimizationReason decodeDeoptReason(Constant constant) { + int reasonValue = ((~constant.asInt()) >> REASON_SHIFT) & REASON_MASK; + DeoptimizationReason reason = convertDeoptReason(reasonValue); + return reason; + } + + public DeoptimizationAction decodeDeoptAction(Constant constant) { + int actionValue = ((~constant.asInt()) >> ACTION_SHIFT) & ACTION_MASK; + DeoptimizationAction action = convertDeoptAction(actionValue); + return action; } public int convertDeoptAction(DeoptimizationAction action) { @@ -106,6 +121,22 @@ } } + public DeoptimizationAction convertDeoptAction(int action) { + if (action == runtime.getConfig().deoptActionNone) { + return DeoptimizationAction.None; + } else if (action == runtime.getConfig().deoptActionMaybeRecompile) { + return DeoptimizationAction.RecompileIfTooManyDeopts; + } else if (action == runtime.getConfig().deoptActionReinterpret) { + return DeoptimizationAction.InvalidateReprofile; + } else if (action == runtime.getConfig().deoptActionMakeNotEntrant) { + return DeoptimizationAction.InvalidateRecompile; + } else if (action == runtime.getConfig().deoptActionMakeNotCompilable) { + return DeoptimizationAction.InvalidateStopCompiling; + } else { + throw GraalInternalError.shouldNotReachHere(); + } + } + public int convertDeoptReason(DeoptimizationReason reason) { switch (reason) { case None: @@ -140,4 +171,38 @@ throw GraalInternalError.shouldNotReachHere(); } } + + public DeoptimizationReason convertDeoptReason(int reason) { + if (reason == runtime.getConfig().deoptReasonNone) { + return DeoptimizationReason.None; + } else if (reason == runtime.getConfig().deoptReasonNullCheck) { + return DeoptimizationReason.NullCheckException; + } else if (reason == runtime.getConfig().deoptReasonRangeCheck) { + return DeoptimizationReason.BoundsCheckException; + } else if (reason == runtime.getConfig().deoptReasonClassCheck) { + return DeoptimizationReason.ClassCastException; + } else if (reason == runtime.getConfig().deoptReasonArrayCheck) { + return DeoptimizationReason.ArrayStoreException; + } else if (reason == runtime.getConfig().deoptReasonUnreached0) { + return DeoptimizationReason.UnreachedCode; + } else if (reason == runtime.getConfig().deoptReasonTypeCheckInlining) { + return DeoptimizationReason.TypeCheckedInliningViolated; + } else if (reason == runtime.getConfig().deoptReasonOptimizedTypeCheck) { + return DeoptimizationReason.OptimizedTypeCheckViolated; + } else if (reason == runtime.getConfig().deoptReasonNotCompiledExceptionHandler) { + return DeoptimizationReason.NotCompiledExceptionHandler; + } else if (reason == runtime.getConfig().deoptReasonUnresolved) { + return DeoptimizationReason.Unresolved; + } else if (reason == runtime.getConfig().deoptReasonJsrMismatch) { + return DeoptimizationReason.JavaSubroutineMismatch; + } else if (reason == runtime.getConfig().deoptReasonDiv0Check) { + return DeoptimizationReason.ArithmeticException; + } else if (reason == runtime.getConfig().deoptReasonConstraint) { + return DeoptimizationReason.RuntimeConstraint; + } else if (reason == runtime.getConfig().deoptReasonLoopLimitCheck) { + return DeoptimizationReason.LoopLimitCheck; + } else { + throw GraalInternalError.shouldNotReachHere(Integer.toHexString(reason)); + } + } } diff -r 134671fbf973 -r 2d8a8980eda8 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 Thu Oct 17 18:18:05 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java Thu Oct 17 18:18:05 2013 +0200 @@ -33,6 +33,8 @@ private final DeoptimizationReason reason; public DeoptimizeNode(DeoptimizationAction action, DeoptimizationReason reason) { + assert action != null; + assert reason != null; this.action = action; this.reason = reason; } diff -r 134671fbf973 -r 2d8a8980eda8 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DynamicDeoptimizeNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DynamicDeoptimizeNode.java Thu Oct 17 18:18:05 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DynamicDeoptimizeNode.java Thu Oct 17 18:18:05 2013 +0200 @@ -23,9 +23,11 @@ package com.oracle.graal.nodes; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.spi.*; -public class DynamicDeoptimizeNode extends AbstractDeoptimizeNode implements LIRLowerable { +public class DynamicDeoptimizeNode extends AbstractDeoptimizeNode implements LIRLowerable, Canonicalizable { @Input private ValueNode actionAndReason; public DynamicDeoptimizeNode(ValueNode actionAndReason) { @@ -44,4 +46,15 @@ public void generate(LIRGeneratorTool generator) { generator.emitDeoptimize(generator.operand(actionAndReason), this); } + + @Override + public Node canonical(CanonicalizerTool tool) { + if (actionAndReason.isConstant()) { + Constant constant = actionAndReason.asConstant(); + DeoptimizeNode newDeopt = graph().add(new DeoptimizeNode(tool.getMetaAccess().decodeDeoptAction(constant), tool.getMetaAccess().decodeDeoptReason(constant))); + newDeopt.setDeoptimizationState(getDeoptimizationState()); + return newDeopt; + } + return this; + } } diff -r 134671fbf973 -r 2d8a8980eda8 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java Thu Oct 17 18:18:05 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java Thu Oct 17 18:18:05 2013 +0200 @@ -296,39 +296,39 @@ graph.replaceFloating((FloatingNode) node, canonical); } } else { - assert node instanceof FixedWithNextNode && node.predecessor() != null : node + " -> " + canonical + " : node should be fixed & connected (" + node.predecessor() + ")"; - FixedWithNextNode fixedWithNext = (FixedWithNextNode) node; - + assert node instanceof FixedNode && node.predecessor() != null : node + " -> " + canonical + " : node should be fixed & connected (" + node.predecessor() + ")"; + FixedNode fixed = (FixedNode) node; if (canonical instanceof ControlSinkNode) { // case 7 FixedWithNextNode pred = (FixedWithNextNode) node.predecessor(); - GraphUtil.killCFG(fixedWithNext); + GraphUtil.killCFG(fixed); pred.setNext((FixedNode) canonical); return true; - } - - // When removing a fixed node, new canonicalization - // opportunities for its successor may arise - assert fixedWithNext.next() != null; - tool.addToWorkList(fixedWithNext.next()); - - if (canonical == null) { - // case 3 - graph.removeFixed(fixedWithNext); - } else if (canonical instanceof FloatingNode) { - // case 4 - graph.replaceFixedWithFloating(fixedWithNext, (FloatingNode) canonical); } else { - assert canonical instanceof FixedNode; - if (canonical.predecessor() == null) { - assert !canonical.cfgSuccessors().iterator().hasNext() : "replacement " + canonical + " shouldn't have successors"; - // case 5 - graph.replaceFixedWithFixed(fixedWithNext, (FixedWithNextNode) canonical); + assert fixed instanceof FixedWithNextNode; + FixedWithNextNode fixedWithNext = (FixedWithNextNode) fixed; + // When removing a fixed node, new canonicalization + // opportunities for its successor may arise + assert fixedWithNext.next() != null; + tool.addToWorkList(fixedWithNext.next()); + if (canonical == null) { + // case 3 + graph.removeFixed(fixedWithNext); + } else if (canonical instanceof FloatingNode) { + // case 4 + graph.replaceFixedWithFloating(fixedWithNext, (FloatingNode) canonical); } else { - assert canonical.cfgSuccessors().iterator().hasNext() : "replacement " + canonical + " should have successors"; - // case 6 - node.replaceAtUsages(canonical); - graph.removeFixed(fixedWithNext); + assert canonical instanceof FixedNode; + if (canonical.predecessor() == null) { + assert !canonical.cfgSuccessors().iterator().hasNext() : "replacement " + canonical + " shouldn't have successors"; + // case 5 + graph.replaceFixedWithFixed(fixedWithNext, (FixedWithNextNode) canonical); + } else { + assert canonical.cfgSuccessors().iterator().hasNext() : "replacement " + canonical + " should have successors"; + // case 6 + node.replaceAtUsages(canonical); + graph.removeFixed(fixedWithNext); + } } } }