changeset 21106:ec894427332d

Don't insert serial barriers for null stores
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Thu, 23 Apr 2015 12:55:54 -0700
parents db2de6c2bf95
children fe0531d98fbe 5d7a2915c96c
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SerialWriteBarrier.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierVerificationPhase.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java
diffstat 4 files changed, 32 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SerialWriteBarrier.java	Thu Apr 23 21:26:04 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SerialWriteBarrier.java	Thu Apr 23 12:55:54 2015 -0700
@@ -31,18 +31,12 @@
 public class SerialWriteBarrier extends WriteBarrier {
 
     public static final NodeClass<SerialWriteBarrier> TYPE = NodeClass.create(SerialWriteBarrier.class);
-    protected final boolean alwaysNull;
 
-    public SerialWriteBarrier(ValueNode object, LocationNode location, boolean precise, boolean alwaysNull) {
-        this(TYPE, object, location, precise, alwaysNull);
+    public SerialWriteBarrier(ValueNode object, LocationNode location, boolean precise) {
+        this(TYPE, object, location, precise);
     }
 
-    protected SerialWriteBarrier(NodeClass<? extends SerialWriteBarrier> c, ValueNode object, LocationNode location, boolean precise, boolean alwaysNull) {
+    protected SerialWriteBarrier(NodeClass<? extends SerialWriteBarrier> c, ValueNode object, LocationNode location, boolean precise) {
         super(c, object, null, location, precise);
-        this.alwaysNull = alwaysNull;
-    }
-
-    public boolean alwaysNull() {
-        return alwaysNull;
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java	Thu Apr 23 21:26:04 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java	Thu Apr 23 12:55:54 2015 -0700
@@ -87,8 +87,12 @@
 
     protected void addSerialPostWriteBarrier(FixedAccessNode node, ValueNode object, ValueNode value, LocationNode location, boolean precise, StructuredGraph graph) {
         final boolean alwaysNull = StampTool.isPointerAlwaysNull(value);
+        if (alwaysNull) {
+            // Serial barrier isn't needed for null value
+            return;
+        }
         final LocationNode loc = (precise ? location : null);
-        graph.addAfterFixed(node, graph.add(new SerialWriteBarrier(object, loc, precise, alwaysNull)));
+        graph.addAfterFixed(node, graph.add(new SerialWriteBarrier(object, loc, precise)));
     }
 
     private void addWriteNodeBarriers(WriteNode node, StructuredGraph graph) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierVerificationPhase.java	Thu Apr 23 21:26:04 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierVerificationPhase.java	Thu Apr 23 12:55:54 2015 -0700
@@ -27,6 +27,7 @@
 
 import java.util.*;
 
+import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.hotspot.replacements.*;
@@ -34,6 +35,7 @@
 import com.oracle.graal.nodes.HeapAccess.BarrierType;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.phases.*;
 
 /**
@@ -92,17 +94,22 @@
         final Node previous = node.predecessor();
         final boolean validatePreBarrier = HotSpotReplacementsUtil.useG1GC() && (isObjectWrite(node) || !((ArrayRangeWriteNode) node).isInitialization());
         if (isObjectWrite(node)) {
-            return next instanceof WriteBarrier && validateBarrier((FixedAccessNode) node, (WriteBarrier) next) &&
-                            (!validatePreBarrier || (previous instanceof WriteBarrier && validateBarrier((FixedAccessNode) node, (WriteBarrier) previous)));
-
+            return (isObjectBarrier(node, next) || StampTool.isPointerAlwaysNull(getValueWritten(node))) && (!validatePreBarrier || isObjectBarrier(node, previous));
         } else if (isObjectArrayRangeWrite(node)) {
-            return ((next instanceof ArrayRangeWriteBarrier) && ((ArrayRangeWriteNode) node).getArray() == ((ArrayRangeWriteBarrier) next).getObject()) &&
-                            (!validatePreBarrier || ((previous instanceof ArrayRangeWriteBarrier) && ((ArrayRangeWriteNode) node).getArray() == ((ArrayRangeWriteBarrier) previous).getObject()));
+            return (isArrayBarrier(node, next) || StampTool.isPointerAlwaysNull(getValueWritten(node))) && (!validatePreBarrier || isArrayBarrier(node, previous));
         } else {
             return true;
         }
     }
 
+    private static boolean isObjectBarrier(FixedWithNextNode node, final Node next) {
+        return next instanceof WriteBarrier && validateBarrier((FixedAccessNode) node, (WriteBarrier) next);
+    }
+
+    private static boolean isArrayBarrier(FixedWithNextNode node, final Node next) {
+        return (next instanceof ArrayRangeWriteBarrier) && ((ArrayRangeWriteNode) node).getArray() == ((ArrayRangeWriteBarrier) next).getObject();
+    }
+
     private static boolean isObjectWrite(Node node) {
         // Read nodes with barrier attached (G1 Ref field) are not validated yet.
         return node instanceof FixedAccessNode && ((HeapAccess) node).getBarrierType() != BarrierType.NONE && !(node instanceof ReadNode);
@@ -129,6 +136,18 @@
         return ((node instanceof DeoptimizingNode) && ((DeoptimizingNode) node).canDeoptimize()) || (node instanceof LoopBeginNode);
     }
 
+    private static ValueNode getValueWritten(FixedWithNextNode write) {
+        if (write instanceof WriteNode) {
+            return ((WriteNode) write).value();
+        } else if (write instanceof LoweredCompareAndSwapNode) {
+            return ((LoweredCompareAndSwapNode) write).getNewValue();
+        } else if (write instanceof LoweredAtomicReadAndWriteNode) {
+            return ((LoweredAtomicReadAndWriteNode) write).getNewValue();
+        } else {
+            throw GraalInternalError.shouldNotReachHere(String.format("unexpected write node %s", write));
+        }
+    }
+
     private static boolean validateBarrier(FixedAccessNode write, WriteBarrier barrier) {
         assert write instanceof WriteNode || write instanceof LoweredCompareAndSwapNode || write instanceof LoweredAtomicReadAndWriteNode : "Node must be of type requiring a write barrier " + write;
         if ((barrier.getObject() == write.object()) && (!barrier.usePrecise() || (barrier.usePrecise() && barrier.getLocation() == write.location()))) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java	Thu Apr 23 21:26:04 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java	Thu Apr 23 12:55:54 2015 -0700
@@ -350,10 +350,6 @@
         }
 
         public void lower(SerialWriteBarrier writeBarrier, LoweringTool tool) {
-            if (writeBarrier.alwaysNull()) {
-                writeBarrier.graph().removeFixed(writeBarrier);
-                return;
-            }
             Arguments args = new Arguments(serialWriteBarrier, writeBarrier.graph().getGuardsStage(), tool.getLoweringStage());
             args.add("object", writeBarrier.getObject());
             args.add("location", writeBarrier.getLocation());