1 /* 2 * Copyright (c) 2016, 2018, Red Hat, Inc. 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 /* 26 * Run standalone with: --add-exports java.base/jdk.internal.misc=ALL-UNNAMED --add-opens java.base/jdk.internal.misc=ALL-UNNAMED 27 */ 28 29 /* 30 * @test id=default 31 * @summary Shenandoah reference CAS test 32 * @requires vm.gc.Shenandoah 33 * @modules java.base/jdk.internal.misc:+open 34 * 35 * @run main/othervm -Diters=20000 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:ShenandoahGCHeuristics=aggressive -XX:+UseShenandoahGC TestReferenceCAS 36 * @run main/othervm -Diters=100 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:ShenandoahGCHeuristics=aggressive -XX:+UseShenandoahGC -Xint TestReferenceCAS 37 * @run main/othervm -Diters=20000 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:ShenandoahGCHeuristics=aggressive -XX:+UseShenandoahGC -XX:-TieredCompilation TestReferenceCAS 38 * @run main/othervm -Diters=20000 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:ShenandoahGCHeuristics=aggressive -XX:+UseShenandoahGC -XX:TieredStopAtLevel=1 TestReferenceCAS 39 * @run main/othervm -Diters=20000 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:ShenandoahGCHeuristics=aggressive -XX:+UseShenandoahGC -XX:TieredStopAtLevel=4 TestReferenceCAS 40 */ 41 42 /* 43 * @test id=no-coops 44 * @summary Shenandoah reference CAS test 45 * @requires vm.gc.Shenandoah 46 * @requires vm.bits == "64" 47 * @modules java.base/jdk.internal.misc:+open 48 * 49 * @run main/othervm -Diters=20000 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:ShenandoahGCHeuristics=aggressive -XX:+UseShenandoahGC -XX:-UseCompressedOops TestReferenceCAS 50 * @run main/othervm -Diters=100 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:ShenandoahGCHeuristics=aggressive -XX:+UseShenandoahGC -XX:-UseCompressedOops -Xint TestReferenceCAS 51 * @run main/othervm -Diters=20000 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:ShenandoahGCHeuristics=aggressive -XX:+UseShenandoahGC -XX:-UseCompressedOops -XX:-TieredCompilation TestReferenceCAS 52 * @run main/othervm -Diters=20000 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:ShenandoahGCHeuristics=aggressive -XX:+UseShenandoahGC -XX:-UseCompressedOops -XX:TieredStopAtLevel=1 TestReferenceCAS 53 * @run main/othervm -Diters=20000 -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:ShenandoahGCHeuristics=aggressive -XX:+UseShenandoahGC -XX:-UseCompressedOops -XX:TieredStopAtLevel=4 TestReferenceCAS 54 */ 55 56 import java.lang.reflect.Field; 57 58 public class TestReferenceCAS { 59 60 static final int ITERS = Integer.getInteger("iters", 1); 61 static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 10); 62 63 static final jdk.internal.misc.Unsafe UNSAFE; 64 static final long V_OFFSET; 65 66 static { 67 try { 68 Field f = jdk.internal.misc.Unsafe.class.getDeclaredField("theUnsafe"); 69 f.setAccessible(true); 70 UNSAFE = (jdk.internal.misc.Unsafe) f.get(null); 71 } catch (Exception e) { 72 throw new RuntimeException("Unable to get Unsafe instance.", e); 73 } 74 75 try { 76 Field vField = TestReferenceCAS.class.getDeclaredField("v"); 77 V_OFFSET = UNSAFE.objectFieldOffset(vField); 78 } catch (Exception e) { 79 throw new RuntimeException(e); 80 } 81 } 82 83 Object v; 84 85 private static void assertEquals(boolean a, boolean b, String msg) { 86 if (a != b) { 87 throw new RuntimeException("a (" + a + ") != b (" + b + "): " + msg); 88 } 89 } 90 91 private static void assertEquals(Object a, Object b, String msg) { 92 if (!a.equals(b)) { 93 throw new RuntimeException("a (" + a.toString() + ") != b (" + b.toString() + "): " + msg); 94 } 95 } 96 97 public static void main(String[] args) { 98 TestReferenceCAS t = new TestReferenceCAS(); 99 for (int c = 0; c < ITERS; c++) { 100 testAccess(t, V_OFFSET); 101 } 102 } 103 104 static void testAccess(Object base, long offset) { 105 String foo = new String("foo"); 106 String bar = new String("bar"); 107 String baz = new String("baz"); 108 UNSAFE.putReference(base, offset, "foo"); 109 { 110 String newval = bar; 111 boolean r = UNSAFE.compareAndSetReference(base, offset, "foo", newval); 112 assertEquals(r, true, "success compareAndSet Object"); 113 assertEquals(newval, "bar", "must not destroy newval"); 114 Object x = UNSAFE.getReference(base, offset); 115 assertEquals(x, "bar", "success compareAndSet Object value"); 116 } 117 118 { 119 String newval = baz; 120 boolean r = UNSAFE.compareAndSetReference(base, offset, "foo", newval); 121 assertEquals(r, false, "failing compareAndSet Object"); 122 assertEquals(newval, "baz", "must not destroy newval"); 123 Object x = UNSAFE.getReference(base, offset); 124 assertEquals(x, "bar", "failing compareAndSet Object value"); 125 } 126 127 UNSAFE.putReference(base, offset, "bar"); 128 { 129 String newval = foo; 130 Object r = UNSAFE.compareAndExchangeReference(base, offset, "bar", newval); 131 assertEquals(r, "bar", "success compareAndExchange Object"); 132 assertEquals(newval, "foo", "must not destroy newval"); 133 Object x = UNSAFE.getReference(base, offset); 134 assertEquals(x, "foo", "success compareAndExchange Object value"); 135 } 136 137 { 138 String newval = baz; 139 Object r = UNSAFE.compareAndExchangeReference(base, offset, "bar", newval); 140 assertEquals(r, "foo", "failing compareAndExchange Object"); 141 assertEquals(newval, "baz", "must not destroy newval"); 142 Object x = UNSAFE.getReference(base, offset); 143 assertEquals(x, "foo", "failing compareAndExchange Object value"); 144 } 145 146 UNSAFE.putReference(base, offset, "bar"); 147 { 148 String newval = foo; 149 boolean success = false; 150 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 151 success = UNSAFE.weakCompareAndSetReference(base, offset, "bar", newval); 152 assertEquals(newval, "foo", "must not destroy newval"); 153 } 154 assertEquals(success, true, "weakCompareAndSet Object"); 155 Object x = UNSAFE.getReference(base, offset); 156 assertEquals(x, "foo", "weakCompareAndSet Object"); 157 } 158 } 159 160 }