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 }