# HG changeset patch # User Gilles Duboscq # Date 1336035946 -7200 # Node ID de571c017f6162fa983b1cbf0add2c89d27ce0b1 # Parent 00803ae428d2c9754b164eb3c578c4578d59edfd# Parent 077ec9468516d89c90b30709eedbda6907583f41 Merge diff -r 00803ae428d2 -r de571c017f61 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java Wed May 02 18:23:12 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java Thu May 03 11:05:46 2012 +0200 @@ -846,7 +846,7 @@ TTY.println("startBlock-ID: " + startBlock.getId()); // bailout of if this occurs in product mode. - throw new CiBailout("liveIn set of first block must be empty"); + throw new GraalInternalError("liveIn set of first block must be empty"); } } diff -r 00803ae428d2 -r de571c017f61 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 Wed May 02 18:23:12 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopTransformDataResolver.java Thu May 03 11:05:46 2012 +0200 @@ -29,6 +29,7 @@ import com.oracle.graal.graph.NodeClass.NodeClassIterator; import com.oracle.graal.graph.NodeClass.Position; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.PhiNode.PhiType; @@ -60,6 +61,7 @@ List newPhis = new LinkedList<>(); for (PhiNode phi : loopBegin.phis().snapshot()) { ValueNode first = null; + StructuredGraph graph = (StructuredGraph) loopBegin.graph(); if (loopBegin.loopEnds().count() == 1) { ValueNode b = phi.valueAt(loopBegin.loopEnds().first()); // back edge value first = prim(b); // corresponding value in the peel @@ -76,7 +78,7 @@ } } if (merge != null) { // found values of interest (backedge values that exist in the peel) - PhiNode firstPhi = loopBegin.graph().add(new PhiNode(phi.kind(), merge, phi.type())); + PhiNode firstPhi = graph.add(new PhiNode(phi.kind(), merge, phi.type())); for (EndNode end : merge.forwardEnds()) { LoopEndNode loopEnd = reverseEnds.get(end); ValueNode prim = prim(phi.valueAt(loopEnd)); @@ -85,10 +87,13 @@ } 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); + } } } if (first != null) { // create a new phi (we don't patch the old one since some usages of the old one may still be valid) - PhiNode newPhi = loopBegin.graph().add(new PhiNode(phi.kind(), loopBegin, phi.type())); + PhiNode newPhi = graph.add(new PhiNode(phi.kind(), loopBegin, phi.type())); newPhi.addInput(first); for (LoopEndNode end : loopBegin.orderedLoopEnds()) { newPhi.addInput(phi.valueAt(end)); diff -r 00803ae428d2 -r de571c017f61 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 Wed May 02 18:23:12 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/SuperBlock.java Thu May 03 11:05:46 2012 +0200 @@ -185,8 +185,8 @@ replaceWith = phi; } else { assert vpn.type() == PhiType.Virtual; - VirtualObjectFieldNode vof = (VirtualObjectFieldNode) GraphUtil.unProxify(vpn); - VirtualObjectFieldNode newVof = (VirtualObjectFieldNode) GraphUtil.unProxify(newVpn); + ValueNode vof = GraphUtil.unProxify(vpn); + ValueNode newVof = GraphUtil.unProxify(newVpn); replaceWith = mergeVirtualChain(graph, vof, newVof, phi, earlyExit, newEarlyExit, merge); } } else { @@ -217,14 +217,14 @@ private static ValueNode mergeVirtualChain( StructuredGraph graph, - VirtualObjectFieldNode vof, - VirtualObjectFieldNode newVof, + ValueNode vof, + ValueNode newVof, PhiNode vPhi, BeginNode earlyExit, BeginNode newEarlyExit, MergeNode merge) { - VirtualObjectNode vObject = vof.object(); - assert newVof.object() == vObject; + VirtualObjectNode vObject = virtualObject(vof); + assert virtualObject(newVof) == vObject; ValueNode[] virtualState = virtualState(vof); ValueNode[] newVirtualState = virtualState(newVof); ValueNode chain = vPhi; @@ -250,8 +250,57 @@ return chain; } - private static ValueNode[] virtualState(VirtualObjectFieldNode vof) { - VirtualObjectNode vObj = vof.object(); + public static ValueNode mergeVirtualChain( + StructuredGraph graph, + PhiNode vPhi, + MergeNode merge) { + NodeInputList virtuals = vPhi.values(); + VirtualObjectNode vObject = virtualObject(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, PhiType.Value)); + 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]; diff -r 00803ae428d2 -r de571c017f61 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/BoxingEliminationPhase.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/BoxingEliminationPhase.java Wed May 02 18:23:12 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/BoxingEliminationPhase.java Thu May 03 11:05:46 2012 +0200 @@ -68,7 +68,7 @@ PhiNode result = null; if (phiNode.stamp().nonNull()) { RiResolvedType exactType = phiNode.stamp().exactType(); - if (exactType != null && exactType.toJava() == kind.toUnboxedJavaClass()) { + if (exactType != null && exactType.toJava() == kind.toBoxedJavaClass()) { StructuredGraph graph = (StructuredGraph) phiNode.graph(); result = graph.add(new PhiNode(kind, phiNode.merge(), PhiType.Value)); phiReplacements.put(phiNode, result); diff -r 00803ae428d2 -r de571c017f61 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotCompiledMethod.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotCompiledMethod.java Wed May 02 18:23:12 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotCompiledMethod.java Thu May 03 11:05:46 2012 +0200 @@ -79,7 +79,7 @@ if (arg == null) { assert sig[i].isObject() : CiUtil.format("%H.%n(%p): expected arg ", method) + i + " to be Object, not " + sig[i]; } else if (!sig[i].isObject()) { - assert sig[i].toUnboxedJavaClass() == arg.getClass() : CiUtil.format("%H.%n(%p): expected arg ", method) + i + " to be " + sig[i] + ", not " + arg.getClass(); + assert sig[i].toBoxedJavaClass() == arg.getClass() : CiUtil.format("%H.%n(%p): expected arg ", method) + i + " to be " + sig[i] + ", not " + arg.getClass(); } } return true; diff -r 00803ae428d2 -r de571c017f61 graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiKind.java --- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiKind.java Wed May 02 18:23:12 2012 +0200 +++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiKind.java Thu May 03 11:05:46 2012 +0200 @@ -186,7 +186,7 @@ // Checkstyle: resume } - public Class< ? > toUnboxedJavaClass() { + public Class< ? > toBoxedJavaClass() { // Checkstyle: stop switch(this) { case Void: return null;