# HG changeset patch # User Gilles Duboscq # Date 1338910728 -7200 # Node ID 9743ae819f7350871ce8fc44f82ad2ee83078bc9 # Parent 85986efe747eeb6ab5fd20d826e80060551443d3 Move virtual chain help methods from SuperBlock to GraphUtil Rename replaceAtPredecessors to replaceAtPredecessor diff -r 85986efe747e -r 9743ae819f73 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopTransformDataResolver.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopTransformDataResolver.java Mon Jun 04 16:15:56 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopTransformDataResolver.java Tue Jun 05 17:38:48 2012 +0200 @@ -30,6 +30,7 @@ import com.oracle.graal.graph.NodeClass.Position; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.PhiNode.PhiType; +import com.oracle.graal.nodes.util.*; @@ -88,7 +89,7 @@ first = firstPhi; merge.stateAfter().replaceFirstInput(phi, firstPhi); // fix the merge's state after (see SuperBlock.mergeExits) if (phi.type() == PhiType.Virtual) { - first = SuperBlock.mergeVirtualChain(graph, firstPhi, merge); + first = GraphUtil.mergeVirtualChain(graph, firstPhi, merge); } } } diff -r 85986efe747e -r 9743ae819f73 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/SuperBlock.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/SuperBlock.java Mon Jun 04 16:15:56 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/SuperBlock.java Tue Jun 05 17:38:48 2012 +0200 @@ -29,7 +29,6 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.PhiNode.PhiType; import com.oracle.graal.nodes.util.*; -import com.oracle.graal.nodes.virtual.*; public class SuperBlock { protected BeginNode entry; @@ -165,7 +164,7 @@ EndNode end = endsToMerge.get(0); assert end.usages().count() == 0; newExit = graph.add(new BeginNode()); - end.replaceAtPredecessors(newExit); + end.replaceAtPredecessor(newExit); end.safeDelete(); } else { assert endsToMerge.size() > 1; @@ -224,7 +223,7 @@ assert vpn.type() == PhiType.Virtual; ValueNode vof = GraphUtil.unProxify(vpn); ValueNode newVof = GraphUtil.unProxify(newVpn); - replaceWith = mergeVirtualChain(graph, vof, newVof, phi, earlyExit, newEarlyExit, merge); + replaceWith = GraphUtil.mergeVirtualChain(graph, vof, newVof, phi, earlyExit, newEarlyExit, merge); } } else { replaceWith = vpn.value(); @@ -239,130 +238,6 @@ } } - private static ValueProxyNode findProxy(ValueNode value, BeginNode proxyPoint) { - for (ValueProxyNode vpn : proxyPoint.proxies()) { - ValueNode v = vpn; - while (v instanceof ValueProxyNode) { - v = ((ValueProxyNode) v).value(); - if (v == value) { - return vpn; - } - } - } - return null; - } - - private static ValueNode mergeVirtualChain( - StructuredGraph graph, - ValueNode vof, - ValueNode newVof, - PhiNode vPhi, - BeginNode earlyExit, - BeginNode newEarlyExit, - MergeNode merge) { - VirtualObjectNode vObject = virtualObject(vof); - assert virtualObject(newVof) == vObject; - ValueNode[] virtualState = virtualState(vof); - ValueNode[] newVirtualState = virtualState(newVof); - ValueNode chain = vPhi; - for (int i = 0; i < virtualState.length; i++) { - ValueNode value = virtualState[i]; - ValueNode newValue = newVirtualState[i]; - assert value.kind() == newValue.kind(); - if (value != newValue) { - PhiNode valuePhi = graph.add(new PhiNode(value.kind(), merge)); - ValueProxyNode inputProxy = findProxy(value, earlyExit); - if (inputProxy != null) { - ValueProxyNode newInputProxy = findProxy(newValue, newEarlyExit); - assert newInputProxy != null : "no proxy for " + newValue + " at " + newEarlyExit; - valuePhi.addInput(inputProxy); - valuePhi.addInput(newInputProxy); - } else { - valuePhi.addInput(graph.unique(new ValueProxyNode(value, earlyExit, PhiType.Value))); - valuePhi.addInput(newValue); - } - chain = graph.add(new VirtualObjectFieldNode(vObject, chain, valuePhi, i)); - } - } - return chain; - } - - public static ValueNode mergeVirtualChain( - StructuredGraph graph, - PhiNode vPhi, - MergeNode merge) { - NodeInputList virtuals = vPhi.values(); - VirtualObjectNode vObject = virtualObject(GraphUtil.unProxify(virtuals.first())); - List virtualStates = new ArrayList<>(virtuals.size()); - for (ValueNode virtual : virtuals) { - virtualStates.add(virtualState(GraphUtil.unProxify(virtual))); - } - ValueNode chain = vPhi; - int stateLength = virtualStates.get(0).length; - for (int i = 0; i < stateLength; i++) { - ValueNode v = null; - boolean reconcile = false; - for (ValueNode[] state : virtualStates) { - if (v == null) { - v = state[i]; - } else if (v != state[i]) { - reconcile = true; - break; - } - assert v.kind() == state[i].kind(); - } - if (reconcile) { - PhiNode valuePhi = graph.add(new PhiNode(v.kind(), merge)); - for (ValueNode[] state : virtualStates) { - valuePhi.addInput(state[i]); - } - chain = graph.add(new VirtualObjectFieldNode(vObject, chain, valuePhi, i)); - } - } - return chain; - } - - private static VirtualObjectNode virtualObject(ValueNode vof) { - assert vof instanceof VirtualObjectFieldNode || (vof instanceof PhiNode && ((PhiNode) vof).type() == PhiType.Virtual) : vof; - ValueNode currentField = vof; - do { - if (currentField instanceof VirtualObjectFieldNode) { - return ((VirtualObjectFieldNode) currentField).object(); - } else { - assert currentField instanceof PhiNode && ((PhiNode) currentField).type() == PhiType.Virtual : currentField; - currentField = ((PhiNode) currentField).valueAt(0); - } - } while (currentField != null); - throw new GraalInternalError("Invalid virtual chain : cound not find virtual object from %s", vof); - } - - private static ValueNode[] virtualState(ValueNode vof) { - VirtualObjectNode vObj = virtualObject(vof); - int fieldsCount = vObj.fieldsCount(); - int dicovered = 0; - ValueNode[] state = new ValueNode[fieldsCount]; - ValueNode currentField = vof; - do { - if (currentField instanceof VirtualObjectFieldNode) { - int index = ((VirtualObjectFieldNode) currentField).index(); - if (state[index] == null) { - dicovered++; - state[index] = ((VirtualObjectFieldNode) currentField).input(); - if (dicovered >= fieldsCount) { - break; - } - } - currentField = ((VirtualObjectFieldNode) currentField).lastState(); - } else if (currentField instanceof ValueProxyNode) { - currentField = ((ValueProxyNode) currentField).value(); - } else { - assert currentField instanceof PhiNode && ((PhiNode) currentField).type() == PhiType.Virtual : currentField; - currentField = ((PhiNode) currentField).valueAt(0); - } - } while (currentField != null); - return state; - } - private NodeBitMap computeNodes() { NodeBitMap nodes = entry.graph().createNodeBitMap(); for (BeginNode b : blocks) { @@ -432,7 +307,7 @@ public void insertBefore(FixedNode fixed) { assert entry.predecessor() == null; assert exit.next() == null; - fixed.replaceAtPredecessors(entry); + fixed.replaceAtPredecessor(entry); exit.setNext(fixed); } } diff -r 85986efe747e -r 9743ae819f73 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/ConvertDeoptimizeToGuardPhase.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/ConvertDeoptimizeToGuardPhase.java Mon Jun 04 16:15:56 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/ConvertDeoptimizeToGuardPhase.java Tue Jun 05 17:38:48 2012 +0200 @@ -90,7 +90,7 @@ FixedNode next = otherBegin.next(); otherBegin.setNext(null); guard.setNext(next); - ifNode.replaceAtPredecessors(guard); + ifNode.replaceAtPredecessor(guard); GraphUtil.killCFG(ifNode); } } diff -r 85986efe747e -r 9743ae819f73 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/SnippetIntrinsificationPhase.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/SnippetIntrinsificationPhase.java Mon Jun 04 16:15:56 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/SnippetIntrinsificationPhase.java Tue Jun 05 17:38:48 2012 +0200 @@ -267,7 +267,7 @@ } FixedNode next = checkCastNode.next(); checkCastNode.setNext(null); - checkCastNode.replaceAtPredecessors(next); + checkCastNode.replaceAtPredecessor(next); GraphUtil.killCFG(checkCastNode); } } diff -r 85986efe747e -r 9743ae819f73 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/util/InliningUtil.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/util/InliningUtil.java Mon Jun 04 16:15:56 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/util/InliningUtil.java Tue Jun 05 17:38:48 2012 +0200 @@ -806,7 +806,7 @@ if (receiverNullCheck) { receiverNullCheck(invoke); } - invoke.node().replaceAtPredecessors(firstCFGNodeDuplicate); + invoke.node().replaceAtPredecessor(firstCFGNodeDuplicate); FrameState stateAtExceptionEdge = null; if (invoke instanceof InvokeWithExceptionNode) { diff -r 85986efe747e -r 9743ae819f73 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java Mon Jun 04 16:15:56 2012 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java Tue Jun 05 17:38:48 2012 +0200 @@ -202,10 +202,10 @@ } /** - * Updates the predecessor sets of the given nodes after a successor slot is changed from oldSuccessor to newSuccessor: + * Updates the predecessor of the given nodes after a successor slot is changed from oldSuccessor to newSuccessor: * removes this node from oldSuccessor's predecessors and adds this node to newSuccessor's predecessors. */ - protected void updatePredecessors(Node oldSuccessor, Node newSuccessor) { + protected void updatePredecessor(Node oldSuccessor, Node newSuccessor) { assert assertTrue(usages != null, "usages == null while adding %s to %s", newSuccessor, this); if (oldSuccessor != newSuccessor) { if (oldSuccessor != null) { @@ -228,7 +228,7 @@ updateUsages(null, input); } for (Node successor : successors()) { - updatePredecessors(null, successor); + updatePredecessor(null, successor); } } @@ -262,12 +262,12 @@ usages.clear(); } - public void replaceAtPredecessors(Node other) { + public void replaceAtPredecessor(Node other) { assert checkReplaceWith(other); if (predecessor != null) { boolean result = predecessor.getNodeClass().replaceFirstSuccessor(predecessor, this, other); assert assertTrue(result, "not found in successors, predecessor: %s", predecessor); - predecessor.updatePredecessors(this, other); + predecessor.updatePredecessor(this, other); } } @@ -276,14 +276,14 @@ if (other != null) { clearSuccessors(); replaceAtUsages(other); - replaceAtPredecessors(other); + replaceAtPredecessor(other); } safeDelete(); } public void replaceFirstSuccessor(Node oldSuccessor, Node newSuccessor) { if (getNodeClass().replaceFirstSuccessor(this, oldSuccessor, newSuccessor)) { - updatePredecessors(oldSuccessor, newSuccessor); + updatePredecessor(oldSuccessor, newSuccessor); } } diff -r 85986efe747e -r 9743ae819f73 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Mon Jun 04 16:15:56 2012 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Tue Jun 05 17:38:48 2012 +0200 @@ -663,7 +663,7 @@ if (pos.input) { node.updateUsages(old, x); } else { - node.updatePredecessors(old, x); + node.updatePredecessor(old, x); } } else { NodeList list = getNodeList(node, offset); diff -r 85986efe747e -r 9743ae819f73 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeSuccessorList.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeSuccessorList.java Mon Jun 04 16:15:56 2012 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeSuccessorList.java Tue Jun 05 17:38:48 2012 +0200 @@ -43,7 +43,7 @@ @Override protected void update(T oldNode, T newNode) { - self.updatePredecessors(oldNode, newNode); + self.updatePredecessor(oldNode, newNode); } @Override diff -r 85986efe747e -r 9743ae819f73 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java Mon Jun 04 16:15:56 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java Tue Jun 05 17:38:48 2012 +0200 @@ -147,7 +147,7 @@ if (node instanceof FixedWithNextNode) { ((StructuredGraph) graph()).replaceFixedWithFixed(this, (FixedWithNextNode) node); } else if (node instanceof DeoptimizeNode) { - this.replaceAtPredecessors(node); + this.replaceAtPredecessor(node); this.replaceAtUsages(null); GraphUtil.killCFG(this); return; diff -r 85986efe747e -r 9743ae819f73 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java Mon Jun 04 16:15:56 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java Tue Jun 05 17:38:48 2012 +0200 @@ -185,7 +185,7 @@ assert kind() == CiKind.Void && usages().isEmpty(); ((StructuredGraph) graph()).removeSplit(this, NORMAL_EDGE); } else if (node instanceof DeoptimizeNode) { - this.replaceAtPredecessors(node); + this.replaceAtPredecessor(node); this.replaceAtUsages(null); GraphUtil.killCFG(this); return; diff -r 85986efe747e -r 9743ae819f73 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MergeNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MergeNode.java Mon Jun 04 16:15:56 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MergeNode.java Tue Jun 05 17:38:48 2012 +0200 @@ -177,7 +177,7 @@ phi.addInput(newInput); } this.removeEnd(end); - end.replaceAtPredecessors(newEnd); + end.replaceAtPredecessor(newEnd); end.safeDelete(); tool.addToWorkList(newEnd.predecessor()); // ? } diff -r 85986efe747e -r 9743ae819f73 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ScheduledNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ScheduledNode.java Mon Jun 04 16:15:56 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ScheduledNode.java Tue Jun 05 17:38:48 2012 +0200 @@ -35,7 +35,7 @@ } public void setScheduledNext(ScheduledNode x) { - updatePredecessors(scheduledNext, x); + updatePredecessor(scheduledNext, x); scheduledNext = x; } diff -r 85986efe747e -r 9743ae819f73 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Mon Jun 04 16:15:56 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Tue Jun 05 17:38:48 2012 +0200 @@ -201,7 +201,7 @@ assert node.usages().isEmpty() : node + " " + node.usages(); FixedNode next = node.next(); node.setNext(null); - node.replaceAtPredecessors(next); + node.replaceAtPredecessor(next); node.safeDelete(); } @@ -228,7 +228,7 @@ assert node != null && replacement != null && node.isAlive() && replacement.isAlive() : "cannot replace " + node + " with " + replacement; FixedNode next = node.next(); node.setNext(null); - node.replaceAtPredecessors(next); + node.replaceAtPredecessor(next); node.replaceAtUsages(replacement); node.safeDelete(); } @@ -241,7 +241,7 @@ for (int i = 0; i < node.blockSuccessorCount(); i++) { node.setBlockSuccessor(i, null); } - node.replaceAtPredecessors(begin); + node.replaceAtPredecessor(begin); node.safeDelete(); } @@ -258,7 +258,7 @@ } } if (begin.isAlive()) { - node.replaceAtPredecessors(begin); + node.replaceAtPredecessor(begin); node.safeDelete(); } else { assert node.isDeleted(); @@ -293,7 +293,7 @@ for (int i = 0; i < node.blockSuccessorCount(); i++) { node.setBlockSuccessor(i, null); } - node.replaceAtPredecessors(begin); + node.replaceAtPredecessor(begin); node.replaceAtUsages(replacement); node.safeDelete(); } @@ -353,7 +353,7 @@ stateAfter.safeDelete(); } if (sux == null) { - singleEnd.replaceAtPredecessors(null); + singleEnd.replaceAtPredecessor(null); singleEnd.safeDelete(); } else { singleEnd.replaceAndDelete(sux); diff -r 85986efe747e -r 9743ae819f73 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 Mon Jun 04 16:15:56 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java Tue Jun 05 17:38:48 2012 +0200 @@ -30,6 +30,7 @@ import com.oracle.graal.graph.iterators.*; import com.oracle.graal.graph.iterators.NodePredicates.PositiveTypePredicate; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.PhiNode.PhiType; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.virtual.*; @@ -95,7 +96,7 @@ // null out remaining usages node.replaceAtUsages(null); - node.replaceAtPredecessors(null); + node.replaceAtPredecessor(null); killWithUnusedFloatingInputs(node); for (Node usage : usagesSnapshot) { @@ -186,4 +187,144 @@ } return v; } + + private static ValueProxyNode findProxy(ValueNode value, BeginNode proxyPoint) { + for (ValueProxyNode vpn : proxyPoint.proxies()) { + ValueNode v = vpn; + while (v instanceof ValueProxyNode) { + v = ((ValueProxyNode) v).value(); + if (v == value) { + return vpn; + } + } + } + return null; + } + + public static ValueNode mergeVirtualChain( + StructuredGraph graph, + ValueNode vof, + ValueNode newVof, + PhiNode vPhi, + BeginNode earlyExit, + BeginNode newEarlyExit, + MergeNode merge) { + VirtualObjectNode vObject = virtualObject(vof); + assert virtualObject(newVof) == vObject; + ValueNode[] virtualState = virtualState(vof); + ValueNode[] newVirtualState = virtualState(newVof); + ValueNode chain = vPhi; + for (int i = 0; i < virtualState.length; i++) { + ValueNode value = virtualState[i]; + ValueNode newValue = newVirtualState[i]; + assert value.kind() == newValue.kind(); + if (value != newValue) { + PhiNode valuePhi = graph.add(new PhiNode(value.kind(), merge)); + ValueProxyNode inputProxy = findProxy(value, earlyExit); + if (inputProxy != null) { + ValueProxyNode newInputProxy = findProxy(newValue, newEarlyExit); + assert newInputProxy != null : "no proxy for " + newValue + " at " + newEarlyExit; + valuePhi.addInput(inputProxy); + valuePhi.addInput(newInputProxy); + } else { + valuePhi.addInput(graph.unique(new ValueProxyNode(value, earlyExit, PhiType.Value))); + valuePhi.addInput(newValue); + } + chain = graph.add(new VirtualObjectFieldNode(vObject, chain, valuePhi, i)); + } + } + return chain; + } + + public static ValueNode mergeVirtualChain( + StructuredGraph graph, + PhiNode vPhi, + MergeNode merge) { + NodeInputList virtuals = vPhi.values(); + VirtualObjectNode vObject = virtualObject(unProxify(virtuals.first())); + List virtualStates = new ArrayList<>(virtuals.size()); + for (ValueNode virtual : virtuals) { + virtualStates.add(virtualState(unProxify(virtual))); + } + ValueNode chain = vPhi; + int stateLength = virtualStates.get(0).length; + for (int i = 0; i < stateLength; i++) { + ValueNode v = null; + boolean reconcile = false; + for (ValueNode[] state : virtualStates) { + if (v == null) { + v = state[i]; + } else if (v != state[i]) { + reconcile = true; + break; + } + assert v.kind() == state[i].kind(); + } + if (reconcile) { + PhiNode valuePhi = graph.add(new PhiNode(v.kind(), merge)); + for (ValueNode[] state : virtualStates) { + valuePhi.addInput(state[i]); + } + chain = graph.add(new VirtualObjectFieldNode(vObject, chain, valuePhi, i)); + } + } + return chain; + } + + /** + * Returns the VirtualObjectNode associated with the virtual chain of the provided virtual node. + * @param vof a virtual ValueNode (a VirtualObjectFieldNode or a Virtual Phi) + * @return the VirtualObjectNode associated with the virtual chain of the provided virtual node. + */ + public static VirtualObjectNode virtualObject(ValueNode vof) { + assert vof instanceof VirtualObjectFieldNode || (vof instanceof PhiNode && ((PhiNode) vof).type() == PhiType.Virtual) : vof; + ValueNode currentField = vof; + do { + if (currentField instanceof VirtualObjectFieldNode) { + return ((VirtualObjectFieldNode) currentField).object(); + } else { + assert currentField instanceof PhiNode && ((PhiNode) currentField).type() == PhiType.Virtual : currentField; + currentField = ((PhiNode) currentField).valueAt(0); + } + } while (currentField != null); + throw new GraalInternalError("Invalid virtual chain : cound not find virtual object from %s", vof); + } + + /** + * Builds the state of the virtual object at the provided point into a virtual chain. + * @param vof a virtual ValueNode (a VirtualObjectFieldNode or a Virtual Phi) + * @return the state of the virtual object at the provided point into a virtual chain. + */ + public static ValueNode[] virtualState(ValueNode vof) { + return virtualState(vof, virtualObject(vof)); + } + + /** + * Builds the state of the virtual object at the provided point into a virtual chain. + * @param vof a virtual ValueNode (a VirtualObjectFieldNode or a Virtual Phi) + * @param vObj the virtual object + * @return the state of the virtual object at the provided point into a virtual chain. + */ + public static ValueNode[] virtualState(ValueNode vof, VirtualObjectNode vObj) { + int fieldsCount = vObj.fieldsCount(); + int dicovered = 0; + ValueNode[] state = new ValueNode[fieldsCount]; + ValueNode currentField = vof; + do { + if (currentField instanceof VirtualObjectFieldNode) { + int index = ((VirtualObjectFieldNode) currentField).index(); + if (state[index] == null) { + dicovered++; + state[index] = ((VirtualObjectFieldNode) currentField).input(); + } + currentField = ((VirtualObjectFieldNode) currentField).lastState(); + } else if (currentField instanceof ValueProxyNode) { + currentField = ((ValueProxyNode) currentField).value(); + } else { + assert currentField instanceof PhiNode && ((PhiNode) currentField).type() == PhiType.Virtual : currentField; + currentField = ((PhiNode) currentField).valueAt(0); + } + } while (currentField != null && dicovered < fieldsCount); + return state; + } } diff -r 85986efe747e -r 9743ae819f73 graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java --- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java Mon Jun 04 16:15:56 2012 +0200 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java Tue Jun 05 17:38:48 2012 +0200 @@ -144,7 +144,7 @@ FixedNode explodeLoopNext = explodeLoop.next(); explodeLoop.clearSuccessors(); - explodeLoop.replaceAtPredecessors(explodeLoopNext); + explodeLoop.replaceAtPredecessor(explodeLoopNext); explodeLoop.replaceAtUsages(null); GraphUtil.killCFG(explodeLoop); break; @@ -296,7 +296,7 @@ // Re-wire the control flow graph around the replacee FixedNode firstCFGNodeDuplicate = (FixedNode) duplicates.get(firstCFGNode); - anchor.replaceAtPredecessors(firstCFGNodeDuplicate); + anchor.replaceAtPredecessor(firstCFGNodeDuplicate); FixedNode next = anchor.next(); anchor.setNext(null);