changeset 10774:0f8d0c86611d

Augment WriteBarrierVerification phase to account for ArrayRange barriers
author Christos Kotselidis <christos.kotselidis@oracle.com>
date Tue, 16 Jul 2013 14:10:10 +0200
parents fbeda94727f8
children 0a8f1eefce51
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierVerificationPhase.java
diffstat 1 files changed, 30 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierVerificationPhase.java	Mon Jul 15 17:58:17 2013 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierVerificationPhase.java	Tue Jul 16 14:10:10 2013 +0200
@@ -54,7 +54,7 @@
 
     private void processWrites(StructuredGraph graph) {
         for (Node node : graph.getNodes()) {
-            if (isObjectWrite(node)) {
+            if (isObjectWrite(node) || isObjectArrayRangeWrite(node)) {
                 validateWrite(node);
             }
         }
@@ -65,7 +65,7 @@
          * The currently validated write is checked in order to discover if it has an appropriate
          * attached write barrier.
          */
-        if (hasAttachedBarrier(write)) {
+        if (hasAttachedBarrier((FixedWithNextNode) write)) {
             return;
         }
         NodeFlood frontier = write.graph().createNodeFlood();
@@ -79,19 +79,38 @@
                     expandFrontier(frontier, currentNode);
                 }
             } else {
-                if (!(currentNode instanceof SerialWriteBarrier) || ((currentNode instanceof SerialWriteBarrier) && !validateBarrier(write, (WriteBarrier) currentNode))) {
+                if (!(currentNode instanceof SerialWriteBarrier) || ((currentNode instanceof SerialWriteBarrier) && !validateBarrier(write, (WriteBarrier) currentNode)) ||
+                                ((currentNode instanceof SerialWriteBarrier) && !validateBarrier(write, (WriteBarrier) currentNode))) {
                     expandFrontier(frontier, currentNode);
                 }
             }
         }
     }
 
-    private boolean hasAttachedBarrier(Node node) {
+    private boolean hasAttachedBarrier(FixedWithNextNode node) {
+        final Node next = node.next();
+        final Node previous = node.predecessor();
         if (useG1GC) {
-            return ((FixedWithNextNode) node).next() instanceof G1PostWriteBarrier && ((FixedWithNextNode) node).predecessor() instanceof G1PreWriteBarrier &&
-                            validateBarrier(node, (G1PostWriteBarrier) ((FixedWithNextNode) node).next()) && validateBarrier(node, (G1PreWriteBarrier) ((FixedWithNextNode) node).predecessor());
+            if (isObjectWrite(node)) {
+                return next instanceof G1PostWriteBarrier && previous instanceof G1PreWriteBarrier && validateBarrier(node, (G1PostWriteBarrier) next) &&
+                                validateBarrier(node, (G1PreWriteBarrier) previous);
+            } else if (isObjectArrayRangeWrite(node)) {
+                assert (next instanceof G1ArrayRangePostWriteBarrier) && (previous instanceof G1ArrayRangePreWriteBarrier) &&
+                                ((ArrayRangeWriteNode) node).getArray() == ((G1ArrayRangePostWriteBarrier) next).getObject() &&
+                                ((ArrayRangeWriteNode) node).getArray() == ((G1ArrayRangePreWriteBarrier) previous).getObject() : "ArrayRangeWriteNode misses pre and/or post barriers";
+                return true;
+            } else {
+                return false;
+            }
         } else {
-            return (((FixedWithNextNode) node).next() instanceof SerialWriteBarrier) && validateBarrier(node, (SerialWriteBarrier) ((FixedWithNextNode) node).next());
+            if (isObjectWrite(node)) {
+                return next instanceof SerialWriteBarrier && validateBarrier(node, (SerialWriteBarrier) next);
+            } else if (isObjectArrayRangeWrite(node)) {
+                assert (next instanceof SerialArrayRangeWriteBarrier && ((ArrayRangeWriteNode) node).getArray() == ((SerialArrayRangeWriteBarrier) next).getObject()) : "ArrayRangeWriteNode misses post barriers";
+                return true;
+            } else {
+                return false;
+            }
         }
     }
 
@@ -103,6 +122,10 @@
         return false;
     }
 
+    private static boolean isObjectArrayRangeWrite(Node node) {
+        return node instanceof ArrayRangeWriteNode && ((ArrayRangeWriteNode) node).isObjectArray();
+    }
+
     private static void expandFrontier(NodeFlood frontier, Node node) {
         for (Node previousNode : node.cfgPredecessors()) {
             if (previousNode != null) {