# HG changeset patch # User Bernhard Urban # Date 1364407890 -3600 # Node ID 2978a819763b73ee4414c2ffa24144059401e3ba # Parent 3cf7d22b14dde7f03d586acf2ed320780e6ea843 CheckCastSnippets: anchor UnsafeCast with subclass tests diff -r 3cf7d22b14dd -r 2978a819763b graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCast.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCast.java Wed Mar 27 22:30:03 2013 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCast.java Wed Mar 27 19:11:30 2013 +0100 @@ -43,6 +43,8 @@ * typecheck itself. With special crafting, it's possible to get the scheduler moving the * FloatingReadNode before the typecheck. Assuming the object is of the wrong type (here for * example A), an invalid field read is done. + * + * In order to avoid this situation, an anchor node is introduced in CheckCastSnippts. */ public class ReadAfterCheckCast extends GraphScheduleTest { @@ -71,7 +73,6 @@ } } - @Ignore @Test public void test1() { test("test1Snippet"); diff -r 3cf7d22b14dd -r 2978a819763b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastSnippets.java Wed Mar 27 22:30:03 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastSnippets.java Wed Mar 27 19:11:30 2013 +0100 @@ -81,7 +81,11 @@ } exactHit.inc(); } - return unsafeCast(verifyOop(object), StampFactory.forNodeIntrinsic()); + /** + * make sure that the unsafeCast is done *after* the check above, + * cf. {@link ReadAfterCheckCast}*/ + BeginNode anchorNode = BeginNode.anchor(StampFactory.forNodeIntrinsic()); + return unsafeCast(verifyOop(object), StampFactory.forNodeIntrinsic(), anchorNode); } /** @@ -109,7 +113,8 @@ } displayHit.inc(); } - return unsafeCast(verifyOop(object), StampFactory.forNodeIntrinsic()); + BeginNode anchorNode = BeginNode.anchor(StampFactory.forNodeIntrinsic()); + return unsafeCast(verifyOop(object), StampFactory.forNodeIntrinsic(), anchorNode); } /** @@ -132,14 +137,16 @@ Word hintHub = hints[i]; if (hintHub.equal(objectHub)) { hintsHit.inc(); - return unsafeCast(verifyOop(object), StampFactory.forNodeIntrinsic()); + BeginNode anchorNode = BeginNode.anchor(StampFactory.forNodeIntrinsic()); + return unsafeCast(verifyOop(object), StampFactory.forNodeIntrinsic(), anchorNode); } } if (!checkSecondarySubType(hub, objectHub)) { DeoptimizeNode.deopt(InvalidateReprofile, ClassCastException); } } - return unsafeCast(verifyOop(object), StampFactory.forNodeIntrinsic()); + BeginNode anchorNode = BeginNode.anchor(StampFactory.forNodeIntrinsic()); + return unsafeCast(verifyOop(object), StampFactory.forNodeIntrinsic(), anchorNode); } /** @@ -160,7 +167,8 @@ DeoptimizeNode.deopt(InvalidateReprofile, ClassCastException); } } - return unsafeCast(verifyOop(object), StampFactory.forNodeIntrinsic()); + BeginNode anchorNode = BeginNode.anchor(StampFactory.forNodeIntrinsic()); + return unsafeCast(verifyOop(object), StampFactory.forNodeIntrinsic(), anchorNode); } // @formatter:on diff -r 3cf7d22b14dd -r 2978a819763b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BeginNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BeginNode.java Wed Mar 27 22:30:03 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BeginNode.java Wed Mar 27 19:11:30 2013 +0100 @@ -184,4 +184,7 @@ throw new UnsupportedOperationException(); } } + + @NodeIntrinsic + public static native T anchor(@ConstantNodeParameter Stamp stamp); } diff -r 3cf7d22b14dd -r 2978a819763b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java Wed Mar 27 22:30:03 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java Wed Mar 27 19:11:30 2013 +0100 @@ -44,6 +44,11 @@ this.object = object; } + public UnsafeCastNode(ValueNode object, Stamp stamp, ValueNode anchor) { + super(stamp, anchor); + this.object = object; + } + public UnsafeCastNode(ValueNode object, ResolvedJavaType toType, boolean exactType, boolean nonNull) { this(object, toType.getKind() == Kind.Object ? StampFactory.object(toType, exactType, nonNull || object.stamp().nonNull()) : StampFactory.forKind(toType.getKind())); } @@ -109,6 +114,9 @@ @NodeIntrinsic public static native T unsafeCast(Object object, @ConstantNodeParameter Stamp stamp); + @NodeIntrinsic + public static native T unsafeCast(Object object, @ConstantNodeParameter Stamp stamp, ValueNode anchor); + @SuppressWarnings("unused") @NodeIntrinsic public static T unsafeCast(Object object, @ConstantNodeParameter Class toType, @ConstantNodeParameter boolean exactType, @ConstantNodeParameter boolean nonNull) {