Mercurial > hg > graal-compiler
changeset 8536:2978a819763b
CheckCastSnippets: anchor UnsafeCast with subclass tests
author | Bernhard Urban <bernhard.urban@jku.at> |
---|---|
date | Wed, 27 Mar 2013 19:11:30 +0100 |
parents | 3cf7d22b14dd |
children | da674936800c |
files | graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCast.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastSnippets.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BeginNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java |
diffstat | 4 files changed, 26 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- 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");
--- 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
--- 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> T anchor(@ConstantNodeParameter Stamp stamp); }
--- 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> T unsafeCast(Object object, @ConstantNodeParameter Stamp stamp); + @NodeIntrinsic + public static native <T> T unsafeCast(Object object, @ConstantNodeParameter Stamp stamp, ValueNode anchor); + @SuppressWarnings("unused") @NodeIntrinsic public static <T> T unsafeCast(Object object, @ConstantNodeParameter Class<T> toType, @ConstantNodeParameter boolean exactType, @ConstantNodeParameter boolean nonNull) {