changeset 20147:46bb6e576335

fix unguarded reads resulting from lowering UnsafeLoadNode
author Doug Simon <doug.simon@oracle.com>
date Thu, 02 Apr 2015 19:30:19 +0200
parents a927a3ccfd0d
children 6f669b9be43c
files graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatableAccessNode.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java
diffstat 2 files changed, 13 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatableAccessNode.java	Thu Apr 02 19:23:19 2015 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatableAccessNode.java	Thu Apr 02 19:30:19 2015 +0200
@@ -49,12 +49,18 @@
 
     public abstract FloatingAccessNode asFloatingNode(MemoryNode lastLocationAccess);
 
+    protected boolean forceFixed;
+
+    public void setForceFixed(boolean flag) {
+        this.forceFixed = flag;
+    }
+
     /**
      * AccessNodes can float only if their location identities are not ANY_LOCATION. Furthermore, in
      * case G1 is enabled any access (read) to the java.lang.ref.Reference.referent field which has
      * an attached write barrier with pre-semantics can not also float.
      */
     public boolean canFloat() {
-        return location().getLocationIdentity().isSingle() && getBarrierType() == BarrierType.NONE;
+        return !forceFixed && location().getLocationIdentity().isSingle() && getBarrierType() == BarrierType.NONE;
     }
 }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java	Thu Apr 02 19:23:19 2015 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java	Thu Apr 02 19:30:19 2015 +0200
@@ -273,10 +273,7 @@
             graph.addAfterFixed(valueAnchorNode, memoryRead);
         } else {
             assert load.getKind() != Kind.Illegal;
-            // An unsafe read must not float outside its block otherwise
-            // it may float above an explicit null check on its object.
-            AbstractBeginNode guard = AbstractBeginNode.prevBegin(load);
-            ReadNode memoryRead = createUnsafeRead(graph, load, guard);
+            ReadNode memoryRead = createUnsafeRead(graph, load, null);
             graph.replaceFixedWithFixed(load, memoryRead);
         }
     }
@@ -295,6 +292,11 @@
         }
         Stamp loadStamp = loadStamp(load.stamp(), readKind, compressible);
         ReadNode memoryRead = graph.add(new ReadNode(object, location, loadStamp, guard, BarrierType.NONE));
+        if (guard == null) {
+            // An unsafe read must not float otherwise it may float above
+            // a test guaranteeing the read is safe.
+            memoryRead.setForceFixed(true);
+        }
         ValueNode readValue = implicitLoadConvert(graph, readKind, memoryRead, compressible);
         load.replaceAtUsages(readValue);
         return memoryRead;