# HG changeset patch # User Lukas Stadler # Date 1359020263 -3600 # Node ID 727e869891fcb951812030775237531c769390a9 # Parent b30b33d9da80aedb46b19e74c8005433d9c51f2b let CheckCastSnippets insert UnsafeCastNodes (so that type stays visible during lowering) diff -r b30b33d9da80 -r 727e869891fc graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/CheckCastSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/CheckCastSnippets.java Thu Jan 24 08:16:41 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/CheckCastSnippets.java Thu Jan 24 10:37:43 2013 +0100 @@ -26,6 +26,7 @@ import static com.oracle.graal.api.meta.DeoptimizationReason.*; import static com.oracle.graal.hotspot.snippets.HotSpotSnippetUtils.*; import static com.oracle.graal.hotspot.snippets.TypeCheckSnippetUtils.*; +import static com.oracle.graal.nodes.extended.UnsafeCastNode.*; import static com.oracle.graal.snippets.SnippetTemplate.*; import static com.oracle.graal.snippets.SnippetTemplate.Arguments.*; import static com.oracle.graal.snippets.nodes.BranchProbabilityNode.*; @@ -76,17 +77,17 @@ if (checkNull && object == null) { probability(0.1); isNull.inc(); - return object; + } else { + Word objectHub = loadHub(object); + if (objectHub != exactHub) { + probability(0.01); + exactMiss.inc(); + //bkpt(object, exactHub, objectHub); + DeoptimizeNode.deopt(InvalidateReprofile, ClassCastException); + } + exactHit.inc(); } - Word objectHub = loadHub(object); - if (objectHub != exactHub) { - probability(0.01); - exactMiss.inc(); - //bkpt(object, exactHub, objectHub); - DeoptimizeNode.deopt(InvalidateReprofile, ClassCastException); - } - exactHit.inc(); - return object; + return unsafeCast(verifyOop(object), StampFactory.forNodeIntrinsic()); } /** @@ -103,16 +104,18 @@ @ConstantParameter("checkNull") boolean checkNull, @ConstantParameter("superCheckOffset") int superCheckOffset) { if (checkNull && object == null) { + probability(0.1); isNull.inc(); - return object; + } else { + Word objectHub = loadHub(object); + if (objectHub.readWord(superCheckOffset) != hub) { + probability(0.1); + displayMiss.inc(); + DeoptimizeNode.deopt(InvalidateReprofile, ClassCastException); + } + displayHit.inc(); } - Word objectHub = loadHub(object); - if (objectHub.readWord(superCheckOffset) != hub) { - displayMiss.inc(); - DeoptimizeNode.deopt(InvalidateReprofile, ClassCastException); - } - displayHit.inc(); - return object; + return unsafeCast(verifyOop(object), StampFactory.forNodeIntrinsic()); } /** @@ -125,23 +128,24 @@ @VarargsParameter("hints") Word[] hints, @ConstantParameter("checkNull") boolean checkNull) { if (checkNull && object == null) { + probability(0.1); isNull.inc(); - return object; - } - Word objectHub = loadHub(object); - // if we get an exact match: succeed immediately - ExplodeLoopNode.explodeLoop(); - for (int i = 0; i < hints.length; i++) { - Word hintHub = hints[i]; - if (hintHub == objectHub) { - hintsHit.inc(); - return object; + } else { + Word objectHub = loadHub(object); + // if we get an exact match: succeed immediately + ExplodeLoopNode.explodeLoop(); + for (int i = 0; i < hints.length; i++) { + Word hintHub = hints[i]; + if (hintHub == objectHub) { + hintsHit.inc(); + return unsafeCast(verifyOop(object), StampFactory.forNodeIntrinsic()); + } + } + if (!checkSecondarySubType(hub, objectHub)) { + DeoptimizeNode.deopt(InvalidateReprofile, ClassCastException); } } - if (!checkSecondarySubType(hub, objectHub)) { - DeoptimizeNode.deopt(InvalidateReprofile, ClassCastException); - } - return object; + return unsafeCast(verifyOop(object), StampFactory.forNodeIntrinsic()); } /** @@ -154,14 +158,15 @@ @Parameter("object") Object object, @ConstantParameter("checkNull") boolean checkNull) { if (checkNull && object == null) { + probability(0.1); isNull.inc(); - return object; + } else { + Word objectHub = loadHub(object); + if (!checkUnknownSubType(hub, objectHub)) { + DeoptimizeNode.deopt(InvalidateReprofile, ClassCastException); + } } - Word objectHub = loadHub(object); - if (!checkUnknownSubType(hub, objectHub)) { - DeoptimizeNode.deopt(InvalidateReprofile, ClassCastException); - } - return object; + return unsafeCast(verifyOop(object), StampFactory.forNodeIntrinsic()); } // @formatter:on diff -r b30b33d9da80 -r 727e869891fc 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 Thu Jan 24 08:16:41 2013 +0100 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java Thu Jan 24 10:37:43 2013 +0100 @@ -357,18 +357,17 @@ // Remove all frame states from inlined snippet graph. Snippets must be atomic (i.e. free // of side-effects that prevent deoptimizing to a point before the snippet). - List curSideEffectNodes = new ArrayList<>(); - Node curStampNode = null; + ArrayList curSideEffectNodes = new ArrayList<>(); + ArrayList curStampNodes = new ArrayList<>(); for (Node node : snippetCopy.getNodes()) { if (node instanceof ValueNode && ((ValueNode) node).stamp() == StampFactory.forNodeIntrinsic()) { - assert curStampNode == null : "Currently limited to one stamp node (but this can be converted to a List if necessary)"; - curStampNode = node; + curStampNodes.add((ValueNode) node); } if (node instanceof StateSplit) { StateSplit stateSplit = (StateSplit) node; FrameState frameState = stateSplit.stateAfter(); if (stateSplit.hasSideEffect()) { - curSideEffectNodes.add(node); + curSideEffectNodes.add((StateSplit) node); } if (frameState != null) { stateSplit.setStateAfter(null); @@ -399,7 +398,7 @@ } this.sideEffectNodes = curSideEffectNodes; - this.stampNode = curStampNode; + this.stampNodes = curStampNodes; this.returnNode = retNode; } @@ -457,12 +456,12 @@ * Nodes that inherit the {@link StateSplit#stateAfter()} from the replacee during * instantiation. */ - private final List sideEffectNodes; + private final ArrayList sideEffectNodes; /** - * Node that inherits the {@link ValueNode#stamp()} from the replacee during instantiation. + * The nodes that inherit the {@link ValueNode#stamp()} from the replacee during instantiation. */ - private final Node stampNode; + private final ArrayList stampNodes; /** * The nodes to be inlined when this specialization is instantiated. @@ -578,13 +577,13 @@ replacee.setNext(null); if (replacee instanceof StateSplit) { - for (Node sideEffectNode : sideEffectNodes) { + for (StateSplit sideEffectNode : sideEffectNodes) { assert ((StateSplit) replacee).hasSideEffect(); Node sideEffectDup = duplicates.get(sideEffectNode); ((StateSplit) sideEffectDup).setStateAfter(((StateSplit) replacee).stateAfter()); } } - if (stampNode != null) { + for (ValueNode stampNode : stampNodes) { Node stampDup = duplicates.get(stampNode); ((ValueNode) stampDup).setStamp(((ValueNode) replacee).stamp()); } @@ -651,13 +650,13 @@ replaceeGraph.addAfterFixed(lastFixedNode, firstCFGNodeDuplicate); if (replacee instanceof StateSplit) { - for (Node sideEffectNode : sideEffectNodes) { + for (StateSplit sideEffectNode : sideEffectNodes) { assert ((StateSplit) replacee).hasSideEffect(); Node sideEffectDup = duplicates.get(sideEffectNode); ((StateSplit) sideEffectDup).setStateAfter(((StateSplit) replacee).stateAfter()); } } - if (stampNode != null) { + for (ValueNode stampNode : stampNodes) { Node stampDup = duplicates.get(stampNode); ((ValueNode) stampDup).setStamp(((ValueNode) replacee).stamp()); }