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) {