# HG changeset patch # User Christian Humer # Date 1371762833 -7200 # Node ID 3754634b49a75931ea3beedfd87a88a75a1c3a20 # Parent 648165ffcf262631f8f05daa0146f900261ffc24# Parent 6447890af1bf4832457adbffe7301a2a4f6dd333 Merge. diff -r 648165ffcf26 -r 3754634b49a7 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/WriteBarrierAdditionTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/WriteBarrierAdditionTest.java Thu Jun 20 21:33:00 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.compiler.test; - -import org.junit.*; - -import com.oracle.graal.api.code.*; -import com.oracle.graal.debug.*; -import com.oracle.graal.hotspot.phases.*; -import com.oracle.graal.nodes.HeapAccess.WriteBarrierType; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.spi.Lowerable.LoweringType; -import com.oracle.graal.phases.common.*; -import com.oracle.graal.phases.tiers.*; - -public class WriteBarrierAdditionTest extends GraalCompilerTest { - - public static class Container { - - public Container a; - public Container b; - } - - public static void test1Snippet() { - Container main = new Container(); - Container temp1 = new Container(); - Container temp2 = new Container(); - main.a = temp1; - main.b = temp2; - } - - public static void test2Snippet(boolean test) { - Container main = new Container(); - Container temp1 = new Container(); - Container temp2 = new Container(); - for (int i = 0; i < 10; i++) { - if (test) { - main.a = temp1; - main.b = temp2; - } else { - main.a = temp2; - main.b = temp1; - } - } - } - - public static void test3Snippet() { - Container[] main = new Container[10]; - Container temp1 = new Container(); - Container temp2 = new Container(); - for (int i = 0; i < 10; i++) { - main[i].a = main[i].b = temp1; - } - - for (int i = 0; i < 10; i++) { - main[i].a = main[i].b = temp2; - } - - } - - @Test - public void test1() { - test("test1Snippet", 2); - } - - @Test - public void test2() { - test("test2Snippet", 4); - } - - @Test - public void test3() { - test("test3Snippet", 4); - } - - private void test(final String snippet, final int expectedBarriers) { - Debug.scope("WriteBarrierAditionTest", new DebugDumpScope(snippet), new Runnable() { - - public void run() { - StructuredGraph graph = parse(snippet); - HighTierContext context = new HighTierContext(runtime(), new Assumptions(false), replacements); - new LoweringPhase(LoweringType.BEFORE_GUARDS).apply(graph, context); - new WriteBarrierAdditionPhase().apply(graph); - Debug.dump(graph, "After Write Barrier Addition"); - final int barriers = graph.getNodes(SerialWriteBarrier.class).count(); - Assert.assertTrue(barriers == expectedBarriers); - for (WriteNode write : graph.getNodes(WriteNode.class)) { - if (write.getWriteBarrierType() != WriteBarrierType.NONE) { - Assert.assertTrue(write.successors().count() == 1); - Assert.assertTrue(write.next() instanceof SerialWriteBarrier); - } - } - } - }); - } -} diff -r 648165ffcf26 -r 3754634b49a7 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/WriteBarrierVerificationTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/WriteBarrierVerificationTest.java Thu Jun 20 21:33:00 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,712 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.compiler.test; - -import java.util.*; -import java.util.concurrent.*; - -import org.junit.*; - -import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.*; -import com.oracle.graal.debug.*; -import com.oracle.graal.debug.internal.*; -import com.oracle.graal.hotspot.phases.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.spi.Lowerable.LoweringType; -import com.oracle.graal.phases.*; -import com.oracle.graal.phases.common.*; -import com.oracle.graal.phases.graph.*; -import com.oracle.graal.phases.graph.ReentrantNodeIterator.NodeIteratorClosure; -import com.oracle.graal.phases.tiers.*; - -/** - * The following tests validate the write barrier verification phase. For every tested snippet, an - * array of write barrier indices and the total write barrier number are passed as parameters. The - * indices denote the barriers that will be manually removed. The write barrier verification phase - * runs after the write barrier removal and depending on the result an assertion might be generated. - * The tests anticipate the presence or not of an assertion generated by the verification phase. - */ -public class WriteBarrierVerificationTest extends GraalCompilerTest { - - public static int barrierIndex; - - public static class Container { - - public Container a; - public Container b; - } - - private static native void safepoint(); - - public static void test1Snippet() { - Container main = new Container(); - Container temp1 = new Container(); - Container temp2 = new Container(); - barrierIndex = 0; - safepoint(); - barrierIndex = 1; - main.a = temp1; - safepoint(); - barrierIndex = 2; - main.b = temp2; - safepoint(); - } - - @Test(expected = AssertionError.class) - public void test1() { - test("test1Snippet", 2, new int[]{1}); - } - - @Test(expected = AssertionError.class) - public void test2() { - test("test1Snippet", 2, new int[]{2}); - } - - public static void test2Snippet() { - Container main = new Container(); - Container temp1 = new Container(); - Container temp2 = new Container(); - barrierIndex = 0; - safepoint(); - barrierIndex = 1; - main.a = temp1; - barrierIndex = 2; - main.b = temp2; - safepoint(); - } - - @Test(expected = AssertionError.class) - public void test3() { - test("test2Snippet", 2, new int[]{1}); - } - - @Test - public void test4() { - test("test2Snippet", 2, new int[]{2}); - } - - public static void test3Snippet(boolean test) { - Container main = new Container(); - Container temp1 = new Container(); - Container temp2 = new Container(); - barrierIndex = 0; - safepoint(); - for (int i = 0; i < 10; i++) { - if (test) { - barrierIndex = 1; - main.a = temp1; - barrierIndex = 2; - main.b = temp2; - } else { - barrierIndex = 3; - main.a = temp1; - barrierIndex = 4; - main.b = temp2; - } - } - } - - @Test(expected = AssertionError.class) - public void test5() { - test("test3Snippet", 4, new int[]{1, 2}); - } - - @Test(expected = AssertionError.class) - public void test6() { - test("test3Snippet", 4, new int[]{3, 4}); - } - - @Test(expected = AssertionError.class) - public void test7() { - test("test3Snippet", 4, new int[]{1}); - } - - @Test - public void test8() { - test("test3Snippet", 4, new int[]{2}); - } - - @Test(expected = AssertionError.class) - public void test9() { - test("test3Snippet", 4, new int[]{3}); - } - - @Test - public void test10() { - test("test3Snippet", 4, new int[]{4}); - } - - public static void test4Snippet(boolean test) { - Container main = new Container(); - Container temp1 = new Container(); - Container temp2 = new Container(); - safepoint(); - barrierIndex = 1; - main.a = temp1; - for (int i = 0; i < 10; i++) { - if (test) { - barrierIndex = 2; - main.a = temp1; - barrierIndex = 3; - main.b = temp2; - } else { - barrierIndex = 4; - main.a = temp2; - barrierIndex = 5; - main.b = temp1; - } - } - } - - @Test(expected = AssertionError.class) - public void test11() { - test("test4Snippet", 5, new int[]{2, 3}); - } - - @Test(expected = AssertionError.class) - public void test12() { - test("test4Snippet", 5, new int[]{4, 5}); - } - - @Test(expected = AssertionError.class) - public void test13() { - test("test4Snippet", 5, new int[]{1}); - } - - public static void test5Snippet() { - Container main = new Container(); - Container temp1 = new Container(); - Container temp2 = new Container(); - safepoint(); - barrierIndex = 1; - main.a = temp1; - if (main.a == main.b) { - barrierIndex = 2; - main.a = temp1; - barrierIndex = 3; - main.b = temp2; - } else { - barrierIndex = 4; - main.a = temp2; - barrierIndex = 5; - main.b = temp1; - } - safepoint(); - } - - @Test(expected = AssertionError.class) - public void test14() { - test("test5Snippet", 5, new int[]{1}); - } - - @Test - public void test15() { - test("test5Snippet", 5, new int[]{2}); - } - - @Test - public void test16() { - test("test5Snippet", 5, new int[]{4}); - } - - @Test - public void test17() { - test("test5Snippet", 5, new int[]{3}); - } - - @Test - public void test18() { - test("test5Snippet", 5, new int[]{5}); - } - - @Test - public void test19() { - test("test5Snippet", 5, new int[]{2, 3}); - } - - @Test - public void test20() { - test("test5Snippet", 5, new int[]{4, 5}); - } - - public static void test6Snippet(boolean test) { - Container main = new Container(); - Container temp1 = new Container(); - Container temp2 = new Container(); - safepoint(); - barrierIndex = 1; - main.a = temp1; - if (test) { - barrierIndex = 2; - main.a = temp1; - barrierIndex = 3; - main.b = temp1.a.a; - } else { - barrierIndex = 4; - main.a = temp2; - barrierIndex = 5; - main.b = temp2.a.a; - } - safepoint(); - } - - @Test(expected = AssertionError.class) - public void test21() { - test("test6Snippet", 5, new int[]{1}); - } - - @Test(expected = AssertionError.class) - public void test22() { - test("test6Snippet", 5, new int[]{1, 2}); - } - - @Test(expected = AssertionError.class) - public void test23() { - test("test6Snippet", 5, new int[]{3}); - } - - @Test - public void test24() { - test("test6Snippet", 5, new int[]{4}); - } - - public static void test7Snippet(boolean test) { - Container main = new Container(); - Container temp1 = new Container(); - Container temp2 = new Container(); - safepoint(); - barrierIndex = 1; - main.a = temp1; - if (test) { - barrierIndex = 2; - main.a = temp1; - } - barrierIndex = 3; - main.b = temp2; - safepoint(); - } - - @Test - public void test25() { - test("test7Snippet", 3, new int[]{2}); - } - - @Test - public void test26() { - test("test7Snippet", 3, new int[]{3}); - } - - @Test - public void test27() { - test("test7Snippet", 3, new int[]{2, 3}); - } - - @Test(expected = AssertionError.class) - public void test28() { - test("test7Snippet", 3, new int[]{1}); - } - - public static void test8Snippet(boolean test) { - Container main = new Container(); - Container temp1 = new Container(); - Container temp2 = new Container(); - safepoint(); - if (test) { - barrierIndex = 1; - main.a = temp1; - } - barrierIndex = 2; - main.b = temp2; - safepoint(); - } - - @Test(expected = AssertionError.class) - public void test29() { - test("test8Snippet", 2, new int[]{1}); - } - - @Test(expected = AssertionError.class) - public void test30() { - test("test8Snippet", 2, new int[]{2}); - } - - @Test(expected = AssertionError.class) - public void test31() { - test("test8Snippet", 2, new int[]{1, 2}); - } - - public static void test9Snippet(boolean test) { - Container main1 = new Container(); - Container main2 = new Container(); - Container temp1 = new Container(); - Container temp2 = new Container(); - safepoint(); - if (test) { - barrierIndex = 1; - main1.a = temp1; - } else { - barrierIndex = 2; - main2.a = temp1; - } - barrierIndex = 3; - main1.b = temp2; - barrierIndex = 4; - main2.b = temp2; - safepoint(); - } - - @Test(expected = AssertionError.class) - public void test32() { - test("test9Snippet", 4, new int[]{1}); - } - - @Test(expected = AssertionError.class) - public void test33() { - test("test9Snippet", 4, new int[]{2}); - } - - @Test(expected = AssertionError.class) - public void test34() { - test("test9Snippet", 4, new int[]{3}); - } - - @Test(expected = AssertionError.class) - public void test35() { - test("test9Snippet", 4, new int[]{4}); - } - - @Test(expected = AssertionError.class) - public void test36() { - test("test9Snippet", 4, new int[]{1, 2}); - } - - @Test(expected = AssertionError.class) - public void test37() { - test("test9Snippet", 4, new int[]{3, 4}); - } - - public static void test10Snippet(boolean test) { - Container main1 = new Container(); - Container main2 = new Container(); - Container temp1 = new Container(); - Container temp2 = new Container(); - safepoint(); - if (test) { - barrierIndex = 1; - main1.a = temp1; - barrierIndex = 2; - main2.a = temp2; - } else { - barrierIndex = 3; - main2.a = temp1; - } - barrierIndex = 4; - main1.b = temp2; - barrierIndex = 5; - main2.b = temp2; - safepoint(); - } - - @Test(expected = AssertionError.class) - public void test38() { - test("test10Snippet", 5, new int[]{1}); - } - - @Test(expected = AssertionError.class) - public void test39() { - test("test10Snippet", 5, new int[]{2}); - } - - @Test(expected = AssertionError.class) - public void test40() { - test("test10Snippet", 5, new int[]{3}); - } - - @Test(expected = AssertionError.class) - public void test41() { - test("test10Snippet", 5, new int[]{4}); - } - - @Test - public void test42() { - test("test10Snippet", 5, new int[]{5}); - } - - @Test(expected = AssertionError.class) - public void test43() { - test("test10Snippet", 5, new int[]{1, 2}); - } - - @Test(expected = AssertionError.class) - public void test44() { - test("test10Snippet", 5, new int[]{1, 2, 3}); - } - - @Test(expected = AssertionError.class) - public void test45() { - test("test10Snippet", 5, new int[]{3, 4}); - } - - public static void test11Snippet(boolean test) { - Container main1 = new Container(); - Container main2 = new Container(); - Container main3 = new Container(); - Container temp1 = new Container(); - Container temp2 = new Container(); - safepoint(); - if (test) { - barrierIndex = 1; - main1.a = temp1; - barrierIndex = 2; - main3.a = temp1; - if (!test) { - barrierIndex = 3; - main2.a = temp2; - } else { - barrierIndex = 4; - main1.a = temp2; - barrierIndex = 5; - main3.a = temp2; - } - } else { - barrierIndex = 6; - main1.b = temp2; - for (int i = 0; i < 10; i++) { - barrierIndex = 7; - main3.a = temp1; - } - barrierIndex = 8; - main3.b = temp2; - } - barrierIndex = 9; - main1.b = temp2; - barrierIndex = 10; - main2.b = temp2; - barrierIndex = 11; - main3.b = temp2; - safepoint(); - } - - @Test(expected = AssertionError.class) - public void test46() { - test("test11Snippet", 11, new int[]{1}); - } - - @Test(expected = AssertionError.class) - public void test47() { - test("test11Snippet", 11, new int[]{2}); - } - - @Test(expected = AssertionError.class) - public void test48() { - test("test11Snippet", 11, new int[]{3}); - } - - @Test(expected = AssertionError.class) - public void test49() { - test("test11Snippet", 11, new int[]{6}); - } - - @Test(expected = AssertionError.class) - public void test50() { - test("test11Snippet", 11, new int[]{7}); - } - - @Test(expected = AssertionError.class) - public void test51() { - test("test11Snippet", 11, new int[]{8}); - } - - @Test(expected = AssertionError.class) - public void test52() { - test("test11Snippet", 11, new int[]{9}); - } - - @Test(expected = AssertionError.class) - public void test53() { - test("test11Snippet", 11, new int[]{10}); - } - - @Test - public void test54() { - test("test11Snippet", 11, new int[]{4}); - } - - @Test - public void test55() { - test("test11Snippet", 11, new int[]{5}); - } - - @Test - public void test56() { - test("test11Snippet", 11, new int[]{11}); - } - - public static void test12Snippet(boolean test) { - Container main = new Container(); - Container main1 = new Container(); - Container temp1 = new Container(); - Container temp2 = new Container(); - barrierIndex = 0; - safepoint(); - barrierIndex = 7; - main1.a = temp1; - for (int i = 0; i < 10; i++) { - if (test) { - barrierIndex = 1; - main.a = temp1; - barrierIndex = 2; - main.b = temp2; - } else { - barrierIndex = 3; - main.a = temp1; - barrierIndex = 4; - main.b = temp2; - } - } - barrierIndex = 5; - main.a = temp1; - barrierIndex = 6; - main.b = temp1; - barrierIndex = 8; - main1.b = temp1; - safepoint(); - } - - @Test(expected = AssertionError.class) - public void test57() { - test("test12Snippet", 8, new int[]{5}); - } - - @Test - public void test58() { - test("test12Snippet", 8, new int[]{6}); - } - - @Test(expected = AssertionError.class) - public void test59() { - test("test12Snippet", 8, new int[]{7}); - } - - @Test(expected = AssertionError.class) - public void test60() { - test("test12Snippet", 8, new int[]{8}); - } - - private void test(final String snippet, final int expectedBarriers, final int... removedBarrierIndices) { - - AssertionError expectedError = Debug.scope("WriteBarrierVerificationTest", new DebugDumpScope(snippet), new Callable() { - - public AssertionError call() { - final StructuredGraph graph = parse(snippet); - HighTierContext highTierContext = new HighTierContext(runtime(), new Assumptions(false), replacements); - 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 WriteBarrierAdditionPhase().apply(graph); - - // First, the total number of expected barriers is checked. - final int barriers = graph.getNodes(SerialWriteBarrier.class).count(); - Assert.assertTrue(expectedBarriers == barriers); - - // Iterate over all write nodes and remove barriers according to input indices. - NodeIteratorClosure closure = new NodeIteratorClosure() { - - @Override - protected Boolean processNode(FixedNode node, Boolean currentState) { - if (node instanceof WriteNode) { - WriteNode write = (WriteNode) node; - LocationIdentity obj = write.getLocationIdentity(); - if (obj instanceof ResolvedJavaField) { - if (((ResolvedJavaField) obj).getName().equals("barrierIndex")) { - /* - * A "barrierIndex" variable was found and is checked against - * the input barrier array. - */ - if (eliminateBarrier(write.value().asConstant().asInt(), removedBarrierIndices)) { - return true; - } - } - } - } else if (node instanceof SerialWriteBarrier) { - // Remove flagged write barriers. - if (currentState) { - graph.removeFixed(((SerialWriteBarrier) node)); - return false; - } - } - return currentState; - } - - private boolean eliminateBarrier(int index, int[] map) { - for (int i = 0; i < map.length; i++) { - if (map[i] == index) { - return true; - } - } - return false; - } - - @Override - protected Map processLoop(LoopBeginNode loop, Boolean initialState) { - return ReentrantNodeIterator.processLoop(this, loop, initialState).exitStates; - } - - @Override - protected Boolean merge(MergeNode merge, List states) { - return false; - } - - @Override - protected Boolean afterSplit(AbstractBeginNode node, Boolean oldState) { - return false; - } - }; - - DebugConfig config = DebugScope.getConfig(); - try { - ReentrantNodeIterator.apply(closure, graph.start(), false, null); - Debug.setConfig(Debug.fixedConfig(false, false, false, false, config.dumpHandlers(), config.output())); - new WriteBarrierVerificationPhase().apply(graph); - } catch (AssertionError error) { - /* - * Catch assertion, test for expected one and re-throw in order to validate unit - * test. - */ - Assert.assertTrue(error.getMessage().equals("Write barrier must be present")); - return error; - } finally { - Debug.setConfig(config); - } - return null; - } - }); - if (expectedError != null) { - throw expectedError; - } - } -} diff -r 648165ffcf26 -r 3754634b49a7 graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java Thu Jun 20 23:13:53 2013 +0200 @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.test; + +import org.junit.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.compiler.test.*; +import com.oracle.graal.debug.*; +import com.oracle.graal.hotspot.phases.*; +import com.oracle.graal.nodes.HeapAccess.WriteBarrierType; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.spi.Lowerable.LoweringType; +import com.oracle.graal.phases.common.*; +import com.oracle.graal.phases.tiers.*; + +public class WriteBarrierAdditionTest extends GraalCompilerTest { + + public static class Container { + + public Container a; + public Container b; + } + + public static void test1Snippet() { + Container main = new Container(); + Container temp1 = new Container(); + Container temp2 = new Container(); + main.a = temp1; + main.b = temp2; + } + + public static void test2Snippet(boolean test) { + Container main = new Container(); + Container temp1 = new Container(); + Container temp2 = new Container(); + for (int i = 0; i < 10; i++) { + if (test) { + main.a = temp1; + main.b = temp2; + } else { + main.a = temp2; + main.b = temp1; + } + } + } + + public static void test3Snippet() { + Container[] main = new Container[10]; + Container temp1 = new Container(); + Container temp2 = new Container(); + for (int i = 0; i < 10; i++) { + main[i].a = main[i].b = temp1; + } + + for (int i = 0; i < 10; i++) { + main[i].a = main[i].b = temp2; + } + + } + + @Test + public void test1() { + test("test1Snippet", 2); + } + + @Test + public void test2() { + test("test2Snippet", 4); + } + + @Test + public void test3() { + test("test3Snippet", 4); + } + + private void test(final String snippet, final int expectedBarriers) { + Debug.scope("WriteBarrierAditionTest", new DebugDumpScope(snippet), new Runnable() { + + public void run() { + StructuredGraph graph = parse(snippet); + HighTierContext context = new HighTierContext(runtime(), new Assumptions(false), replacements); + new LoweringPhase(LoweringType.BEFORE_GUARDS).apply(graph, context); + new WriteBarrierAdditionPhase().apply(graph); + Debug.dump(graph, "After Write Barrier Addition"); + final int barriers = graph.getNodes(SerialWriteBarrier.class).count(); + Assert.assertTrue(barriers == expectedBarriers); + for (WriteNode write : graph.getNodes(WriteNode.class)) { + if (write.getWriteBarrierType() != WriteBarrierType.NONE) { + Assert.assertTrue(write.successors().count() == 1); + Assert.assertTrue(write.next() instanceof SerialWriteBarrier); + } + } + } + }); + } +} diff -r 648165ffcf26 -r 3754634b49a7 graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java Thu Jun 20 23:13:53 2013 +0200 @@ -0,0 +1,713 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.test; + +import java.util.*; +import java.util.concurrent.*; + +import org.junit.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.test.*; +import com.oracle.graal.debug.*; +import com.oracle.graal.debug.internal.*; +import com.oracle.graal.hotspot.phases.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.spi.Lowerable.LoweringType; +import com.oracle.graal.phases.*; +import com.oracle.graal.phases.common.*; +import com.oracle.graal.phases.graph.*; +import com.oracle.graal.phases.graph.ReentrantNodeIterator.NodeIteratorClosure; +import com.oracle.graal.phases.tiers.*; + +/** + * The following tests validate the write barrier verification phase. For every tested snippet, an + * array of write barrier indices and the total write barrier number are passed as parameters. The + * indices denote the barriers that will be manually removed. The write barrier verification phase + * runs after the write barrier removal and depending on the result an assertion might be generated. + * The tests anticipate the presence or not of an assertion generated by the verification phase. + */ +public class WriteBarrierVerificationTest extends GraalCompilerTest { + + public static int barrierIndex; + + public static class Container { + + public Container a; + public Container b; + } + + private static native void safepoint(); + + public static void test1Snippet() { + Container main = new Container(); + Container temp1 = new Container(); + Container temp2 = new Container(); + barrierIndex = 0; + safepoint(); + barrierIndex = 1; + main.a = temp1; + safepoint(); + barrierIndex = 2; + main.b = temp2; + safepoint(); + } + + @Test(expected = AssertionError.class) + public void test1() { + test("test1Snippet", 2, new int[]{1}); + } + + @Test(expected = AssertionError.class) + public void test2() { + test("test1Snippet", 2, new int[]{2}); + } + + public static void test2Snippet() { + Container main = new Container(); + Container temp1 = new Container(); + Container temp2 = new Container(); + barrierIndex = 0; + safepoint(); + barrierIndex = 1; + main.a = temp1; + barrierIndex = 2; + main.b = temp2; + safepoint(); + } + + @Test(expected = AssertionError.class) + public void test3() { + test("test2Snippet", 2, new int[]{1}); + } + + @Test + public void test4() { + test("test2Snippet", 2, new int[]{2}); + } + + public static void test3Snippet(boolean test) { + Container main = new Container(); + Container temp1 = new Container(); + Container temp2 = new Container(); + barrierIndex = 0; + safepoint(); + for (int i = 0; i < 10; i++) { + if (test) { + barrierIndex = 1; + main.a = temp1; + barrierIndex = 2; + main.b = temp2; + } else { + barrierIndex = 3; + main.a = temp1; + barrierIndex = 4; + main.b = temp2; + } + } + } + + @Test(expected = AssertionError.class) + public void test5() { + test("test3Snippet", 4, new int[]{1, 2}); + } + + @Test(expected = AssertionError.class) + public void test6() { + test("test3Snippet", 4, new int[]{3, 4}); + } + + @Test(expected = AssertionError.class) + public void test7() { + test("test3Snippet", 4, new int[]{1}); + } + + @Test + public void test8() { + test("test3Snippet", 4, new int[]{2}); + } + + @Test(expected = AssertionError.class) + public void test9() { + test("test3Snippet", 4, new int[]{3}); + } + + @Test + public void test10() { + test("test3Snippet", 4, new int[]{4}); + } + + public static void test4Snippet(boolean test) { + Container main = new Container(); + Container temp1 = new Container(); + Container temp2 = new Container(); + safepoint(); + barrierIndex = 1; + main.a = temp1; + for (int i = 0; i < 10; i++) { + if (test) { + barrierIndex = 2; + main.a = temp1; + barrierIndex = 3; + main.b = temp2; + } else { + barrierIndex = 4; + main.a = temp2; + barrierIndex = 5; + main.b = temp1; + } + } + } + + @Test(expected = AssertionError.class) + public void test11() { + test("test4Snippet", 5, new int[]{2, 3}); + } + + @Test(expected = AssertionError.class) + public void test12() { + test("test4Snippet", 5, new int[]{4, 5}); + } + + @Test(expected = AssertionError.class) + public void test13() { + test("test4Snippet", 5, new int[]{1}); + } + + public static void test5Snippet() { + Container main = new Container(); + Container temp1 = new Container(); + Container temp2 = new Container(); + safepoint(); + barrierIndex = 1; + main.a = temp1; + if (main.a == main.b) { + barrierIndex = 2; + main.a = temp1; + barrierIndex = 3; + main.b = temp2; + } else { + barrierIndex = 4; + main.a = temp2; + barrierIndex = 5; + main.b = temp1; + } + safepoint(); + } + + @Test(expected = AssertionError.class) + public void test14() { + test("test5Snippet", 5, new int[]{1}); + } + + @Test + public void test15() { + test("test5Snippet", 5, new int[]{2}); + } + + @Test + public void test16() { + test("test5Snippet", 5, new int[]{4}); + } + + @Test + public void test17() { + test("test5Snippet", 5, new int[]{3}); + } + + @Test + public void test18() { + test("test5Snippet", 5, new int[]{5}); + } + + @Test + public void test19() { + test("test5Snippet", 5, new int[]{2, 3}); + } + + @Test + public void test20() { + test("test5Snippet", 5, new int[]{4, 5}); + } + + public static void test6Snippet(boolean test) { + Container main = new Container(); + Container temp1 = new Container(); + Container temp2 = new Container(); + safepoint(); + barrierIndex = 1; + main.a = temp1; + if (test) { + barrierIndex = 2; + main.a = temp1; + barrierIndex = 3; + main.b = temp1.a.a; + } else { + barrierIndex = 4; + main.a = temp2; + barrierIndex = 5; + main.b = temp2.a.a; + } + safepoint(); + } + + @Test(expected = AssertionError.class) + public void test21() { + test("test6Snippet", 5, new int[]{1}); + } + + @Test(expected = AssertionError.class) + public void test22() { + test("test6Snippet", 5, new int[]{1, 2}); + } + + @Test(expected = AssertionError.class) + public void test23() { + test("test6Snippet", 5, new int[]{3}); + } + + @Test + public void test24() { + test("test6Snippet", 5, new int[]{4}); + } + + public static void test7Snippet(boolean test) { + Container main = new Container(); + Container temp1 = new Container(); + Container temp2 = new Container(); + safepoint(); + barrierIndex = 1; + main.a = temp1; + if (test) { + barrierIndex = 2; + main.a = temp1; + } + barrierIndex = 3; + main.b = temp2; + safepoint(); + } + + @Test + public void test25() { + test("test7Snippet", 3, new int[]{2}); + } + + @Test + public void test26() { + test("test7Snippet", 3, new int[]{3}); + } + + @Test + public void test27() { + test("test7Snippet", 3, new int[]{2, 3}); + } + + @Test(expected = AssertionError.class) + public void test28() { + test("test7Snippet", 3, new int[]{1}); + } + + public static void test8Snippet(boolean test) { + Container main = new Container(); + Container temp1 = new Container(); + Container temp2 = new Container(); + safepoint(); + if (test) { + barrierIndex = 1; + main.a = temp1; + } + barrierIndex = 2; + main.b = temp2; + safepoint(); + } + + @Test(expected = AssertionError.class) + public void test29() { + test("test8Snippet", 2, new int[]{1}); + } + + @Test(expected = AssertionError.class) + public void test30() { + test("test8Snippet", 2, new int[]{2}); + } + + @Test(expected = AssertionError.class) + public void test31() { + test("test8Snippet", 2, new int[]{1, 2}); + } + + public static void test9Snippet(boolean test) { + Container main1 = new Container(); + Container main2 = new Container(); + Container temp1 = new Container(); + Container temp2 = new Container(); + safepoint(); + if (test) { + barrierIndex = 1; + main1.a = temp1; + } else { + barrierIndex = 2; + main2.a = temp1; + } + barrierIndex = 3; + main1.b = temp2; + barrierIndex = 4; + main2.b = temp2; + safepoint(); + } + + @Test(expected = AssertionError.class) + public void test32() { + test("test9Snippet", 4, new int[]{1}); + } + + @Test(expected = AssertionError.class) + public void test33() { + test("test9Snippet", 4, new int[]{2}); + } + + @Test(expected = AssertionError.class) + public void test34() { + test("test9Snippet", 4, new int[]{3}); + } + + @Test(expected = AssertionError.class) + public void test35() { + test("test9Snippet", 4, new int[]{4}); + } + + @Test(expected = AssertionError.class) + public void test36() { + test("test9Snippet", 4, new int[]{1, 2}); + } + + @Test(expected = AssertionError.class) + public void test37() { + test("test9Snippet", 4, new int[]{3, 4}); + } + + public static void test10Snippet(boolean test) { + Container main1 = new Container(); + Container main2 = new Container(); + Container temp1 = new Container(); + Container temp2 = new Container(); + safepoint(); + if (test) { + barrierIndex = 1; + main1.a = temp1; + barrierIndex = 2; + main2.a = temp2; + } else { + barrierIndex = 3; + main2.a = temp1; + } + barrierIndex = 4; + main1.b = temp2; + barrierIndex = 5; + main2.b = temp2; + safepoint(); + } + + @Test(expected = AssertionError.class) + public void test38() { + test("test10Snippet", 5, new int[]{1}); + } + + @Test(expected = AssertionError.class) + public void test39() { + test("test10Snippet", 5, new int[]{2}); + } + + @Test(expected = AssertionError.class) + public void test40() { + test("test10Snippet", 5, new int[]{3}); + } + + @Test(expected = AssertionError.class) + public void test41() { + test("test10Snippet", 5, new int[]{4}); + } + + @Test + public void test42() { + test("test10Snippet", 5, new int[]{5}); + } + + @Test(expected = AssertionError.class) + public void test43() { + test("test10Snippet", 5, new int[]{1, 2}); + } + + @Test(expected = AssertionError.class) + public void test44() { + test("test10Snippet", 5, new int[]{1, 2, 3}); + } + + @Test(expected = AssertionError.class) + public void test45() { + test("test10Snippet", 5, new int[]{3, 4}); + } + + public static void test11Snippet(boolean test) { + Container main1 = new Container(); + Container main2 = new Container(); + Container main3 = new Container(); + Container temp1 = new Container(); + Container temp2 = new Container(); + safepoint(); + if (test) { + barrierIndex = 1; + main1.a = temp1; + barrierIndex = 2; + main3.a = temp1; + if (!test) { + barrierIndex = 3; + main2.a = temp2; + } else { + barrierIndex = 4; + main1.a = temp2; + barrierIndex = 5; + main3.a = temp2; + } + } else { + barrierIndex = 6; + main1.b = temp2; + for (int i = 0; i < 10; i++) { + barrierIndex = 7; + main3.a = temp1; + } + barrierIndex = 8; + main3.b = temp2; + } + barrierIndex = 9; + main1.b = temp2; + barrierIndex = 10; + main2.b = temp2; + barrierIndex = 11; + main3.b = temp2; + safepoint(); + } + + @Test(expected = AssertionError.class) + public void test46() { + test("test11Snippet", 11, new int[]{1}); + } + + @Test(expected = AssertionError.class) + public void test47() { + test("test11Snippet", 11, new int[]{2}); + } + + @Test(expected = AssertionError.class) + public void test48() { + test("test11Snippet", 11, new int[]{3}); + } + + @Test(expected = AssertionError.class) + public void test49() { + test("test11Snippet", 11, new int[]{6}); + } + + @Test(expected = AssertionError.class) + public void test50() { + test("test11Snippet", 11, new int[]{7}); + } + + @Test(expected = AssertionError.class) + public void test51() { + test("test11Snippet", 11, new int[]{8}); + } + + @Test(expected = AssertionError.class) + public void test52() { + test("test11Snippet", 11, new int[]{9}); + } + + @Test(expected = AssertionError.class) + public void test53() { + test("test11Snippet", 11, new int[]{10}); + } + + @Test + public void test54() { + test("test11Snippet", 11, new int[]{4}); + } + + @Test + public void test55() { + test("test11Snippet", 11, new int[]{5}); + } + + @Test + public void test56() { + test("test11Snippet", 11, new int[]{11}); + } + + public static void test12Snippet(boolean test) { + Container main = new Container(); + Container main1 = new Container(); + Container temp1 = new Container(); + Container temp2 = new Container(); + barrierIndex = 0; + safepoint(); + barrierIndex = 7; + main1.a = temp1; + for (int i = 0; i < 10; i++) { + if (test) { + barrierIndex = 1; + main.a = temp1; + barrierIndex = 2; + main.b = temp2; + } else { + barrierIndex = 3; + main.a = temp1; + barrierIndex = 4; + main.b = temp2; + } + } + barrierIndex = 5; + main.a = temp1; + barrierIndex = 6; + main.b = temp1; + barrierIndex = 8; + main1.b = temp1; + safepoint(); + } + + @Test(expected = AssertionError.class) + public void test57() { + test("test12Snippet", 8, new int[]{5}); + } + + @Test + public void test58() { + test("test12Snippet", 8, new int[]{6}); + } + + @Test(expected = AssertionError.class) + public void test59() { + test("test12Snippet", 8, new int[]{7}); + } + + @Test(expected = AssertionError.class) + public void test60() { + test("test12Snippet", 8, new int[]{8}); + } + + private void test(final String snippet, final int expectedBarriers, final int... removedBarrierIndices) { + + AssertionError expectedError = Debug.scope("WriteBarrierVerificationTest", new DebugDumpScope(snippet), new Callable() { + + public AssertionError call() { + final StructuredGraph graph = parse(snippet); + HighTierContext highTierContext = new HighTierContext(runtime(), new Assumptions(false), replacements); + 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 WriteBarrierAdditionPhase().apply(graph); + + // First, the total number of expected barriers is checked. + final int barriers = graph.getNodes(SerialWriteBarrier.class).count(); + Assert.assertTrue(expectedBarriers == barriers); + + // Iterate over all write nodes and remove barriers according to input indices. + NodeIteratorClosure closure = new NodeIteratorClosure() { + + @Override + protected Boolean processNode(FixedNode node, Boolean currentState) { + if (node instanceof WriteNode) { + WriteNode write = (WriteNode) node; + LocationIdentity obj = write.getLocationIdentity(); + if (obj instanceof ResolvedJavaField) { + if (((ResolvedJavaField) obj).getName().equals("barrierIndex")) { + /* + * A "barrierIndex" variable was found and is checked against + * the input barrier array. + */ + if (eliminateBarrier(write.value().asConstant().asInt(), removedBarrierIndices)) { + return true; + } + } + } + } else if (node instanceof SerialWriteBarrier) { + // Remove flagged write barriers. + if (currentState) { + graph.removeFixed(((SerialWriteBarrier) node)); + return false; + } + } + return currentState; + } + + private boolean eliminateBarrier(int index, int[] map) { + for (int i = 0; i < map.length; i++) { + if (map[i] == index) { + return true; + } + } + return false; + } + + @Override + protected Map processLoop(LoopBeginNode loop, Boolean initialState) { + return ReentrantNodeIterator.processLoop(this, loop, initialState).exitStates; + } + + @Override + protected Boolean merge(MergeNode merge, List states) { + return false; + } + + @Override + protected Boolean afterSplit(AbstractBeginNode node, Boolean oldState) { + return false; + } + }; + + DebugConfig config = DebugScope.getConfig(); + try { + ReentrantNodeIterator.apply(closure, graph.start(), false, null); + Debug.setConfig(Debug.fixedConfig(false, false, false, false, config.dumpHandlers(), config.output())); + new WriteBarrierVerificationPhase().apply(graph); + } catch (AssertionError error) { + /* + * Catch assertion, test for expected one and re-throw in order to validate unit + * test. + */ + Assert.assertTrue(error.getMessage().equals("Write barrier must be present")); + return error; + } finally { + Debug.setConfig(config); + } + return null; + } + }); + if (expectedError != null) { + throw expectedError; + } + } +} diff -r 648165ffcf26 -r 3754634b49a7 mx/projects --- a/mx/projects Thu Jun 20 21:33:00 2013 +0200 +++ b/mx/projects Thu Jun 20 23:13:53 2013 +0200 @@ -141,7 +141,7 @@ # graal.hotspot.test project@com.oracle.graal.hotspot.test@subDir=graal project@com.oracle.graal.hotspot.test@sourceDirs=src -project@com.oracle.graal.hotspot.test@dependencies=com.oracle.graal.replacements.test +project@com.oracle.graal.hotspot.test@dependencies=com.oracle.graal.replacements.test,com.oracle.graal.hotspot project@com.oracle.graal.hotspot.test@checkstyle=com.oracle.graal.graph project@com.oracle.graal.hotspot.test@javaCompliance=1.7 project@com.oracle.graal.hotspot.test@workingSets=Graal,HotSpot,Test @@ -260,7 +260,7 @@ # graal.replacements.test project@com.oracle.graal.replacements.test@subDir=graal project@com.oracle.graal.replacements.test@sourceDirs=src -project@com.oracle.graal.replacements.test@dependencies=com.oracle.graal.compiler.test +project@com.oracle.graal.replacements.test@dependencies=com.oracle.graal.compiler.test,com.oracle.graal.replacements project@com.oracle.graal.replacements.test@checkstyle=com.oracle.graal.graph project@com.oracle.graal.replacements.test@javaCompliance=1.7 project@com.oracle.graal.replacements.test@workingSets=Graal,Replacements,Test @@ -404,7 +404,7 @@ # graal.compiler.test project@com.oracle.graal.compiler.test@subDir=graal project@com.oracle.graal.compiler.test@sourceDirs=src -project@com.oracle.graal.compiler.test@dependencies=com.oracle.graal.test,com.oracle.graal.hotspot +project@com.oracle.graal.compiler.test@dependencies=com.oracle.graal.test,com.oracle.graal.printer project@com.oracle.graal.compiler.test@checkstyle=com.oracle.graal.graph project@com.oracle.graal.compiler.test@javaCompliance=1.7 project@com.oracle.graal.compiler.test@workingSets=Graal,Test