# HG changeset patch # User Gilles Duboscq # Date 1333719855 -7200 # Node ID 09e87f5b81e42b172e41f3b3e51ea3f915072648 # Parent 450af990078ff57bd3a5529b60b46b71e661ba01 Fix potential KillCFG problem Handle VirtualObjectField and VirtualObject better in killCFG diff -r 450af990078f -r 09e87f5b81e4 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java Fri Apr 06 15:23:58 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java Fri Apr 06 15:44:15 2012 +0200 @@ -27,8 +27,10 @@ import java.util.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.iterators.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.virtual.*; public class GraphUtil { @@ -40,7 +42,11 @@ killEnd(end); } else { // Normal control flow node. - for (Node successor : node.successors().snapshot()) { + /* We do not take a successor snapshot because this iterator supports concurrent modifications + * as long as they do not change the size of the successor list. Not tasking a snapshot allows + * us to see modifications to other branches that may happen while processing one branch. + */ + for (Node successor : node.successors()) { killCFG((FixedNode) successor); } } @@ -50,6 +56,7 @@ private static void killEnd(EndNode end) { MergeNode merge = end.merge(); merge.removeEnd(end); + StructuredGraph graph = (StructuredGraph) end.graph(); if (merge instanceof LoopBeginNode && merge.forwardEndCount() == 0) { //dead loop for (PhiNode phi : merge.phis().snapshot()) { propagateKill(phi); @@ -63,15 +70,19 @@ killCFG(begin.next()); begin.safeDelete(); } else if (merge instanceof LoopBeginNode && ((LoopBeginNode) merge).loopEnds().isEmpty()) { // not a loop anymore - ((StructuredGraph) end.graph()).reduceDegenerateLoopBegin((LoopBeginNode) merge); + graph.reduceDegenerateLoopBegin((LoopBeginNode) merge); } else if (merge.phiPredecessorCount() == 1) { // not a merge anymore - ((StructuredGraph) end.graph()).reduceTrivialMerge(merge); + graph.reduceTrivialMerge(merge); } } + public static NodePredicate isFloatingNode() { + return isA(FloatingNode.class).or(CallTargetNode.class).or(FrameState.class).or(VirtualObjectFieldNode.class).or(VirtualObjectNode.class); + } + public static void propagateKill(Node node) { if (node != null && node.isAlive()) { - List usagesSnapshot = node.usages().filter(isA(FloatingNode.class).or(CallTargetNode.class).or(FrameState.class)).snapshot(); + List usagesSnapshot = node.usages().filter(isFloatingNode()).snapshot(); // null out remaining usages node.replaceAtUsages(null); @@ -91,7 +102,7 @@ } public static void killUnusedFloatingInputs(Node node) { - List floatingInputs = node.inputs().filter(isA(FloatingNode.class).or(CallTargetNode.class).or(FrameState.class)).snapshot(); + List floatingInputs = node.inputs().filter(isFloatingNode()).snapshot(); node.safeDelete(); for (Node in : floatingInputs) {