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 }