changeset 9105:2cae919cd3af

Introduce enumeration for the different write barrier types
author Christos Kotselidis <christos.kotselidis@oracle.com>
date Fri, 12 Apr 2013 23:29:45 +0200
parents 1c77db9ba064
children 0c8ec85fa013
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectObjectStoreNode.java graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java
diffstat 6 files changed, 98 insertions(+), 62 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Wed Apr 10 16:25:47 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Fri Apr 12 23:29:45 2013 +0200
@@ -64,6 +64,7 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.extended.WriteNode.WriteBarrierType;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
 import com.oracle.graal.nodes.spi.*;
@@ -573,16 +574,14 @@
             HotSpotResolvedJavaField field = (HotSpotResolvedJavaField) storeField.field();
             ValueNode object = storeField.isStatic() ? ConstantNode.forObject(field.getDeclaringClass().mirror(), this, graph) : storeField.object();
             LocationNode location = LocationNode.create(field, field.getKind(), field.offset(), graph);
-            WriteNode memoryWrite = graph.add(new WriteNode(object, storeField.value(), location, false));
+            WriteBarrierType barrierType = getFieldStoreBarrier(storeField);
+            WriteNode memoryWrite = graph.add(new WriteNode(object, storeField.value(), location, barrierType));
             memoryWrite.dependencies().add(tool.createNullCheckGuard(object));
             memoryWrite.setStateAfter(storeField.stateAfter());
             graph.replaceFixedWithFixed(storeField, memoryWrite);
             FixedWithNextNode last = memoryWrite;
             FixedWithNextNode first = memoryWrite;
 
-            if (field.getKind() == Kind.Object && !memoryWrite.value().objectStamp().alwaysNull()) {
-                memoryWrite.setWriteBarrier();
-            }
             if (storeField.isVolatile()) {
                 MembarNode preMembar = graph.add(new MembarNode(JMM_PRE_VOLATILE_WRITE));
                 graph.addBeforeFixed(first, preMembar);
@@ -592,13 +591,7 @@
         } else if (n instanceof CompareAndSwapNode) {
             // Separate out GC barrier semantics
             CompareAndSwapNode cas = (CompareAndSwapNode) n;
-            ValueNode expected = cas.expected();
-            if (expected.kind() == Kind.Object && !cas.newValue().objectStamp().alwaysNull()) {
-                ResolvedJavaType type = cas.object().objectStamp().type();
-                final boolean precise = (type != null && type.isArray() && !MetaUtil.isJavaLangObject(type));
-                cas.setWriteBarrier();
-                cas.setPreciseWriteBarrier(precise);
-            }
+            cas.setWriteBarrierType(getCompareAndSwapBarrier(cas));
         } else if (n instanceof LoadIndexedNode) {
             LoadIndexedNode loadIndexed = (LoadIndexedNode) n;
             ValueNode boundsCheck = createBoundsCheck(loadIndexed, tool);
@@ -634,14 +627,12 @@
                     value = checkcast;
                 }
             }
-            WriteNode memoryWrite = graph.add(new WriteNode(array, value, arrayLocation, true));
+            WriteBarrierType barrierType = getArrayStoreBarrier(storeIndexed);
+            WriteNode memoryWrite = graph.add(new WriteNode(array, value, arrayLocation, barrierType));
             memoryWrite.dependencies().add(boundsCheck);
             memoryWrite.setStateAfter(storeIndexed.stateAfter());
             graph.replaceFixedWithFixed(storeIndexed, memoryWrite);
 
-            if (elementKind == Kind.Object && !value.objectStamp().alwaysNull()) {
-                memoryWrite.setWriteBarrier();
-            }
         } else if (n instanceof UnsafeLoadNode) {
             UnsafeLoadNode load = (UnsafeLoadNode) n;
             assert load.kind() != Kind.Illegal;
@@ -655,14 +646,11 @@
             UnsafeStoreNode store = (UnsafeStoreNode) n;
             IndexedLocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, store.accessKind(), store.displacement(), store.offset(), graph, 1);
             ValueNode object = store.object();
-            ResolvedJavaType type = object.objectStamp().type();
-            final boolean precise = (type != null && type.isArray() && !MetaUtil.isJavaLangObject(type));
-            WriteNode write = graph.add(new WriteNode(object, store.value(), location, precise));
+            WriteBarrierType barrierType = getUnsafeStoreBarrier(store);
+            WriteNode write = graph.add(new WriteNode(object, store.value(), location, barrierType));
             write.setStateAfter(store.stateAfter());
             graph.replaceFixedWithFixed(store, write);
-            if (write.value().kind() == Kind.Object && !write.value().objectStamp().alwaysNull()) {
-                write.setWriteBarrier();
-            }
+
         } else if (n instanceof LoadHubNode) {
             LoadHubNode loadHub = (LoadHubNode) n;
             assert loadHub.kind() == wordKind;
@@ -722,6 +710,48 @@
         }
     }
 
