# HG changeset patch # User Doug Simon # Date 1375806724 -7200 # Node ID 78da293f6efa36328b71fc5f73bbf33d3b8dc97e # Parent e28663a9f5ef193282566982922b7892fb92b27a# Parent 7244c8366d4401b43babe7f33f44948c729e2e92 Merge. diff -r e28663a9f5ef -r 78da293f6efa graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java --- 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); diff -r e28663a9f5ef -r 78da293f6efa graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java --- 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) { diff -r e28663a9f5ef -r 78da293f6efa graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java --- 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; diff -r e28663a9f5ef -r 78da293f6efa graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierVerificationPhase.java --- 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; diff -r e28663a9f5ef -r 78da293f6efa graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java --- 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; } diff -r e28663a9f5ef -r 78da293f6efa graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java --- 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); diff -r e28663a9f5ef -r 78da293f6efa graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java --- 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(); diff -r e28663a9f5ef -r 78da293f6efa graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredCompareAndSwapNode.java --- 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()))); } }