1 /* 2 * Copyright (c) 2013 SAP SE. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /** 25 * @test 26 * @bug 8007898 27 * @summary Incorrect optimization of Memory Barriers in Matcher::post_store_load_barrier(). 28 * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation 29 * -XX:CICompilerCount=1 -XX:+StressGCM -XX:+StressLCM 30 * compiler.membars.DekkerTest 31 * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation 32 * -XX:CICompilerCount=1 -XX:+StressGCM -XX:+StressLCM 33 * compiler.membars.DekkerTest 34 * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation 35 * -XX:CICompilerCount=1 -XX:+StressGCM -XX:+StressLCM 36 * compiler.membars.DekkerTest 37 * @author Martin Doerr martin DOT doerr AT sap DOT com 38 * 39 * Run 3 times since the failure is intermittent. 40 */ 41 42 package compiler.membars; 43 44 public class DekkerTest { 45 46 /* 47 Read After Write Test (basically a simple Dekker test with volatile variables) 48 Derived from the original jcstress test, available at: 49 http://hg.openjdk.java.net/code-tools/jcstress/file/6c339a5aa00d/ 50 tests-custom/src/main/java/org/openjdk/jcstress/tests/volatiles/DekkerTest.java 51 */ 52 53 static final int ITERATIONS = 1000000; 54 55 static class TestData { 56 public volatile int a; 57 public volatile int b; 58 } 59 60 static class ResultData { 61 public int a; 62 public int b; 63 } 64 65 TestData[] testDataArray; 66 ResultData[] results; 67 68 volatile boolean start; 69 70 public DekkerTest() { 71 testDataArray = new TestData[ITERATIONS]; 72 results = new ResultData[ITERATIONS]; 73 for (int i = 0; i < ITERATIONS; ++i) { 74 testDataArray[i] = new TestData(); 75 results[i] = new ResultData(); 76 } 77 start = false; 78 } 79 80 public void reset() { 81 for (int i = 0; i < ITERATIONS; ++i) { 82 testDataArray[i].a = 0; 83 testDataArray[i].b = 0; 84 results[i].a = 0; 85 results[i].b = 0; 86 } 87 start = false; 88 } 89 90 int actor1(TestData t) { 91 t.a = 1; 92 return t.b; 93 } 94 95 int actor2(TestData t) { 96 t.b = 1; 97 return t.a; 98 } 99 100 class Runner1 extends Thread { 101 public void run() { 102 do {} while (!start); 103 for (int i = 0; i < ITERATIONS; ++i) { 104 results[i].a = actor1(testDataArray[i]); 105 } 106 } 107 } 108 109 class Runner2 extends Thread { 110 public void run() { 111 do {} while (!start); 112 for (int i = 0; i < ITERATIONS; ++i) { 113 results[i].b = actor2(testDataArray[i]); 114 } 115 } 116 } 117 118 void testRunner() { 119 Thread thread1 = new Runner1(); 120 Thread thread2 = new Runner2(); 121 thread1.start(); 122 thread2.start(); 123 do {} while (!thread1.isAlive()); 124 do {} while (!thread2.isAlive()); 125 start = true; 126 Thread.yield(); 127 try { 128 thread1.join(); 129 thread2.join(); 130 } catch (InterruptedException e) { 131 System.out.println("interrupted!"); 132 System.exit(1); 133 } 134 } 135 136 boolean printResult() { 137 int[] count = new int[4]; 138 for (int i = 0; i < ITERATIONS; ++i) { 139 int event_kind = (results[i].a << 1) + results[i].b; 140 ++count[event_kind]; 141 } 142 if (count[0] == 0 && count[3] == 0) { 143 System.out.println("[not interesting]"); 144 return false; // not interesting 145 } 146 String error = (count[0] == 0) ? " ok" : " disallowed!"; 147 System.out.println("[0,0] " + count[0] + error); 148 System.out.println("[0,1] " + count[1]); 149 System.out.println("[1,0] " + count[2]); 150 System.out.println("[1,1] " + count[3]); 151 return (count[0] != 0); 152 } 153 154 public static void main(String args[]) { 155 DekkerTest test = new DekkerTest(); 156 final int runs = 30; 157 int failed = 0; 158 for (int c = 0; c < runs; ++c) { 159 test.testRunner(); 160 if (test.printResult()) { 161 failed++; 162 } 163 test.reset(); 164 } 165 if (failed > 0) { 166 throw new InternalError("FAILED. Got " + failed + " failed ITERATIONS"); 167 } 168 System.out.println("PASSED."); 169 } 170 171 }