+    private static WriteBarrierType getFieldStoreBarrier(StoreFieldNode storeField) {
+        WriteBarrierType barrierType = WriteBarrierType.NONE;
+        if (storeField.field().getKind() == Kind.Object && !storeField.value().objectStamp().alwaysNull()) {
+            barrierType = WriteBarrierType.IMPRECISE;
+        }
+        return barrierType;
+    }
+
+    private static WriteBarrierType getArrayStoreBarrier(StoreIndexedNode store) {
+        WriteBarrierType barrierType = WriteBarrierType.NONE;
+        if (store.elementKind() == Kind.Object && !store.value().objectStamp().alwaysNull()) {
+            barrierType = WriteBarrierType.PRECISE;
+        }
+        return barrierType;
+    }
+
+    private static WriteBarrierType getUnsafeStoreBarrier(UnsafeStoreNode store) {
+        WriteBarrierType barrierType = WriteBarrierType.NONE;
+        if (store.value().kind() == Kind.Object && !store.value().objectStamp().alwaysNull()) {
+            ResolvedJavaType type = store.object().objectStamp().type();
+            if ((type != null && type.isArray() && !MetaUtil.isJavaLangObject(type))) {
+                barrierType = WriteBarrierType.PRECISE;
+            } else {
+                barrierType = WriteBarrierType.IMPRECISE;
+            }
+        }
+        return barrierType;
+    }
+
+    private static WriteBarrierType getCompareAndSwapBarrier(CompareAndSwapNode cas) {
+        WriteBarrierType barrierType = WriteBarrierType.NONE;
+        if (cas.expected().kind() == Kind.Object && !cas.newValue().objectStamp().alwaysNull()) {
+            ResolvedJavaType type = cas.object().objectStamp().type();
+            if ((type != null && type.isArray() && !MetaUtil.isJavaLangObject(type))) {
+                barrierType = WriteBarrierType.PRECISE;
+            } else {
+                barrierType = WriteBarrierType.IMPRECISE;
+            }
+        }
+        return barrierType;
+    }
+
     private IndexedLocationNode createArrayLocation(Graph graph, Kind elementKind, ValueNode index) {
         int scale = this.graalRuntime.getTarget().sizeInBytes(elementKind);
         return IndexedLocationNode.create(LocationNode.getArrayLocation(elementKind), elementKind, getArrayBaseOffset(elementKind), index, graph, scale);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java	Wed Apr 10 16:25:47 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java	Fri Apr 12 23:29:45 2013 +0200
@@ -24,6 +24,7 @@
 
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.extended.WriteNode.WriteBarrierType;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.phases.*;
 
@@ -46,16 +47,27 @@
     }
 
     private static void addWriteNodeBarriers(WriteNode node, StructuredGraph graph) {
-        if (node.needsWriteBarrier()) {
-            graph.addAfterFixed(node, graph.add(new SerialWriteBarrier(node.object(), node.location(), node.usePreciseWriteBarriers())));
+        WriteBarrierType barrierType = node.getWriteBarrierType();
+        if (barrierType == WriteBarrierType.PRECISE) {
+            graph.addAfterFixed(node, graph.add(new SerialWriteBarrier(node.object(), node.location(), true)));
+        } else if (barrierType == WriteBarrierType.IMPRECISE) {
+            graph.addAfterFixed(node, graph.add(new SerialWriteBarrier(node.object(), node.location(), false)));
+        } else {
+            assert barrierType == WriteBarrierType.NONE;
         }
 
     }
 
     private static void addCASBarriers(CompareAndSwapNode node, StructuredGraph graph) {
-        if (node.needsWriteBarrier()) {
+        WriteBarrierType barrierType = node.getWriteBarrierType();
+        if (barrierType == WriteBarrierType.PRECISE) {
             LocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, node.expected().kind(), node.displacement(), node.offset(), graph, 1);
-            graph.addAfterFixed(node, graph.add(new SerialWriteBarrier(node.object(), location, node.usePreciseWriteBarriers())));
+            graph.addAfterFixed(node, graph.add(new SerialWriteBarrier(node.object(), location, true)));
+        } else if (barrierType == WriteBarrierType.IMPRECISE) {
+            LocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, node.expected().kind(), node.displacement(), node.offset(), graph, 1);
+            graph.addAfterFixed(node, graph.add(new SerialWriteBarrier(node.object(), location, false)));
+        } else {
+            assert barrierType == WriteBarrierType.NONE;
         }
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java	Wed Apr 10 16:25:47 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java	Fri Apr 12 23:29:45 2013 +0200
@@ -34,13 +34,25 @@
 
     @Input private ValueNode value;
     @Input(notDataflow = true) private FrameState stateAfter;
+    private final WriteBarrierType barrierType;
 
     /*
-     * The field below instructs the snippet to use the address of the object or the effective
-     * address of the object element of an array when calculating the card offset.
+     * The types of write barriers attached to stores.
      */
-    private final boolean usePreciseWriteBarriers;
-    private boolean needsWriteBarrier;
+    public enum WriteBarrierType {
+        /*
+         * Primitive stores which do not necessitate write barriers.
+         */
+        NONE,
+        /*
+         * Array object stores which necessitate precise write barriers.
+         */
+        PRECISE,
+        /*
+         * Field object stores which necessitate imprecise write barriers.
+         */
+        IMPRECISE
+    }
 
     public FrameState stateAfter() {
         return stateAfter;
@@ -60,22 +72,14 @@
         return value;
     }
 
-    public boolean usePreciseWriteBarriers() {
-        return usePreciseWriteBarriers;
-    }
-
-    public boolean needsWriteBarrier() {
-        return needsWriteBarrier;
+    public WriteBarrierType getWriteBarrierType() {
+        return barrierType;
     }
 
-    public void setWriteBarrier() {
-        this.needsWriteBarrier = true;
-    }
-
-    public WriteNode(ValueNode object, ValueNode value, ValueNode location, boolean usePreciseWriteBarriers) {
+    public WriteNode(ValueNode object, ValueNode value, ValueNode location, WriteBarrierType barrierType) {
         super(object, location, StampFactory.forVoid());
         this.value = value;
-        this.usePreciseWriteBarriers = usePreciseWriteBarriers;
+        this.barrierType = barrierType;
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java	Wed Apr 10 16:25:47 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java	Fri Apr 12 23:29:45 2013 +0200
@@ -28,6 +28,7 @@
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.extended.WriteNode.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 
@@ -42,12 +43,7 @@
     @Input private ValueNode expected;
     @Input private ValueNode newValue;
     private final int displacement;
-    /*
-     * The field below instructs the snippet to use the address of the object or the effective
-     * address of the object element of an array when calculating the card offset.
-     */
-    private boolean usePreciseWriteBarriers;
-    private boolean needsWriteBarrier;
+    private WriteBarrierType barrierType;
 
     public ValueNode object() {
         return object;
@@ -69,20 +65,12 @@
         return displacement;
     }
 
-    public boolean usePreciseWriteBarriers() {
-        return usePreciseWriteBarriers;
+    public WriteBarrierType getWriteBarrierType() {
+        return barrierType;
     }
 
-    public boolean needsWriteBarrier() {
-        return needsWriteBarrier;
-    }
-
-    public void setWriteBarrier() {
-        this.needsWriteBarrier = true;
-    }
-
-    public void setPreciseWriteBarrier(boolean precise) {
-        this.usePreciseWriteBarriers = precise;
+    public void setWriteBarrierType(WriteBarrierType type) {
+        this.barrierType = type;
     }
 
     public CompareAndSwapNode(ValueNode object, int displacement, ValueNode offset, ValueNode expected, ValueNode newValue) {
@@ -93,7 +81,7 @@
         this.expected = expected;
         this.newValue = newValue;
         this.displacement = displacement;
-        this.usePreciseWriteBarriers = false;
+        this.barrierType = WriteBarrierType.NONE;
     }
 
     @Override
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectObjectStoreNode.java	Wed Apr 10 16:25:47 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectObjectStoreNode.java	Fri Apr 12 23:29:45 2013 +0200
@@ -24,6 +24,7 @@
 
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.extended.WriteNode.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.word.*;
@@ -63,7 +64,7 @@
     public void lower(LoweringTool tool) {
         StructuredGraph graph = (StructuredGraph) this.graph();
         IndexedLocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, value.kind(), displacement, offset, graph, 1);
-        WriteNode write = graph.add(new WriteNode(object, value, location, false));
+        WriteNode write = graph.add(new WriteNode(object, value, location, WriteBarrierType.NONE));
         graph.replaceFixedWithFixed(this, write);
     }
 }
--- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java	Wed Apr 10 16:25:47 2013 +0200
+++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java	Fri Apr 12 23:29:45 2013 +0200
@@ -29,6 +29,7 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.extended.WriteNode.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.util.*;
@@ -277,7 +278,7 @@
 
     private static ValueNode writeOp(StructuredGraph graph, ValueNode base, ValueNode offset, ValueNode value, Invoke invoke, Kind writeKind, Object locationIdentity) {
         IndexedLocationNode location = IndexedLocationNode.create(locationIdentity, writeKind, 0, offset, graph, 1);
-        WriteNode write = graph.add(new WriteNode(base, value, location, false));
+        WriteNode write = graph.add(new WriteNode(base, value, location, WriteBarrierType.NONE));
         write.setStateAfter(invoke.stateAfter());
         graph.addBeforeFixed(invoke.node(), write);
         return write;