# HG changeset patch # User Christian Wimmer # Date 1444856026 25200 # Node ID 209d958f3b9d96ee20587950c1be555d948357b8 # Parent 2f752d0432d24a8314c97a261c30e5d852b55491 Allow subclasses of BytecodeParser to disable loop safepoint checks; store flag in LoopBeginNode to avoid problems when control flow optimizations introduce a new LoopEndNode diff -r 2f752d0432d2 -r 209d958f3b9d graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/MonitorDeoptTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/MonitorDeoptTest.java Wed Oct 14 13:52:03 2015 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/MonitorDeoptTest.java Wed Oct 14 13:53:46 2015 -0700 @@ -36,7 +36,6 @@ import com.oracle.graal.nodes.FixedNode; import com.oracle.graal.nodes.FixedWithNextNode; import com.oracle.graal.nodes.LoopBeginNode; -import com.oracle.graal.nodes.LoopEndNode; import com.oracle.graal.nodes.StructuredGraph; import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; @@ -134,9 +133,7 @@ */ private static void removeLoopSafepoint(StructuredGraph graph) { LoopBeginNode loopBegin = findFirstLoop(graph); - for (LoopEndNode end : loopBegin.loopEnds()) { - end.disableSafepoint(); - } + loopBegin.disableSafepoint(); } @Test diff -r 2f752d0432d2 -r 209d958f3b9d graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeParser.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeParser.java Wed Oct 14 13:52:03 2015 -0700 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeParser.java Wed Oct 14 13:53:46 2015 -0700 @@ -928,9 +928,6 @@ } LoopBeginNode loopBegin = (LoopBeginNode) ((EndNode) merge.next()).merge(); LoopEndNode loopEnd = graph.add(new LoopEndNode(loopBegin)); - if (parsingIntrinsic()) { - loopEnd.disableSafepoint(); - } endNode.replaceAndDelete(loopEnd); } else if (visited.contains(n)) { // Normal merge into a branch we are already exploring. @@ -2309,9 +2306,6 @@ */ LoopBeginNode loopBegin = (LoopBeginNode) getFirstInstruction(block, operatingDimension); LoopEndNode loopEnd = graph.add(new LoopEndNode(loopBegin)); - if (parsingIntrinsic()) { - loopEnd.disableSafepoint(); - } Target target = checkLoopExit(loopEnd, block, state); FixedNode result = target.fixed; getEntryState(block, operatingDimension).merge(loopBegin, target.state); @@ -2700,9 +2694,17 @@ return true; } + /* Also a hook for subclasses. */ + protected boolean disableLoopSafepoint() { + return parsingIntrinsic(); + } + private LoopBeginNode appendLoopBegin(FixedWithNextNode fixedWithNext) { EndNode preLoopEnd = graph.add(new EndNode()); LoopBeginNode loopBegin = graph.add(new LoopBeginNode()); + if (disableLoopSafepoint()) { + loopBegin.disableSafepoint(); + } fixedWithNext.setNext(preLoopEnd); // Add the single non-loop predecessor of the loop header. loopBegin.addForwardEnd(preLoopEnd); diff -r 2f752d0432d2 -r 209d958f3b9d graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopSafepointEliminationPhase.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopSafepointEliminationPhase.java Wed Oct 14 13:52:03 2015 -0700 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopSafepointEliminationPhase.java Wed Oct 14 13:53:46 2015 -0700 @@ -48,9 +48,7 @@ } if (hasSafepoint) { loop.counted().createOverFlowGuard(); - for (LoopEndNode loopEnd : loop.loopBegin().loopEnds()) { - loopEnd.disableSafepoint(); - } + loop.loopBegin().disableSafepoint(); } } } diff -r 2f752d0432d2 -r 209d958f3b9d graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java Wed Oct 14 13:52:03 2015 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java Wed Oct 14 13:53:46 2015 -0700 @@ -49,12 +49,19 @@ protected int nextEndIndex; protected int unswitches; protected int inversionCount; + boolean canSafepoint; @OptionalInput(InputType.Guard) GuardingNode overflowGuard; public LoopBeginNode() { super(TYPE); loopFrequency = 1; + this.canSafepoint = true; + } + + /** Disables safepoint for the whole loop, i.e., for all {@link LoopEndNode loop ends}. */ + public void disableSafepoint() { + this.canSafepoint = false; } public double loopFrequency() { diff -r 2f752d0432d2 -r 209d958f3b9d graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopEndNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopEndNode.java Wed Oct 14 13:52:03 2015 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopEndNode.java Wed Oct 14 13:53:46 2015 -0700 @@ -39,7 +39,7 @@ public static final NodeClass TYPE = NodeClass.create(LoopEndNode.class); @Input(InputType.Association) LoopBeginNode loopBegin; - protected boolean canSafepoint; + private boolean canSafepoint; protected int endIndex; public LoopEndNode(LoopBeginNode begin) { @@ -65,12 +65,16 @@ this.loopBegin = x; } + /** + * Disables safepoints for only this loop end (in contrast to disabling it for + * {@link LoopBeginNode#disableSafepoint() the whole loop}. + */ public void disableSafepoint() { this.canSafepoint = false; } public boolean canSafepoint() { - return canSafepoint; + return canSafepoint && loopBegin.canSafepoint; } @Override