changeset 11229:78da293f6efa

Merge.
author Doug Simon <doug.simon@oracle.com>
date Tue, 06 Aug 2013 18:32:04 +0200
parents e28663a9f5ef (current diff) 7244c8366d44 (diff)
children 5c153c59ba62
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java
diffstat 8 files changed, 52 insertions(+), 89 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java	Tue Aug 06 18:31:23 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java	Tue Aug 06 18:32:04 2013 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.hotspot.test;
 
+import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
+
 import java.lang.ref.*;
 import java.lang.reflect.*;
 
@@ -41,7 +43,6 @@
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.tiers.*;
-import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
 
 /**
  * The following unit tests assert the presence of write barriers for both Serial and G1 GCs.
@@ -146,9 +147,9 @@
     static Container con = new Container();
 
     /**
-     * Expected 4 barriers for the Serial GC and 9 for G1 (5 pre + 4 post). In this test, we load
-     * the correct offset of the WeakReference object so naturally we assert the presence of the pre
-     * barrier.
+     * Expected 4 barriers for the Serial GC and 9 for G1 (1 ref + 4 pre + 4 post). In this test, we
+     * load the correct offset of the WeakReference object so naturally we assert the presence of
+     * the pre barrier.
      */
     @Test
     public void test5() throws Exception {
@@ -156,7 +157,7 @@
     }
 
     public static Object test5Snippet() throws Exception {
-        return UnsafeLoadNode.load(wr, 0, 16, Kind.Object);
+        return UnsafeLoadNode.load(wr, 0, useCompressedOops() ? 12 : 16, Kind.Object);
     }
 
     /**
@@ -246,9 +247,12 @@
 
             public void run() {
                 StructuredGraph graph = parse(snippet);
-                HighTierContext context = new HighTierContext(runtime(), new Assumptions(false), replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
-                new InliningPhase(new InliningPhase.InlineEverythingPolicy()).apply(graph, context);
-                new LoweringPhase(LoweringType.BEFORE_GUARDS).apply(graph, context);
+                HighTierContext highContext = new HighTierContext(runtime(), new Assumptions(false), replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
+                MidTierContext midContext = new MidTierContext(runtime(), new Assumptions(false), replacements, runtime().getTarget(), OptimisticOptimizations.ALL);
+                new InliningPhase(new InliningPhase.InlineEverythingPolicy()).apply(graph, highContext);
+                new LoweringPhase(LoweringType.BEFORE_GUARDS).apply(graph, highContext);
+                new GuardLoweringPhase().apply(graph, midContext);
+                new LoweringPhase(LoweringType.AFTER_GUARDS).apply(graph, midContext);
                 new WriteBarrierAdditionPhase().apply(graph);
                 Debug.dump(graph, "After Write Barrier Addition");
 
@@ -278,8 +282,6 @@
                     if (read.getBarrierType() != BarrierType.NONE) {
                         if (read.location() instanceof ConstantLocationNode) {
                             Assert.assertTrue(((ConstantLocationNode) (read.location())).getDisplacement() == referentOffset());
-                        } else {
-                            Assert.assertTrue(((IndexedLocationNode) (read.location())).getDisplacement() == referentOffset());
                         }
                         Assert.assertTrue(useG1GC());
                         Assert.assertTrue(read.getBarrierType() == BarrierType.PRECISE);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Tue Aug 06 18:31:23 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Tue Aug 06 18:32:04 2013 +0200
@@ -311,7 +311,7 @@
         linkForeignCall(r, OSR_MIGRATION_END, c.osrMigrationEndAddress, DONT_PREPEND_THREAD, LEAF, NOT_REEXECUTABLE, NO_LOCATIONS);
         linkForeignCall(r, G1WBPRECALL, c.writeBarrierPreAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS);
         linkForeignCall(r, G1WBPOSTCALL, c.writeBarrierPostAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS);
-        linkForeignCall(r, VALIDATEOBJECT, c.validateObject, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS);
+        linkForeignCall(r, VALIDATE_OBJECT, c.validateObject, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS);
 
         if (IntrinsifyObjectMethods.getValue()) {
             r.registerSubstitutions(ObjectSubstitutions.class);
@@ -593,6 +593,7 @@
             LocationNode location = IndexedLocationNode.create(ANY_LOCATION, cas.expected().kind(), cas.displacement(), cas.offset(), graph, 1);
             LoweredCompareAndSwapNode atomicNode = graph.add(new LoweredCompareAndSwapNode(cas.object(), location, cas.expected(), cas.newValue(), getCompareAndSwapBarrier(cas),
                             cas.expected().kind() == Kind.Object));
+            atomicNode.setStateAfter(cas.stateAfter());
             graph.replaceFixedWithFixed(cas, atomicNode);
         } else if (n instanceof LoadIndexedNode) {
             LoadIndexedNode loadIndexed = (LoadIndexedNode) n;
@@ -636,11 +637,11 @@
             graph.replaceFixedWithFixed(storeIndexed, memoryWrite);
 
         } else if (n instanceof UnsafeLoadNode) {
-            if (tool.getLoweringType() != LoweringType.BEFORE_GUARDS) {
+            if (tool.getLoweringType().ordinal() > LoweringType.BEFORE_GUARDS.ordinal()) {
                 UnsafeLoadNode load = (UnsafeLoadNode) n;
                 assert load.kind() != Kind.Illegal;
                 boolean compressible = (!load.object().isNullConstant() && load.accessKind() == Kind.Object);
-                if (addReadBarrier(load, tool)) {
+                if (addReadBarrier(load)) {
                     unsafeLoadSnippets.lower(load, tool);
                 } else {
                     IndexedLocationNode location = IndexedLocationNode.create(ANY_LOCATION, load.accessKind(), load.displacement(), load.offset(), graph, 1);
@@ -847,9 +848,9 @@
         }
     }
 
-    private static boolean addReadBarrier(UnsafeLoadNode load, LoweringTool tool) {
+    private static boolean addReadBarrier(UnsafeLoadNode load) {
         return useG1GC() && load.object().kind() == Kind.Object && load.accessKind() == Kind.Object && !load.object().objectStamp().alwaysNull() && load.object().objectStamp().type() != null &&
-                        !(load.object().objectStamp().type().isArray()) && tool.getLoweringType() == LoweringType.BEFORE_GUARDS;
+                        !(load.object().objectStamp().type().isArray());
     }
 
     private static ReadNode createReadVirtualMethod(StructuredGraph graph, Kind wordKind, ValueNode hub, ResolvedJavaMethod method) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java	Tue Aug 06 18:31:23 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java	Tue Aug 06 18:32:04 2013 +0200
@@ -71,6 +71,7 @@
                     G1PreWriteBarrier preBarrier = graph.add(new G1PreWriteBarrier(node.object(), null, node.location(), true, node.getNullCheck()));
                     preBarrier.setDeoptimizationState(node.getDeoptimizationState());
                     node.setNullCheck(false);
+                    node.setDeoptimizationState(null);
                     graph.addBeforeFixed(node, preBarrier);
                 }
                 graph.addAfterFixed(node, graph.add(new G1PostWriteBarrier(node.object(), node.value(), node.location(), true)));
@@ -82,6 +83,7 @@
                 G1PreWriteBarrier preBarrier = graph.add(new G1PreWriteBarrier(node.object(), null, node.location(), true, node.getNullCheck()));
                 preBarrier.setDeoptimizationState(node.getDeoptimizationState());
                 node.setNullCheck(false);
+                node.setDeoptimizationState(null);
                 graph.addBeforeFixed(node, preBarrier);
                 graph.addAfterFixed(node, graph.add(new G1PostWriteBarrier(node.object(), node.value(), node.location(), false)));
             } else {
@@ -97,17 +99,17 @@
         BarrierType barrierType = node.getBarrierType();
         if (barrierType == BarrierType.PRECISE) {
             if (useG1GC()) {
-                graph.addBeforeFixed(node, graph.add(new G1PreWriteBarrier(node.object(), node.getExpectedValue(), node.getLocation(), false, false)));
-                graph.addAfterFixed(node, graph.add(new G1PostWriteBarrier(node.object(), node.getNewValue(), node.getLocation(), true)));
+                graph.addBeforeFixed(node, graph.add(new G1PreWriteBarrier(node.object(), node.getExpectedValue(), node.location(), false, false)));
+                graph.addAfterFixed(node, graph.add(new G1PostWriteBarrier(node.object(), node.getNewValue(), node.location(), true)));
             } else {
-                graph.addAfterFixed(node, graph.add(new SerialWriteBarrier(node.object(), node.getNewValue(), node.getLocation(), true)));
+                graph.addAfterFixed(node, graph.add(new SerialWriteBarrier(node.object(), node.getNewValue(), node.location(), true)));
             }
         } else if (barrierType == BarrierType.IMPRECISE) {
             if (useG1GC()) {
-                graph.addBeforeFixed(node, graph.add(new G1PreWriteBarrier(node.object(), node.getExpectedValue(), node.getLocation(), false, false)));
-                graph.addAfterFixed(node, graph.add(new G1PostWriteBarrier(node.object(), node.getNewValue(), node.getLocation(), false)));
+                graph.addBeforeFixed(node, graph.add(new G1PreWriteBarrier(node.object(), node.getExpectedValue(), node.location(), false, false)));
+                graph.addAfterFixed(node, graph.add(new G1PostWriteBarrier(node.object(), node.getNewValue(), node.location(), false)));
             } else {
-                graph.addAfterFixed(node, graph.add(new SerialWriteBarrier(node.object(), node.getNewValue(), node.getLocation(), false)));
+                graph.addAfterFixed(node, graph.add(new SerialWriteBarrier(node.object(), node.getNewValue(), node.location(), false)));
             }
         } else {
             assert barrierType == BarrierType.NONE;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierVerificationPhase.java	Tue Aug 06 18:31:23 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierVerificationPhase.java	Tue Aug 06 18:32:04 2013 +0200
@@ -72,12 +72,12 @@
             Node currentNode = iterator.next();
             assert !isSafepoint(currentNode) : "Write barrier must be present";
             if (useG1GC()) {
-                if (!(currentNode instanceof G1PostWriteBarrier) || ((currentNode instanceof G1PostWriteBarrier) && !validateBarrier(write, (WriteBarrier) currentNode))) {
+                if (!(currentNode instanceof G1PostWriteBarrier) || ((currentNode instanceof G1PostWriteBarrier) && !validateBarrier((AccessNode) write, (WriteBarrier) currentNode))) {
                     expandFrontier(frontier, currentNode);
                 }
             } else {
-                if (!(currentNode instanceof SerialWriteBarrier) || ((currentNode instanceof SerialWriteBarrier) && !validateBarrier(write, (WriteBarrier) currentNode)) ||
-                                ((currentNode instanceof SerialWriteBarrier) && !validateBarrier(write, (WriteBarrier) currentNode))) {
+                if (!(currentNode instanceof SerialWriteBarrier) || ((currentNode instanceof SerialWriteBarrier) && !validateBarrier((AccessNode) write, (WriteBarrier) currentNode)) ||
+                                ((currentNode instanceof SerialWriteBarrier) && !validateBarrier((AccessNode) write, (WriteBarrier) currentNode))) {
                     expandFrontier(frontier, currentNode);
                 }
             }
@@ -87,36 +87,22 @@
     private static boolean hasAttachedBarrier(FixedWithNextNode node) {
         final Node next = node.next();
         final Node previous = node.predecessor();
-        if (HotSpotReplacementsUtil.useG1GC()) {
-            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;
-            }
+        final boolean validatePreBarrier = HotSpotReplacementsUtil.useG1GC() && (isObjectWrite(node) || !((ArrayRangeWriteNode) node).isInitialization());
+        if (isObjectWrite(node)) {
+            return next instanceof WriteBarrier && validateBarrier((AccessNode) node, (WriteBarrier) next) &&
+                            (!validatePreBarrier || (previous instanceof WriteBarrier && validateBarrier((AccessNode) node, (WriteBarrier) 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()));
         } else {
-            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;
-            }
+            return true;
         }
     }
 
     private static boolean isObjectWrite(Node node) {
-        if ((node instanceof WriteNode && (((WriteNode) node).getBarrierType() != BarrierType.NONE)) ||
-                        (node instanceof LoweredCompareAndSwapNode && (((LoweredCompareAndSwapNode) node).getBarrierType() != BarrierType.NONE))) {
-            return true;
-        }
-        return false;
+        // Read nodes with barrier attached (G1 Ref field) are not validated yet.
+        return node instanceof AccessNode && ((HeapAccess) node).getBarrierType() != BarrierType.NONE && !(node instanceof ReadNode);
     }
 
     private static boolean isObjectArrayRangeWrite(Node node) {
@@ -140,20 +126,9 @@
         return ((node instanceof DeoptimizingNode) && ((DeoptimizingNode) node).canDeoptimize()) || (node instanceof LoopBeginNode);
     }
 
-    private static boolean validateBarrier(Node write, WriteBarrier barrier) {
-        ValueNode writtenObject = null;
-        LocationNode writtenLocation = null;
-        if (write instanceof WriteNode) {
-            writtenObject = ((WriteNode) write).object();
-            writtenLocation = ((WriteNode) write).location();
-        } else if (write instanceof LoweredCompareAndSwapNode) {
-            writtenObject = ((LoweredCompareAndSwapNode) write).object();
-            writtenLocation = ((LoweredCompareAndSwapNode) write).getLocation();
-        } else {
-            assert false : "Node must be of type requiring a write barrier";
-        }
-
-        if ((barrier.getObject() == writtenObject) && (!barrier.usePrecise() || (barrier.usePrecise() && barrier.getLocation() == writtenLocation))) {
+    private static boolean validateBarrier(AccessNode write, WriteBarrier barrier) {
+        assert write instanceof WriteNode || write instanceof LoweredCompareAndSwapNode : "Node must be of type requiring a write barrier";
+        if ((barrier.getObject() == write.object()) && (!barrier.usePrecise() || (barrier.usePrecise() && barrier.getLocation() == write.location()))) {
             return true;
         }
         return false;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java	Tue Aug 06 18:31:23 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java	Tue Aug 06 18:32:04 2013 +0200
@@ -434,6 +434,11 @@
     }
 
     @Fold
+    public static boolean useCompressedOops() {
+        return config().useCompressedOops;
+    }
+
+    @Fold
     static int uninitializedIdentityHashCodeValue() {
         return config().uninitializedIdentityHashCodeValue;
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java	Tue Aug 06 18:31:23 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java	Tue Aug 06 18:32:04 2013 +0200
@@ -437,13 +437,13 @@
      * prematurely crash the VM and debug the stack trace of the faulty method.
      */
     private static void validateObject(Object parent, Object child) {
-        if (verifyOops() && child != null && !validateOop(VALIDATEOBJECT, parent, child)) {
+        if (verifyOops() && child != null && !validateOop(VALIDATE_OBJECT, parent, child)) {
             log(true, "Verification ERROR, Parent: %p Child: %p\n", Word.fromObject(parent).rawValue(), Word.fromObject(child).rawValue());
             DirectObjectStoreNode.storeWord(null, 0, 0, Word.zero());
         }
     }
 
-    public static final ForeignCallDescriptor VALIDATEOBJECT = new ForeignCallDescriptor("validate_object", boolean.class, Word.class, Word.class);
+    public static final ForeignCallDescriptor VALIDATE_OBJECT = new ForeignCallDescriptor("validate_object", boolean.class, Word.class, Word.class);
 
     @NodeIntrinsic(ForeignCallNode.class)
     private static native boolean validateOop(@ConstantNodeParameter ForeignCallDescriptor descriptor, Object parent, Object object);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java	Tue Aug 06 18:31:23 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java	Tue Aug 06 18:32:04 2013 +0200
@@ -40,7 +40,6 @@
     @Input private ValueNode offset;
     @Input private ValueNode expected;
     @Input private ValueNode newValue;
-    @Input private LocationNode location;
     private final int displacement;
 
     public ValueNode object() {
@@ -63,15 +62,6 @@
         return displacement;
     }
 
-    public LocationNode getLocation() {
-        return location;
-    }
-
-    public void setLocation(LocationNode location) {
-        updateUsages(this.location, location);
-        this.location = location;
-    }
-
     public CompareAndSwapNode(ValueNode object, int displacement, ValueNode offset, ValueNode expected, ValueNode newValue) {
         super(StampFactory.forKind(Kind.Boolean.getStackKind()));
         assert expected.kind() == newValue.kind();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredCompareAndSwapNode.java	Tue Aug 06 18:31:23 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredCompareAndSwapNode.java	Tue Aug 06 18:32:04 2013 +0200
@@ -34,10 +34,8 @@
  */
 public class LoweredCompareAndSwapNode extends AccessNode implements StateSplit, LIRLowerable, MemoryCheckpoint.Single, Node.IterableNodeType {
 
-    @Input private ValueNode object;
     @Input private ValueNode expectedValue;
     @Input private ValueNode newValue;
-    @Input private LocationNode location;
     @Input(notDataflow = true) private FrameState stateAfter;
 
     public FrameState stateAfter() {
@@ -54,10 +52,6 @@
         return true;
     }
 
-    public ValueNode getObject() {
-        return object;
-    }
-
     public ValueNode getExpectedValue() {
         return expectedValue;
     }
@@ -66,26 +60,20 @@
         return newValue;
     }
 
-    public LocationNode getLocation() {
-        return location;
-    }
-
     public LoweredCompareAndSwapNode(ValueNode object, LocationNode location, ValueNode expectedValue, ValueNode newValue, BarrierType barrierType, boolean compressible) {
         super(object, location, StampFactory.forKind(Kind.Boolean.getStackKind()), barrierType, compressible);
         assert expectedValue.kind() == newValue.kind();
-        this.object = object;
         this.expectedValue = expectedValue;
         this.newValue = newValue;
-        this.location = location;
     }
 
     @Override
     public LocationIdentity getLocationIdentity() {
-        return location.getLocationIdentity();
+        return location().getLocationIdentity();
     }
 
     @Override
     public void generate(LIRGeneratorTool gen) {
-        gen.visitCompareAndSwap(this, getLocation().generateAddress(gen, gen.operand(getObject())));
+        gen.visitCompareAndSwap(this, location().generateAddress(gen, gen.operand(object())));
     }
 }