# HG changeset patch # User Lukas Stadler # Date 1373980117 -7200 # Node ID b1f438bf1a40b36492011d0233aed7be6a20b693 # Parent c0ce8e825f303cf59b7198c40d4ecbf7bef4f372# Parent a8152db5839471929cad1348d777ddc8fd319371 Merge diff -r c0ce8e825f30 -r b1f438bf1a40 graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java Tue Jul 16 15:08:28 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java Tue Jul 16 15:08:37 2013 +0200 @@ -617,6 +617,15 @@ test("test12Snippet", 8, new int[]{8}); } + public static void test13Snippet(Object[] a, Object[] b) { + System.arraycopy(a, 0, b, 0, a.length); + } + + @Test + public void test61() { + test("test13Snippet", 1, new int[]{}); + } + private void test(final String snippet, final int expectedBarriers, final int... removedBarrierIndices) { AssertionError expectedError = Debug.scope("WriteBarrierVerificationTest", new DebugDumpScope(snippet), new Callable() { @@ -624,20 +633,25 @@ public AssertionError call() { final StructuredGraph graph = parse(snippet); HighTierContext highTierContext = new HighTierContext(runtime(), new Assumptions(false), replacements); + new InliningPhase(runtime(), null, replacements, new Assumptions(false), null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(graph); + MidTierContext midTierContext = new MidTierContext(runtime(), new Assumptions(false), replacements, runtime().getTarget(), OptimisticOptimizations.ALL); new LoweringPhase(LoweringType.BEFORE_GUARDS).apply(graph, highTierContext); new GuardLoweringPhase().apply(graph, midTierContext); new SafepointInsertionPhase().apply(graph); + new LoweringPhase(LoweringType.AFTER_GUARDS).apply(graph, highTierContext); + new WriteBarrierAdditionPhase().apply(graph); int barriers = 0; // First, the total number of expected barriers is checked. if (((HotSpotRuntime) runtime()).config.useG1GC) { - barriers = graph.getNodes(G1PreWriteBarrier.class).count() + graph.getNodes(G1PostWriteBarrier.class).count(); + barriers = graph.getNodes(G1PreWriteBarrier.class).count() + graph.getNodes(G1PostWriteBarrier.class).count() + graph.getNodes(G1ArrayRangePreWriteBarrier.class).count() + + graph.getNodes(G1ArrayRangePostWriteBarrier.class).count(); Assert.assertTrue(expectedBarriers * 2 == barriers); } else { - barriers = graph.getNodes(SerialWriteBarrier.class).count(); + barriers = graph.getNodes(SerialWriteBarrier.class).count() + graph.getNodes(SerialArrayRangeWriteBarrier.class).count(); Assert.assertTrue(expectedBarriers == barriers); } // Iterate over all write nodes and remove barriers according to input indices. @@ -698,7 +712,7 @@ try { ReentrantNodeIterator.apply(closure, graph.start(), false, null); Debug.setConfig(Debug.fixedConfig(false, false, false, false, config.dumpHandlers(), config.output())); - new WriteBarrierVerificationPhase(((HotSpotRuntime) runtime()).config.useG1GC).apply(graph); + new WriteBarrierVerificationPhase().apply(graph); } catch (AssertionError error) { /* * Catch assertion, test for expected one and re-throw in order to validate unit diff -r c0ce8e825f30 -r b1f438bf1a40 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 Jul 16 15:08:28 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Tue Jul 16 15:08:37 2013 +0200 @@ -1241,7 +1241,7 @@ ret.getMidTier().appendPhase(new WriteBarrierAdditionPhase()); if (VerifyPhases.getValue()) { - ret.getMidTier().appendPhase(new WriteBarrierVerificationPhase(config.useG1GC)); + ret.getMidTier().appendPhase(new WriteBarrierVerificationPhase()); } return ret; diff -r c0ce8e825f30 -r b1f438bf1a40 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 Jul 16 15:08:28 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierVerificationPhase.java Tue Jul 16 15:08:37 2013 +0200 @@ -23,9 +23,12 @@ package com.oracle.graal.hotspot.phases; +import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; + import java.util.*; import com.oracle.graal.graph.*; +import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.HeapAccess.WriteBarrierType; import com.oracle.graal.nodes.extended.*; @@ -41,31 +44,25 @@ */ public class WriteBarrierVerificationPhase extends Phase { - private final boolean useG1GC; - - public WriteBarrierVerificationPhase(boolean useG1GC) { - this.useG1GC = useG1GC; - } - @Override protected void run(StructuredGraph graph) { processWrites(graph); } - private void processWrites(StructuredGraph graph) { + private static void processWrites(StructuredGraph graph) { for (Node node : graph.getNodes()) { - if (isObjectWrite(node)) { + if (isObjectWrite(node) || isObjectArrayRangeWrite(node)) { validateWrite(node); } } } - private void validateWrite(Node write) { + private static void validateWrite(Node write) { /* * 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(); @@ -74,24 +71,43 @@ while (iterator.hasNext()) { Node currentNode = iterator.next(); assert !isSafepoint(currentNode) : "Write barrier must be present"; - if (useG1GC) { + if (useG1GC()) { if (!(currentNode instanceof G1PostWriteBarrier) || ((currentNode instanceof G1PostWriteBarrier) && !validateBarrier(write, (WriteBarrier) currentNode))) { 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) { - 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()); + 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; + } } 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 +119,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) { diff -r c0ce8e825f30 -r b1f438bf1a40 graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java Tue Jul 16 15:08:28 2013 +0200 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java Tue Jul 16 15:08:37 2013 +0200 @@ -715,7 +715,7 @@ private static void decodeKlassPointer(AMD64MacroAssembler masm, Register resRegister, long base, int shift, int alignment) { if (shift != 0) { - assert alignment == shift : "Decode algorighm is wrong"; + assert alignment == shift : "Decode algorithm is wrong"; masm.shlq(resRegister, alignment); if (base != 0) { masm.addq(resRegister, AMD64.r12);