1 /*
   2  * Copyright (c) 2015, 2019, Oracle and/or its affiliates. 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 #warn
  25 
  26 #if[Value]
  27 /*
  28  * @test
  29  * @run testng/othervm -Diters=10    -XX:+EnableValhalla -Xint                   VarHandleTestAccess$Type$
  30  * @run testng/othervm -Diters=20000 -XX:+EnableValhalla -XX:TieredStopAtLevel=1 VarHandleTestAccess$Type$
  31  * @run testng/othervm -Diters=20000 -XX:+EnableValhalla                         VarHandleTestAccess$Type$
  32  * @run testng/othervm -Diters=20000 -XX:+EnableValhalla -XX:-TieredCompilation  VarHandleTestAccess$Type$
  33  */
  34 #else[Value]
  35 /*
  36  * @test
  37  * @run testng/othervm -Diters=10    -Xint                   VarHandleTestAccess$Type$
  38  * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccess$Type$
  39  * @run testng/othervm -Diters=20000                         VarHandleTestAccess$Type$
  40  * @run testng/othervm -Diters=20000 -XX:-TieredCompilation  VarHandleTestAccess$Type$
  41  */
  42 #end[Value]
  43 
  44 import org.testng.annotations.BeforeClass;
  45 import org.testng.annotations.DataProvider;
  46 import org.testng.annotations.Test;
  47 
  48 import java.lang.invoke.MethodHandles;
  49 import java.lang.invoke.VarHandle;
  50 import java.util.ArrayList;
  51 import java.util.Arrays;
  52 import java.util.List;
  53 
  54 import static org.testng.Assert.*;
  55 
  56 public class VarHandleTestAccess$Type$ extends VarHandleBaseTest {
  57     static final $type$ static_final_v = $value1$;
  58 
  59     static $type$ static_v;
  60 
  61     final $type$ final_v = $value1$;
  62 
  63     $type$ v;
  64 
  65     static final $type$ static_final_v2 = $value1$;
  66 
  67     static $type$ static_v2;
  68 
  69     final $type$ final_v2 = $value1$;
  70 
  71     $type$ v2;
  72 
  73     VarHandle vhFinalField;
  74 
  75     VarHandle vhField;
  76 
  77     VarHandle vhStaticField;
  78 
  79     VarHandle vhStaticFinalField;
  80 
  81     VarHandle vhArray;
  82 
  83 #if[Class]]
  84     VarHandle vhArrayObject;
  85 #end[Class]]
  86 #if[Value]
  87     VarHandle vhValueTypeField;
  88 #end[Value]
  89 
  90     VarHandle[] allocate(boolean same) {
  91         List<VarHandle> vhs = new ArrayList<>();
  92 
  93         String postfix = same ? "" : "2";
  94         VarHandle vh;
  95         try {
  96             vh = MethodHandles.lookup().findVarHandle(
  97                     VarHandleTestAccess$Type$.class, "final_v" + postfix, $type$.class);
  98             vhs.add(vh);
  99 
 100             vh = MethodHandles.lookup().findVarHandle(
 101                     VarHandleTestAccess$Type$.class, "v" + postfix, $type$.class);
 102             vhs.add(vh);
 103 
 104             vh = MethodHandles.lookup().findStaticVarHandle(
 105                 VarHandleTestAccess$Type$.class, "static_final_v" + postfix, $type$.class);
 106             vhs.add(vh);
 107 
 108             vh = MethodHandles.lookup().findStaticVarHandle(
 109                 VarHandleTestAccess$Type$.class, "static_v" + postfix, $type$.class);
 110             vhs.add(vh);
 111 
 112             if (same) {
 113                 vh = MethodHandles.arrayElementVarHandle($type$[].class);
 114             }
 115             else {
 116 #if[String]
 117                 vh = MethodHandles.arrayElementVarHandle(int[].class);
 118 #else[String]
 119                 vh = MethodHandles.arrayElementVarHandle(String[].class);
 120 #end[String]
 121             }
 122             vhs.add(vh);
 123         } catch (Exception e) {
 124             throw new InternalError(e);
 125         }
 126         return vhs.toArray(new VarHandle[0]);
 127     }
 128 
 129     @BeforeClass
 130     public void setup() throws Exception {
 131         vhFinalField = MethodHandles.lookup().findVarHandle(
 132                 VarHandleTestAccess$Type$.class, "final_v", $type$.class);
 133 
 134         vhField = MethodHandles.lookup().findVarHandle(
 135                 VarHandleTestAccess$Type$.class, "v", $type$.class);
 136 
 137         vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
 138             VarHandleTestAccess$Type$.class, "static_final_v", $type$.class);
 139 
 140         vhStaticField = MethodHandles.lookup().findStaticVarHandle(
 141             VarHandleTestAccess$Type$.class, "static_v", $type$.class);
 142 
 143         vhArray = MethodHandles.arrayElementVarHandle($type$[].class);
 144 #if[Class]]
 145         vhArrayObject = MethodHandles.arrayElementVarHandle(Object[].class);
 146 #end[Class]]
 147 
 148 #if[Value]
 149         vhValueTypeField = MethodHandles.lookup().findVarHandle(
 150                     Value.class, "$type$_v", $type$.class);
 151 #end[Value]
 152     }
 153 
 154 
 155     @DataProvider
 156     public Object[][] varHandlesProvider() throws Exception {
 157         List<VarHandle> vhs = new ArrayList<>();
 158         vhs.add(vhField);
 159         vhs.add(vhStaticField);
 160         vhs.add(vhArray);
 161 
 162         return vhs.stream().map(tc -> new Object[]{tc}).toArray(Object[][]::new);
 163     }
 164 
 165     @Test
 166     public void testEquals() {
 167         VarHandle[] vhs1 = allocate(true);
 168         VarHandle[] vhs2 = allocate(true);
 169 
 170         for (int i = 0; i < vhs1.length; i++) {
 171             for (int j = 0; j < vhs1.length; j++) {
 172                 if (i != j) {
 173                     assertNotEquals(vhs1[i], vhs1[j]);
 174                     assertNotEquals(vhs1[i], vhs2[j]);
 175                 }
 176             }
 177         }
 178 
 179         VarHandle[] vhs3 = allocate(false);
 180         for (int i = 0; i < vhs1.length; i++) {
 181             assertNotEquals(vhs1[i], vhs3[i]);
 182         }
 183     }
 184 
 185     @Test(dataProvider = "varHandlesProvider")
 186     public void testIsAccessModeSupported(VarHandle vh) {
 187         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET));
 188         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET));
 189         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_VOLATILE));
 190         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_VOLATILE));
 191         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_ACQUIRE));
 192         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_RELEASE));
 193         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_OPAQUE));
 194         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_OPAQUE));
 195 
 196 #if[CAS]
 197         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_SET));
 198         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE));
 199         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
 200         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
 201         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_PLAIN));
 202         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
 203         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
 204         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
 205         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
 206         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET_ACQUIRE));
 207         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET_RELEASE));
 208 #else[CAS]
 209         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_SET));
 210         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE));
 211         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
 212         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
 213         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_PLAIN));
 214         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
 215         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
 216         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
 217         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
 218         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET_ACQUIRE));
 219         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET_RELEASE));
 220 #end[CAS]
 221 
 222 #if[AtomicAdd]
 223         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
 224         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD_ACQUIRE));
 225         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD_RELEASE));
 226 #else[AtomicAdd]
 227         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
 228         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD_ACQUIRE));
 229         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD_RELEASE));
 230 #end[AtomicAdd]
 231 
 232 #if[Bitwise]
 233         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR));
 234         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR_ACQUIRE));
 235         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR_RELEASE));
 236         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND));
 237         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND_ACQUIRE));
 238         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND_RELEASE));
 239         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR));
 240         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_ACQUIRE));
 241         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_RELEASE));
 242 #else[Bitwise]
 243         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR));
 244         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR_ACQUIRE));
 245         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR_RELEASE));
 246         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND));
 247         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND_ACQUIRE));
 248         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND_RELEASE));
 249         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR));
 250         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_ACQUIRE));
 251         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_RELEASE));
 252 #end[Bitwise]
 253     }
 254 
 255 
 256     @DataProvider
 257     public Object[][] typesProvider() throws Exception {
 258         List<Object[]> types = new ArrayList<>();
 259         types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccess$Type$.class)});
 260         types.add(new Object[] {vhStaticField, Arrays.asList()});
 261         types.add(new Object[] {vhArray, Arrays.asList($type$[].class, int.class)});
 262 
 263         return types.stream().toArray(Object[][]::new);
 264     }
 265 
 266     @Test(dataProvider = "typesProvider")
 267     public void testTypes(VarHandle vh, List<Class<?>> pts) {
 268         assertEquals(vh.varType(), $type$.class);
 269 
 270         assertEquals(vh.coordinateTypes(), pts);
 271 
 272         testTypes(vh);
 273     }
 274 
 275 
 276     @Test
 277     public void testLookupInstanceToStatic() {
 278         checkIAE("Lookup of static final field to instance final field", () -> {
 279             MethodHandles.lookup().findStaticVarHandle(
 280                     VarHandleTestAccess$Type$.class, "final_v", $type$.class);
 281         });
 282 
 283         checkIAE("Lookup of static field to instance field", () -> {
 284             MethodHandles.lookup().findStaticVarHandle(
 285                     VarHandleTestAccess$Type$.class, "v", $type$.class);
 286         });
 287     }
 288 
 289     @Test
 290     public void testLookupStaticToInstance() {
 291         checkIAE("Lookup of instance final field to static final field", () -> {
 292             MethodHandles.lookup().findVarHandle(
 293                 VarHandleTestAccess$Type$.class, "static_final_v", $type$.class);
 294         });
 295 
 296         checkIAE("Lookup of instance field to static field", () -> {
 297             vhStaticField = MethodHandles.lookup().findVarHandle(
 298                 VarHandleTestAccess$Type$.class, "static_v", $type$.class);
 299         });
 300     }
 301 
 302 
 303     @DataProvider
 304     public Object[][] accessTestCaseProvider() throws Exception {
 305         List<AccessTestCase<?>> cases = new ArrayList<>();
 306 
 307         cases.add(new VarHandleAccessTestCase("Instance final field",
 308                                               vhFinalField, vh -> testInstanceFinalField(this, vh)));
 309         cases.add(new VarHandleAccessTestCase("Instance final field unsupported",
 310                                               vhFinalField, vh -> testInstanceFinalFieldUnsupported(this, vh),
 311                                               false));
 312 
 313         cases.add(new VarHandleAccessTestCase("Static final field",
 314                                               vhStaticFinalField, VarHandleTestAccess$Type$::testStaticFinalField));
 315         cases.add(new VarHandleAccessTestCase("Static final field unsupported",
 316                                               vhStaticFinalField, VarHandleTestAccess$Type$::testStaticFinalFieldUnsupported,
 317                                               false));
 318 
 319         cases.add(new VarHandleAccessTestCase("Instance field",
 320                                               vhField, vh -> testInstanceField(this, vh)));
 321         cases.add(new VarHandleAccessTestCase("Instance field unsupported",
 322                                               vhField, vh -> testInstanceFieldUnsupported(this, vh),
 323                                               false));
 324 
 325         cases.add(new VarHandleAccessTestCase("Static field",
 326                                               vhStaticField, VarHandleTestAccess$Type$::testStaticField));
 327         cases.add(new VarHandleAccessTestCase("Static field unsupported",
 328                                               vhStaticField, VarHandleTestAccess$Type$::testStaticFieldUnsupported,
 329                                               false));
 330 
 331         cases.add(new VarHandleAccessTestCase("Array",
 332                                               vhArray, VarHandleTestAccess$Type$::testArray));
 333 #if[Class]]
 334         cases.add(new VarHandleAccessTestCase("Array Object[]",
 335                                               vhArrayObject, VarHandleTestAccess$Type$::testArray));
 336 #end[Class]]
 337         cases.add(new VarHandleAccessTestCase("Array unsupported",
 338                                               vhArray, VarHandleTestAccess$Type$::testArrayUnsupported,
 339                                               false));
 340         cases.add(new VarHandleAccessTestCase("Array index out of bounds",
 341                                               vhArray, VarHandleTestAccess$Type$::testArrayIndexOutOfBounds,
 342                                               false));
 343 #if[Class]]
 344         cases.add(new VarHandleAccessTestCase("Array store exception",
 345                                               vhArrayObject, VarHandleTestAccess$Type$::testArrayStoreException,
 346                                               false));
 347 #end[Class]]
 348 #if[Value]
 349         cases.add(new VarHandleAccessTestCase("Value type field",
 350                                               vhValueTypeField, vh -> testValueTypeField(Value.getInstance(), vh)));
 351         cases.add(new VarHandleAccessTestCase("Value type field unsupported",
 352                                               vhValueTypeField, vh -> testValueTypeFieldUnsupported(Value.getInstance(), vh),
 353                                               false));
 354 #end[Value]
 355         // Work around issue with jtreg summary reporting which truncates
 356         // the String result of Object.toString to 30 characters, hence
 357         // the first dummy argument
 358         return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
 359     }
 360 
 361     @Test(dataProvider = "accessTestCaseProvider")
 362     public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
 363         T t = atc.get();
 364         int iters = atc.requiresLoop() ? ITERS : 1;
 365         for (int c = 0; c < iters; c++) {
 366             atc.testAccess(t);
 367         }
 368     }
 369 
 370 
 371 
 372 
 373     static void testInstanceFinalField(VarHandleTestAccess$Type$ recv, VarHandle vh) {
 374         // Plain
 375         {
 376             $type$ x = ($type$) vh.get(recv);
 377             assertEquals(x, $value1$, "get $type$ value");
 378         }
 379 
 380 
 381         // Volatile
 382         {
 383             $type$ x = ($type$) vh.getVolatile(recv);
 384             assertEquals(x, $value1$, "getVolatile $type$ value");
 385         }
 386 
 387         // Lazy
 388         {
 389             $type$ x = ($type$) vh.getAcquire(recv);
 390             assertEquals(x, $value1$, "getRelease $type$ value");
 391         }
 392 
 393         // Opaque
 394         {
 395             $type$ x = ($type$) vh.getOpaque(recv);
 396             assertEquals(x, $value1$, "getOpaque $type$ value");
 397         }
 398     }
 399 
 400     static void testInstanceFinalFieldUnsupported(VarHandleTestAccess$Type$ recv, VarHandle vh) {
 401         checkUOE(() -> {
 402             vh.set(recv, $value2$);
 403         });
 404 
 405         checkUOE(() -> {
 406             vh.setVolatile(recv, $value2$);
 407         });
 408 
 409         checkUOE(() -> {
 410             vh.setRelease(recv, $value2$);
 411         });
 412 
 413         checkUOE(() -> {
 414             vh.setOpaque(recv, $value2$);
 415         });
 416 
 417 #if[!CAS]
 418         checkUOE(() -> {
 419             boolean r = vh.compareAndSet(recv, $value1$, $value2$);
 420         });
 421 
 422         checkUOE(() -> {
 423             $type$ r = ($type$) vh.compareAndExchange(recv, $value1$, $value2$);
 424         });
 425 
 426         checkUOE(() -> {
 427             $type$ r = ($type$) vh.compareAndExchangeAcquire(recv, $value1$, $value2$);
 428         });
 429 
 430         checkUOE(() -> {
 431             $type$ r = ($type$) vh.compareAndExchangeRelease(recv, $value1$, $value2$);
 432         });
 433 
 434         checkUOE(() -> {
 435             boolean r = vh.weakCompareAndSetPlain(recv, $value1$, $value2$);
 436         });
 437 
 438         checkUOE(() -> {
 439             boolean r = vh.weakCompareAndSet(recv, $value1$, $value2$);
 440         });
 441 
 442         checkUOE(() -> {
 443             boolean r = vh.weakCompareAndSetAcquire(recv, $value1$, $value2$);
 444         });
 445 
 446         checkUOE(() -> {
 447             boolean r = vh.weakCompareAndSetRelease(recv, $value1$, $value2$);
 448         });
 449 
 450         checkUOE(() -> {
 451             $type$ r = ($type$) vh.getAndSet(recv, $value1$);
 452         });
 453 
 454         checkUOE(() -> {
 455             $type$ r = ($type$) vh.getAndSetAcquire(recv, $value1$);
 456         });
 457 
 458         checkUOE(() -> {
 459             $type$ r = ($type$) vh.getAndSetRelease(recv, $value1$);
 460         });
 461 #end[CAS]
 462 
 463 #if[!AtomicAdd]
 464         checkUOE(() -> {
 465             $type$ o = ($type$) vh.getAndAdd(recv, $value1$);
 466         });
 467 
 468         checkUOE(() -> {
 469             $type$ o = ($type$) vh.getAndAddAcquire(recv, $value1$);
 470         });
 471 
 472         checkUOE(() -> {
 473             $type$ o = ($type$) vh.getAndAddRelease(recv, $value1$);
 474         });
 475 #end[AtomicAdd]
 476 
 477 #if[!Bitwise]
 478         checkUOE(() -> {
 479             $type$ o = ($type$) vh.getAndBitwiseOr(recv, $value1$);
 480         });
 481 
 482         checkUOE(() -> {
 483             $type$ o = ($type$) vh.getAndBitwiseOrAcquire(recv, $value1$);
 484         });
 485 
 486         checkUOE(() -> {
 487             $type$ o = ($type$) vh.getAndBitwiseOrRelease(recv, $value1$);
 488         });
 489 
 490         checkUOE(() -> {
 491             $type$ o = ($type$) vh.getAndBitwiseAnd(recv, $value1$);
 492         });
 493 
 494         checkUOE(() -> {
 495             $type$ o = ($type$) vh.getAndBitwiseAndAcquire(recv, $value1$);
 496         });
 497 
 498         checkUOE(() -> {
 499             $type$ o = ($type$) vh.getAndBitwiseAndRelease(recv, $value1$);
 500         });
 501 
 502         checkUOE(() -> {
 503             $type$ o = ($type$) vh.getAndBitwiseXor(recv, $value1$);
 504         });
 505 
 506         checkUOE(() -> {
 507             $type$ o = ($type$) vh.getAndBitwiseXorAcquire(recv, $value1$);
 508         });
 509 
 510         checkUOE(() -> {
 511             $type$ o = ($type$) vh.getAndBitwiseXorRelease(recv, $value1$);
 512         });
 513 #end[Bitwise]
 514     }
 515 
 516 #if[Value]
 517     static void testValueTypeField(Value recv, VarHandle vh) {
 518         // Plain
 519         {
 520             $type$ x = ($type$) vh.get(recv);
 521             assertEquals(x, $value1$, "get $type$ value");
 522         }
 523     }
 524 
 525     static void testValueTypeFieldUnsupported(Value recv, VarHandle vh) {
 526         checkUOE(() -> {
 527             vh.set(recv, $value2$);
 528         });
 529     }
 530 #end[Value]
 531 
 532     static void testStaticFinalField(VarHandle vh) {
 533         // Plain
 534         {
 535             $type$ x = ($type$) vh.get();
 536             assertEquals(x, $value1$, "get $type$ value");
 537         }
 538 
 539 
 540         // Volatile
 541         {
 542             $type$ x = ($type$) vh.getVolatile();
 543             assertEquals(x, $value1$, "getVolatile $type$ value");
 544         }
 545 
 546         // Lazy
 547         {
 548             $type$ x = ($type$) vh.getAcquire();
 549             assertEquals(x, $value1$, "getRelease $type$ value");
 550         }
 551 
 552         // Opaque
 553         {
 554             $type$ x = ($type$) vh.getOpaque();
 555             assertEquals(x, $value1$, "getOpaque $type$ value");
 556         }
 557     }
 558 
 559     static void testStaticFinalFieldUnsupported(VarHandle vh) {
 560         checkUOE(() -> {
 561             vh.set($value2$);
 562         });
 563 
 564         checkUOE(() -> {
 565             vh.setVolatile($value2$);
 566         });
 567 
 568         checkUOE(() -> {
 569             vh.setRelease($value2$);
 570         });
 571 
 572         checkUOE(() -> {
 573             vh.setOpaque($value2$);
 574         });
 575 
 576 #if[!CAS]
 577         checkUOE(() -> {
 578             boolean r = vh.compareAndSet($value1$, $value2$);
 579         });
 580 
 581         checkUOE(() -> {
 582             $type$ r = ($type$) vh.compareAndExchange($value1$, $value2$);
 583         });
 584 
 585         checkUOE(() -> {
 586             $type$ r = ($type$) vh.compareAndExchangeAcquire($value1$, $value2$);
 587         });
 588 
 589         checkUOE(() -> {
 590             $type$ r = ($type$) vh.compareAndExchangeRelease($value1$, $value2$);
 591         });
 592 
 593         checkUOE(() -> {
 594             boolean r = vh.weakCompareAndSetPlain($value1$, $value2$);
 595         });
 596 
 597         checkUOE(() -> {
 598             boolean r = vh.weakCompareAndSet($value1$, $value2$);
 599         });
 600 
 601         checkUOE(() -> {
 602             boolean r = vh.weakCompareAndSetAcquire($value1$, $value2$);
 603         });
 604 
 605         checkUOE(() -> {
 606             boolean r = vh.weakCompareAndSetRelease($value1$, $value2$);
 607         });
 608 
 609         checkUOE(() -> {
 610             $type$ r = ($type$) vh.getAndSet($value1$);
 611         });
 612 
 613         checkUOE(() -> {
 614             $type$ r = ($type$) vh.getAndSetAcquire($value1$);
 615         });
 616 
 617         checkUOE(() -> {
 618             $type$ r = ($type$) vh.getAndSetRelease($value1$);
 619         });
 620 #end[CAS]
 621 
 622 #if[!AtomicAdd]
 623         checkUOE(() -> {
 624             $type$ o = ($type$) vh.getAndAdd($value1$);
 625         });
 626 
 627         checkUOE(() -> {
 628             $type$ o = ($type$) vh.getAndAddAcquire($value1$);
 629         });
 630 
 631         checkUOE(() -> {
 632             $type$ o = ($type$) vh.getAndAddRelease($value1$);
 633         });
 634 #end[AtomicAdd]
 635 
 636 #if[!Bitwise]
 637         checkUOE(() -> {
 638             $type$ o = ($type$) vh.getAndBitwiseOr($value1$);
 639         });
 640 
 641         checkUOE(() -> {
 642             $type$ o = ($type$) vh.getAndBitwiseOrAcquire($value1$);
 643         });
 644 
 645         checkUOE(() -> {
 646             $type$ o = ($type$) vh.getAndBitwiseOrRelease($value1$);
 647         });
 648 
 649         checkUOE(() -> {
 650             $type$ o = ($type$) vh.getAndBitwiseAnd($value1$);
 651         });
 652 
 653         checkUOE(() -> {
 654             $type$ o = ($type$) vh.getAndBitwiseAndAcquire($value1$);
 655         });
 656 
 657         checkUOE(() -> {
 658             $type$ o = ($type$) vh.getAndBitwiseAndRelease($value1$);
 659         });
 660 
 661         checkUOE(() -> {
 662             $type$ o = ($type$) vh.getAndBitwiseXor($value1$);
 663         });
 664 
 665         checkUOE(() -> {
 666             $type$ o = ($type$) vh.getAndBitwiseXorAcquire($value1$);
 667         });
 668 
 669         checkUOE(() -> {
 670             $type$ o = ($type$) vh.getAndBitwiseXorRelease($value1$);
 671         });
 672 #end[Bitwise]
 673     }
 674 
 675 
 676     static void testInstanceField(VarHandleTestAccess$Type$ recv, VarHandle vh) {
 677         // Plain
 678         {
 679             vh.set(recv, $value1$);
 680             $type$ x = ($type$) vh.get(recv);
 681             assertEquals(x, $value1$, "set $type$ value");
 682         }
 683 
 684 
 685         // Volatile
 686         {
 687             vh.setVolatile(recv, $value2$);
 688             $type$ x = ($type$) vh.getVolatile(recv);
 689             assertEquals(x, $value2$, "setVolatile $type$ value");
 690         }
 691 
 692         // Lazy
 693         {
 694             vh.setRelease(recv, $value1$);
 695             $type$ x = ($type$) vh.getAcquire(recv);
 696             assertEquals(x, $value1$, "setRelease $type$ value");
 697         }
 698 
 699         // Opaque
 700         {
 701             vh.setOpaque(recv, $value2$);
 702             $type$ x = ($type$) vh.getOpaque(recv);
 703             assertEquals(x, $value2$, "setOpaque $type$ value");
 704         }
 705 
 706 #if[CAS]
 707         vh.set(recv, $value1$);
 708 
 709         // Compare
 710         {
 711             boolean r = vh.compareAndSet(recv, $value1$, $value2$);
 712             assertEquals(r, true, "success compareAndSet $type$");
 713             $type$ x = ($type$) vh.get(recv);
 714             assertEquals(x, $value2$, "success compareAndSet $type$ value");
 715         }
 716 
 717         {
 718             boolean r = vh.compareAndSet(recv, $value1$, $value3$);
 719             assertEquals(r, false, "failing compareAndSet $type$");
 720             $type$ x = ($type$) vh.get(recv);
 721             assertEquals(x, $value2$, "failing compareAndSet $type$ value");
 722         }
 723 
 724         {
 725             $type$ r = ($type$) vh.compareAndExchange(recv, $value2$, $value1$);
 726             assertEquals(r, $value2$, "success compareAndExchange $type$");
 727             $type$ x = ($type$) vh.get(recv);
 728             assertEquals(x, $value1$, "success compareAndExchange $type$ value");
 729         }
 730 
 731         {
 732             $type$ r = ($type$) vh.compareAndExchange(recv, $value2$, $value3$);
 733             assertEquals(r, $value1$, "failing compareAndExchange $type$");
 734             $type$ x = ($type$) vh.get(recv);
 735             assertEquals(x, $value1$, "failing compareAndExchange $type$ value");
 736         }
 737 
 738         {
 739             $type$ r = ($type$) vh.compareAndExchangeAcquire(recv, $value1$, $value2$);
 740             assertEquals(r, $value1$, "success compareAndExchangeAcquire $type$");
 741             $type$ x = ($type$) vh.get(recv);
 742             assertEquals(x, $value2$, "success compareAndExchangeAcquire $type$ value");
 743         }
 744 
 745         {
 746             $type$ r = ($type$) vh.compareAndExchangeAcquire(recv, $value1$, $value3$);
 747             assertEquals(r, $value2$, "failing compareAndExchangeAcquire $type$");
 748             $type$ x = ($type$) vh.get(recv);
 749             assertEquals(x, $value2$, "failing compareAndExchangeAcquire $type$ value");
 750         }
 751 
 752         {
 753             $type$ r = ($type$) vh.compareAndExchangeRelease(recv, $value2$, $value1$);
 754             assertEquals(r, $value2$, "success compareAndExchangeRelease $type$");
 755             $type$ x = ($type$) vh.get(recv);
 756             assertEquals(x, $value1$, "success compareAndExchangeRelease $type$ value");
 757         }
 758 
 759         {
 760             $type$ r = ($type$) vh.compareAndExchangeRelease(recv, $value2$, $value3$);
 761             assertEquals(r, $value1$, "failing compareAndExchangeRelease $type$");
 762             $type$ x = ($type$) vh.get(recv);
 763             assertEquals(x, $value1$, "failing compareAndExchangeRelease $type$ value");
 764         }
 765 
 766         {
 767             boolean success = false;
 768             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 769                 success = vh.weakCompareAndSetPlain(recv, $value1$, $value2$);
 770             }
 771             assertEquals(success, true, "weakCompareAndSetPlain $type$");
 772             $type$ x = ($type$) vh.get(recv);
 773             assertEquals(x, $value2$, "weakCompareAndSetPlain $type$ value");
 774         }
 775 
 776         {
 777             boolean success = false;
 778             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 779                 success = vh.weakCompareAndSetAcquire(recv, $value2$, $value1$);
 780             }
 781             assertEquals(success, true, "weakCompareAndSetAcquire $type$");
 782             $type$ x = ($type$) vh.get(recv);
 783             assertEquals(x, $value1$, "weakCompareAndSetAcquire $type$");
 784         }
 785 
 786         {
 787             boolean success = false;
 788             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 789                 success = vh.weakCompareAndSetRelease(recv, $value1$, $value2$);
 790             }
 791             assertEquals(success, true, "weakCompareAndSetRelease $type$");
 792             $type$ x = ($type$) vh.get(recv);
 793             assertEquals(x, $value2$, "weakCompareAndSetRelease $type$");
 794         }
 795 
 796         {
 797             boolean success = false;
 798             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 799                 success = vh.weakCompareAndSet(recv, $value2$, $value1$);
 800             }
 801             assertEquals(success, true, "weakCompareAndSet $type$");
 802             $type$ x = ($type$) vh.get(recv);
 803             assertEquals(x, $value1$, "weakCompareAndSet $type$ value");
 804         }
 805 
 806         // Compare set and get
 807         {
 808             vh.set(recv, $value1$);
 809 
 810             $type$ o = ($type$) vh.getAndSet(recv, $value2$);
 811             assertEquals(o, $value1$, "getAndSet $type$");
 812             $type$ x = ($type$) vh.get(recv);
 813             assertEquals(x, $value2$, "getAndSet $type$ value");
 814         }
 815 
 816         {
 817             vh.set(recv, $value1$);
 818 
 819             $type$ o = ($type$) vh.getAndSetAcquire(recv, $value2$);
 820             assertEquals(o, $value1$, "getAndSetAcquire $type$");
 821             $type$ x = ($type$) vh.get(recv);
 822             assertEquals(x, $value2$, "getAndSetAcquire $type$ value");
 823         }
 824 
 825         {
 826             vh.set(recv, $value1$);
 827 
 828             $type$ o = ($type$) vh.getAndSetRelease(recv, $value2$);
 829             assertEquals(o, $value1$, "getAndSetRelease $type$");
 830             $type$ x = ($type$) vh.get(recv);
 831             assertEquals(x, $value2$, "getAndSetRelease $type$ value");
 832         }
 833 #end[CAS]
 834 
 835 #if[AtomicAdd]
 836         // get and add, add and get
 837         {
 838             vh.set(recv, $value1$);
 839 
 840             $type$ o = ($type$) vh.getAndAdd(recv, $value2$);
 841             assertEquals(o, $value1$, "getAndAdd $type$");
 842             $type$ x = ($type$) vh.get(recv);
 843             assertEquals(x, ($type$)($value1$ + $value2$), "getAndAdd $type$ value");
 844         }
 845 
 846         {
 847             vh.set(recv, $value1$);
 848 
 849             $type$ o = ($type$) vh.getAndAddAcquire(recv, $value2$);
 850             assertEquals(o, $value1$, "getAndAddAcquire $type$");
 851             $type$ x = ($type$) vh.get(recv);
 852             assertEquals(x, ($type$)($value1$ + $value2$), "getAndAddAcquire $type$ value");
 853         }
 854 
 855         {
 856             vh.set(recv, $value1$);
 857 
 858             $type$ o = ($type$) vh.getAndAddRelease(recv, $value2$);
 859             assertEquals(o, $value1$, "getAndAddRelease$type$");
 860             $type$ x = ($type$) vh.get(recv);
 861             assertEquals(x, ($type$)($value1$ + $value2$), "getAndAddRelease $type$ value");
 862         }
 863 #end[AtomicAdd]
 864 
 865 #if[Bitwise]
 866         // get and bitwise or
 867         {
 868             vh.set(recv, $value1$);
 869 
 870             $type$ o = ($type$) vh.getAndBitwiseOr(recv, $value2$);
 871             assertEquals(o, $value1$, "getAndBitwiseOr $type$");
 872             $type$ x = ($type$) vh.get(recv);
 873             assertEquals(x, ($type$)($value1$ | $value2$), "getAndBitwiseOr $type$ value");
 874         }
 875 
 876         {
 877             vh.set(recv, $value1$);
 878 
 879             $type$ o = ($type$) vh.getAndBitwiseOrAcquire(recv, $value2$);
 880             assertEquals(o, $value1$, "getAndBitwiseOrAcquire $type$");
 881             $type$ x = ($type$) vh.get(recv);
 882             assertEquals(x, ($type$)($value1$ | $value2$), "getAndBitwiseOrAcquire $type$ value");
 883         }
 884 
 885         {
 886             vh.set(recv, $value1$);
 887 
 888             $type$ o = ($type$) vh.getAndBitwiseOrRelease(recv, $value2$);
 889             assertEquals(o, $value1$, "getAndBitwiseOrRelease $type$");
 890             $type$ x = ($type$) vh.get(recv);
 891             assertEquals(x, ($type$)($value1$ | $value2$), "getAndBitwiseOrRelease $type$ value");
 892         }
 893 
 894         // get and bitwise and
 895         {
 896             vh.set(recv, $value1$);
 897 
 898             $type$ o = ($type$) vh.getAndBitwiseAnd(recv, $value2$);
 899             assertEquals(o, $value1$, "getAndBitwiseAnd $type$");
 900             $type$ x = ($type$) vh.get(recv);
 901             assertEquals(x, ($type$)($value1$ & $value2$), "getAndBitwiseAnd $type$ value");
 902         }
 903 
 904         {
 905             vh.set(recv, $value1$);
 906 
 907             $type$ o = ($type$) vh.getAndBitwiseAndAcquire(recv, $value2$);
 908             assertEquals(o, $value1$, "getAndBitwiseAndAcquire $type$");
 909             $type$ x = ($type$) vh.get(recv);
 910             assertEquals(x, ($type$)($value1$ & $value2$), "getAndBitwiseAndAcquire $type$ value");
 911         }
 912 
 913         {
 914             vh.set(recv, $value1$);
 915 
 916             $type$ o = ($type$) vh.getAndBitwiseAndRelease(recv, $value2$);
 917             assertEquals(o, $value1$, "getAndBitwiseAndRelease $type$");
 918             $type$ x = ($type$) vh.get(recv);
 919             assertEquals(x, ($type$)($value1$ & $value2$), "getAndBitwiseAndRelease $type$ value");
 920         }
 921 
 922         // get and bitwise xor
 923         {
 924             vh.set(recv, $value1$);
 925 
 926             $type$ o = ($type$) vh.getAndBitwiseXor(recv, $value2$);
 927             assertEquals(o, $value1$, "getAndBitwiseXor $type$");
 928             $type$ x = ($type$) vh.get(recv);
 929             assertEquals(x, ($type$)($value1$ ^ $value2$), "getAndBitwiseXor $type$ value");
 930         }
 931 
 932         {
 933             vh.set(recv, $value1$);
 934 
 935             $type$ o = ($type$) vh.getAndBitwiseXorAcquire(recv, $value2$);
 936             assertEquals(o, $value1$, "getAndBitwiseXorAcquire $type$");
 937             $type$ x = ($type$) vh.get(recv);
 938             assertEquals(x, ($type$)($value1$ ^ $value2$), "getAndBitwiseXorAcquire $type$ value");
 939         }
 940 
 941         {
 942             vh.set(recv, $value1$);
 943 
 944             $type$ o = ($type$) vh.getAndBitwiseXorRelease(recv, $value2$);
 945             assertEquals(o, $value1$, "getAndBitwiseXorRelease $type$");
 946             $type$ x = ($type$) vh.get(recv);
 947             assertEquals(x, ($type$)($value1$ ^ $value2$), "getAndBitwiseXorRelease $type$ value");
 948         }
 949 #end[Bitwise]
 950     }
 951 
 952     static void testInstanceFieldUnsupported(VarHandleTestAccess$Type$ recv, VarHandle vh) {
 953 #if[!CAS]
 954         checkUOE(() -> {
 955             boolean r = vh.compareAndSet(recv, $value1$, $value2$);
 956         });
 957 
 958         checkUOE(() -> {
 959             $type$ r = ($type$) vh.compareAndExchange(recv, $value1$, $value2$);
 960         });
 961 
 962         checkUOE(() -> {
 963             $type$ r = ($type$) vh.compareAndExchangeAcquire(recv, $value1$, $value2$);
 964         });
 965 
 966         checkUOE(() -> {
 967             $type$ r = ($type$) vh.compareAndExchangeRelease(recv, $value1$, $value2$);
 968         });
 969 
 970         checkUOE(() -> {
 971             boolean r = vh.weakCompareAndSetPlain(recv, $value1$, $value2$);
 972         });
 973 
 974         checkUOE(() -> {
 975             boolean r = vh.weakCompareAndSet(recv, $value1$, $value2$);
 976         });
 977 
 978         checkUOE(() -> {
 979             boolean r = vh.weakCompareAndSetAcquire(recv, $value1$, $value2$);
 980         });
 981 
 982         checkUOE(() -> {
 983             boolean r = vh.weakCompareAndSetRelease(recv, $value1$, $value2$);
 984         });
 985 
 986         checkUOE(() -> {
 987             $type$ r = ($type$) vh.getAndSet(recv, $value1$);
 988         });
 989 
 990         checkUOE(() -> {
 991             $type$ r = ($type$) vh.getAndSetAcquire(recv, $value1$);
 992         });
 993 
 994         checkUOE(() -> {
 995             $type$ r = ($type$) vh.getAndSetRelease(recv, $value1$);
 996         });
 997 #end[CAS]
 998 
 999 #if[!AtomicAdd]
1000         checkUOE(() -> {
1001             $type$ o = ($type$) vh.getAndAdd(recv, $value1$);
1002         });
1003 
1004         checkUOE(() -> {
1005             $type$ o = ($type$) vh.getAndAddAcquire(recv, $value1$);
1006         });
1007 
1008         checkUOE(() -> {
1009             $type$ o = ($type$) vh.getAndAddRelease(recv, $value1$);
1010         });
1011 #end[AtomicAdd]
1012 
1013 #if[!Bitwise]
1014         checkUOE(() -> {
1015             $type$ o = ($type$) vh.getAndBitwiseOr(recv, $value1$);
1016         });
1017 
1018         checkUOE(() -> {
1019             $type$ o = ($type$) vh.getAndBitwiseOrAcquire(recv, $value1$);
1020         });
1021 
1022         checkUOE(() -> {
1023             $type$ o = ($type$) vh.getAndBitwiseOrRelease(recv, $value1$);
1024         });
1025 
1026         checkUOE(() -> {
1027             $type$ o = ($type$) vh.getAndBitwiseAnd(recv, $value1$);
1028         });
1029 
1030         checkUOE(() -> {
1031             $type$ o = ($type$) vh.getAndBitwiseAndAcquire(recv, $value1$);
1032         });
1033 
1034         checkUOE(() -> {
1035             $type$ o = ($type$) vh.getAndBitwiseAndRelease(recv, $value1$);
1036         });
1037 
1038         checkUOE(() -> {
1039             $type$ o = ($type$) vh.getAndBitwiseXor(recv, $value1$);
1040         });
1041 
1042         checkUOE(() -> {
1043             $type$ o = ($type$) vh.getAndBitwiseXorAcquire(recv, $value1$);
1044         });
1045 
1046         checkUOE(() -> {
1047             $type$ o = ($type$) vh.getAndBitwiseXorRelease(recv, $value1$);
1048         });
1049 #end[Bitwise]
1050     }
1051 
1052 
1053     static void testStaticField(VarHandle vh) {
1054         // Plain
1055         {
1056             vh.set($value1$);
1057             $type$ x = ($type$) vh.get();
1058             assertEquals(x, $value1$, "set $type$ value");
1059         }
1060 
1061 
1062         // Volatile
1063         {
1064             vh.setVolatile($value2$);
1065             $type$ x = ($type$) vh.getVolatile();
1066             assertEquals(x, $value2$, "setVolatile $type$ value");
1067         }
1068 
1069         // Lazy
1070         {
1071             vh.setRelease($value1$);
1072             $type$ x = ($type$) vh.getAcquire();
1073             assertEquals(x, $value1$, "setRelease $type$ value");
1074         }
1075 
1076         // Opaque
1077         {
1078             vh.setOpaque($value2$);
1079             $type$ x = ($type$) vh.getOpaque();
1080             assertEquals(x, $value2$, "setOpaque $type$ value");
1081         }
1082 
1083 #if[CAS]
1084         vh.set($value1$);
1085 
1086         // Compare
1087         {
1088             boolean r = vh.compareAndSet($value1$, $value2$);
1089             assertEquals(r, true, "success compareAndSet $type$");
1090             $type$ x = ($type$) vh.get();
1091             assertEquals(x, $value2$, "success compareAndSet $type$ value");
1092         }
1093 
1094         {
1095             boolean r = vh.compareAndSet($value1$, $value3$);
1096             assertEquals(r, false, "failing compareAndSet $type$");
1097             $type$ x = ($type$) vh.get();
1098             assertEquals(x, $value2$, "failing compareAndSet $type$ value");
1099         }
1100 
1101         {
1102             $type$ r = ($type$) vh.compareAndExchange($value2$, $value1$);
1103             assertEquals(r, $value2$, "success compareAndExchange $type$");
1104             $type$ x = ($type$) vh.get();
1105             assertEquals(x, $value1$, "success compareAndExchange $type$ value");
1106         }
1107 
1108         {
1109             $type$ r = ($type$) vh.compareAndExchange($value2$, $value3$);
1110             assertEquals(r, $value1$, "failing compareAndExchange $type$");
1111             $type$ x = ($type$) vh.get();
1112             assertEquals(x, $value1$, "failing compareAndExchange $type$ value");
1113         }
1114 
1115         {
1116             $type$ r = ($type$) vh.compareAndExchangeAcquire($value1$, $value2$);
1117             assertEquals(r, $value1$, "success compareAndExchangeAcquire $type$");
1118             $type$ x = ($type$) vh.get();
1119             assertEquals(x, $value2$, "success compareAndExchangeAcquire $type$ value");
1120         }
1121 
1122         {
1123             $type$ r = ($type$) vh.compareAndExchangeAcquire($value1$, $value3$);
1124             assertEquals(r, $value2$, "failing compareAndExchangeAcquire $type$");
1125             $type$ x = ($type$) vh.get();
1126             assertEquals(x, $value2$, "failing compareAndExchangeAcquire $type$ value");
1127         }
1128 
1129         {
1130             $type$ r = ($type$) vh.compareAndExchangeRelease($value2$, $value1$);
1131             assertEquals(r, $value2$, "success compareAndExchangeRelease $type$");
1132             $type$ x = ($type$) vh.get();
1133             assertEquals(x, $value1$, "success compareAndExchangeRelease $type$ value");
1134         }
1135 
1136         {
1137             $type$ r = ($type$) vh.compareAndExchangeRelease($value2$, $value3$);
1138             assertEquals(r, $value1$, "failing compareAndExchangeRelease $type$");
1139             $type$ x = ($type$) vh.get();
1140             assertEquals(x, $value1$, "failing compareAndExchangeRelease $type$ value");
1141         }
1142 
1143         {
1144             boolean success = false;
1145             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
1146                 success = vh.weakCompareAndSetPlain($value1$, $value2$);
1147             }
1148             assertEquals(success, true, "weakCompareAndSetPlain $type$");
1149             $type$ x = ($type$) vh.get();
1150             assertEquals(x, $value2$, "weakCompareAndSetPlain $type$ value");
1151         }
1152 
1153         {
1154             boolean success = false;
1155             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
1156                 success = vh.weakCompareAndSetAcquire($value2$, $value1$);
1157             }
1158             assertEquals(success, true, "weakCompareAndSetAcquire $type$");
1159             $type$ x = ($type$) vh.get();
1160             assertEquals(x, $value1$, "weakCompareAndSetAcquire $type$");
1161         }
1162 
1163         {
1164             boolean success = false;
1165             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
1166                 success = vh.weakCompareAndSetRelease($value1$, $value2$);
1167             }
1168             assertEquals(success, true, "weakCompareAndSetRelease $type$");
1169             $type$ x = ($type$) vh.get();
1170             assertEquals(x, $value2$, "weakCompareAndSetRelease $type$");
1171         }
1172 
1173         {
1174             boolean success = false;
1175             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
1176                 success = vh.weakCompareAndSet($value2$, $value1$);
1177             }
1178             assertEquals(success, true, "weakCompareAndSet $type$");
1179             $type$ x = ($type$) vh.get();
1180             assertEquals(x, $value1$, "weakCompareAndSet $type$");
1181         }
1182 
1183         // Compare set and get
1184         {
1185             vh.set($value1$);
1186 
1187             $type$ o = ($type$) vh.getAndSet($value2$);
1188             assertEquals(o, $value1$, "getAndSet $type$");
1189             $type$ x = ($type$) vh.get();
1190             assertEquals(x, $value2$, "getAndSet $type$ value");
1191         }
1192 
1193         {
1194             vh.set($value1$);
1195 
1196             $type$ o = ($type$) vh.getAndSetAcquire($value2$);
1197             assertEquals(o, $value1$, "getAndSetAcquire $type$");
1198             $type$ x = ($type$) vh.get();
1199             assertEquals(x, $value2$, "getAndSetAcquire $type$ value");
1200         }
1201 
1202         {
1203             vh.set($value1$);
1204 
1205             $type$ o = ($type$) vh.getAndSetRelease($value2$);
1206             assertEquals(o, $value1$, "getAndSetRelease $type$");
1207             $type$ x = ($type$) vh.get();
1208             assertEquals(x, $value2$, "getAndSetRelease $type$ value");
1209         }
1210 #end[CAS]
1211 
1212 #if[AtomicAdd]
1213         // get and add, add and get
1214         {
1215             vh.set($value1$);
1216 
1217             $type$ o = ($type$) vh.getAndAdd($value2$);
1218             assertEquals(o, $value1$, "getAndAdd $type$");
1219             $type$ x = ($type$) vh.get();
1220             assertEquals(x, ($type$)($value1$ + $value2$), "getAndAdd $type$ value");
1221         }
1222 
1223         {
1224             vh.set($value1$);
1225 
1226             $type$ o = ($type$) vh.getAndAddAcquire($value2$);
1227             assertEquals(o, $value1$, "getAndAddAcquire $type$");
1228             $type$ x = ($type$) vh.get();
1229             assertEquals(x, ($type$)($value1$ + $value2$), "getAndAddAcquire $type$ value");
1230         }
1231 
1232         {
1233             vh.set($value1$);
1234 
1235             $type$ o = ($type$) vh.getAndAddRelease($value2$);
1236             assertEquals(o, $value1$, "getAndAddRelease$type$");
1237             $type$ x = ($type$) vh.get();
1238             assertEquals(x, ($type$)($value1$ + $value2$), "getAndAddRelease $type$ value");
1239         }
1240 #end[AtomicAdd]
1241 
1242 #if[Bitwise]
1243         // get and bitwise or
1244         {
1245             vh.set($value1$);
1246 
1247             $type$ o = ($type$) vh.getAndBitwiseOr($value2$);
1248             assertEquals(o, $value1$, "getAndBitwiseOr $type$");
1249             $type$ x = ($type$) vh.get();
1250             assertEquals(x, ($type$)($value1$ | $value2$), "getAndBitwiseOr $type$ value");
1251         }
1252 
1253         {
1254             vh.set($value1$);
1255 
1256             $type$ o = ($type$) vh.getAndBitwiseOrAcquire($value2$);
1257             assertEquals(o, $value1$, "getAndBitwiseOrAcquire $type$");
1258             $type$ x = ($type$) vh.get();
1259             assertEquals(x, ($type$)($value1$ | $value2$), "getAndBitwiseOrAcquire $type$ value");
1260         }
1261 
1262         {
1263             vh.set($value1$);
1264 
1265             $type$ o = ($type$) vh.getAndBitwiseOrRelease($value2$);
1266             assertEquals(o, $value1$, "getAndBitwiseOrRelease $type$");
1267             $type$ x = ($type$) vh.get();
1268             assertEquals(x, ($type$)($value1$ | $value2$), "getAndBitwiseOrRelease $type$ value");
1269         }
1270 
1271         // get and bitwise and
1272         {
1273             vh.set($value1$);
1274 
1275             $type$ o = ($type$) vh.getAndBitwiseAnd($value2$);
1276             assertEquals(o, $value1$, "getAndBitwiseAnd $type$");
1277             $type$ x = ($type$) vh.get();
1278             assertEquals(x, ($type$)($value1$ & $value2$), "getAndBitwiseAnd $type$ value");
1279         }
1280 
1281         {
1282             vh.set($value1$);
1283 
1284             $type$ o = ($type$) vh.getAndBitwiseAndAcquire($value2$);
1285             assertEquals(o, $value1$, "getAndBitwiseAndAcquire $type$");
1286             $type$ x = ($type$) vh.get();
1287             assertEquals(x, ($type$)($value1$ & $value2$), "getAndBitwiseAndAcquire $type$ value");
1288         }
1289 
1290         {
1291             vh.set($value1$);
1292 
1293             $type$ o = ($type$) vh.getAndBitwiseAndRelease($value2$);
1294             assertEquals(o, $value1$, "getAndBitwiseAndRelease $type$");
1295             $type$ x = ($type$) vh.get();
1296             assertEquals(x, ($type$)($value1$ & $value2$), "getAndBitwiseAndRelease $type$ value");
1297         }
1298 
1299         // get and bitwise xor
1300         {
1301             vh.set($value1$);
1302 
1303             $type$ o = ($type$) vh.getAndBitwiseXor($value2$);
1304             assertEquals(o, $value1$, "getAndBitwiseXor $type$");
1305             $type$ x = ($type$) vh.get();
1306             assertEquals(x, ($type$)($value1$ ^ $value2$), "getAndBitwiseXor $type$ value");
1307         }
1308 
1309         {
1310             vh.set($value1$);
1311 
1312             $type$ o = ($type$) vh.getAndBitwiseXorAcquire($value2$);
1313             assertEquals(o, $value1$, "getAndBitwiseXorAcquire $type$");
1314             $type$ x = ($type$) vh.get();
1315             assertEquals(x, ($type$)($value1$ ^ $value2$), "getAndBitwiseXorAcquire $type$ value");
1316         }
1317 
1318         {
1319             vh.set($value1$);
1320 
1321             $type$ o = ($type$) vh.getAndBitwiseXorRelease($value2$);
1322             assertEquals(o, $value1$, "getAndBitwiseXorRelease $type$");
1323             $type$ x = ($type$) vh.get();
1324             assertEquals(x, ($type$)($value1$ ^ $value2$), "getAndBitwiseXorRelease $type$ value");
1325         }
1326 #end[Bitwise]
1327     }
1328 
1329     static void testStaticFieldUnsupported(VarHandle vh) {
1330 #if[!CAS]
1331         checkUOE(() -> {
1332             boolean r = vh.compareAndSet($value1$, $value2$);
1333         });
1334 
1335         checkUOE(() -> {
1336             $type$ r = ($type$) vh.compareAndExchange($value1$, $value2$);
1337         });
1338 
1339         checkUOE(() -> {
1340             $type$ r = ($type$) vh.compareAndExchangeAcquire($value1$, $value2$);
1341         });
1342 
1343         checkUOE(() -> {
1344             $type$ r = ($type$) vh.compareAndExchangeRelease($value1$, $value2$);
1345         });
1346 
1347         checkUOE(() -> {
1348             boolean r = vh.weakCompareAndSetPlain($value1$, $value2$);
1349         });
1350 
1351         checkUOE(() -> {
1352             boolean r = vh.weakCompareAndSet($value1$, $value2$);
1353         });
1354 
1355         checkUOE(() -> {
1356             boolean r = vh.weakCompareAndSetAcquire($value1$, $value2$);
1357         });
1358 
1359         checkUOE(() -> {
1360             boolean r = vh.weakCompareAndSetRelease($value1$, $value2$);
1361         });
1362 
1363         checkUOE(() -> {
1364             $type$ r = ($type$) vh.getAndSet($value1$);
1365         });
1366 
1367         checkUOE(() -> {
1368             $type$ r = ($type$) vh.getAndSetAcquire($value1$);
1369         });
1370 
1371         checkUOE(() -> {
1372             $type$ r = ($type$) vh.getAndSetRelease($value1$);
1373         });
1374 #end[CAS]
1375 
1376 #if[!AtomicAdd]
1377         checkUOE(() -> {
1378             $type$ o = ($type$) vh.getAndAdd($value1$);
1379         });
1380 
1381         checkUOE(() -> {
1382             $type$ o = ($type$) vh.getAndAddAcquire($value1$);
1383         });
1384 
1385         checkUOE(() -> {
1386             $type$ o = ($type$) vh.getAndAddRelease($value1$);
1387         });
1388 #end[AtomicAdd]
1389 
1390 #if[!Bitwise]
1391         checkUOE(() -> {
1392             $type$ o = ($type$) vh.getAndBitwiseOr($value1$);
1393         });
1394 
1395         checkUOE(() -> {
1396             $type$ o = ($type$) vh.getAndBitwiseOrAcquire($value1$);
1397         });
1398 
1399         checkUOE(() -> {
1400             $type$ o = ($type$) vh.getAndBitwiseOrRelease($value1$);
1401         });
1402 
1403         checkUOE(() -> {
1404             $type$ o = ($type$) vh.getAndBitwiseAnd($value1$);
1405         });
1406 
1407         checkUOE(() -> {
1408             $type$ o = ($type$) vh.getAndBitwiseAndAcquire($value1$);
1409         });
1410 
1411         checkUOE(() -> {
1412             $type$ o = ($type$) vh.getAndBitwiseAndRelease($value1$);
1413         });
1414 
1415         checkUOE(() -> {
1416             $type$ o = ($type$) vh.getAndBitwiseXor($value1$);
1417         });
1418 
1419         checkUOE(() -> {
1420             $type$ o = ($type$) vh.getAndBitwiseXorAcquire($value1$);
1421         });
1422 
1423         checkUOE(() -> {
1424             $type$ o = ($type$) vh.getAndBitwiseXorRelease($value1$);
1425         });
1426 #end[Bitwise]
1427     }
1428 
1429 
1430     static void testArray(VarHandle vh) {
1431         $type$[] array = new $type$[10];
1432 
1433         for (int i = 0; i < array.length; i++) {
1434             // Plain
1435             {
1436                 vh.set(array, i, $value1$);
1437                 $type$ x = ($type$) vh.get(array, i);
1438                 assertEquals(x, $value1$, "get $type$ value");
1439             }
1440 
1441 
1442             // Volatile
1443             {
1444                 vh.setVolatile(array, i, $value2$);
1445                 $type$ x = ($type$) vh.getVolatile(array, i);
1446                 assertEquals(x, $value2$, "setVolatile $type$ value");
1447             }
1448 
1449             // Lazy
1450             {
1451                 vh.setRelease(array, i, $value1$);
1452                 $type$ x = ($type$) vh.getAcquire(array, i);
1453                 assertEquals(x, $value1$, "setRelease $type$ value");
1454             }
1455 
1456             // Opaque
1457             {
1458                 vh.setOpaque(array, i, $value2$);
1459                 $type$ x = ($type$) vh.getOpaque(array, i);
1460                 assertEquals(x, $value2$, "setOpaque $type$ value");
1461             }
1462 
1463 #if[CAS]
1464             vh.set(array, i, $value1$);
1465 
1466             // Compare
1467             {
1468                 boolean r = vh.compareAndSet(array, i, $value1$, $value2$);
1469                 assertEquals(r, true, "success compareAndSet $type$");
1470                 $type$ x = ($type$) vh.get(array, i);
1471                 assertEquals(x, $value2$, "success compareAndSet $type$ value");
1472             }
1473 
1474             {
1475                 boolean r = vh.compareAndSet(array, i, $value1$, $value3$);
1476                 assertEquals(r, false, "failing compareAndSet $type$");
1477                 $type$ x = ($type$) vh.get(array, i);
1478                 assertEquals(x, $value2$, "failing compareAndSet $type$ value");
1479             }
1480 
1481             {
1482                 $type$ r = ($type$) vh.compareAndExchange(array, i, $value2$, $value1$);
1483                 assertEquals(r, $value2$, "success compareAndExchange $type$");
1484                 $type$ x = ($type$) vh.get(array, i);
1485                 assertEquals(x, $value1$, "success compareAndExchange $type$ value");
1486             }
1487 
1488             {
1489                 $type$ r = ($type$) vh.compareAndExchange(array, i, $value2$, $value3$);
1490                 assertEquals(r, $value1$, "failing compareAndExchange $type$");
1491                 $type$ x = ($type$) vh.get(array, i);
1492                 assertEquals(x, $value1$, "failing compareAndExchange $type$ value");
1493             }
1494 
1495             {
1496                 $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, $value1$, $value2$);
1497                 assertEquals(r, $value1$, "success compareAndExchangeAcquire $type$");
1498                 $type$ x = ($type$) vh.get(array, i);
1499                 assertEquals(x, $value2$, "success compareAndExchangeAcquire $type$ value");
1500             }
1501 
1502             {
1503                 $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, $value1$, $value3$);
1504                 assertEquals(r, $value2$, "failing compareAndExchangeAcquire $type$");
1505                 $type$ x = ($type$) vh.get(array, i);
1506                 assertEquals(x, $value2$, "failing compareAndExchangeAcquire $type$ value");
1507             }
1508 
1509             {
1510                 $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, $value2$, $value1$);
1511                 assertEquals(r, $value2$, "success compareAndExchangeRelease $type$");
1512                 $type$ x = ($type$) vh.get(array, i);
1513                 assertEquals(x, $value1$, "success compareAndExchangeRelease $type$ value");
1514             }
1515 
1516             {
1517                 $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, $value2$, $value3$);
1518                 assertEquals(r, $value1$, "failing compareAndExchangeRelease $type$");
1519                 $type$ x = ($type$) vh.get(array, i);
1520                 assertEquals(x, $value1$, "failing compareAndExchangeRelease $type$ value");
1521             }
1522 
1523             {
1524                 boolean success = false;
1525                 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
1526                     success = vh.weakCompareAndSetPlain(array, i, $value1$, $value2$);
1527                 }
1528                 assertEquals(success, true, "weakCompareAndSetPlain $type$");
1529                 $type$ x = ($type$) vh.get(array, i);
1530                 assertEquals(x, $value2$, "weakCompareAndSetPlain $type$ value");
1531             }
1532 
1533             {
1534                 boolean success = false;
1535                 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
1536                     success = vh.weakCompareAndSetAcquire(array, i, $value2$, $value1$);
1537                 }
1538                 assertEquals(success, true, "weakCompareAndSetAcquire $type$");
1539                 $type$ x = ($type$) vh.get(array, i);
1540                 assertEquals(x, $value1$, "weakCompareAndSetAcquire $type$");
1541             }
1542 
1543             {
1544                 boolean success = false;
1545                 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
1546                     success = vh.weakCompareAndSetRelease(array, i, $value1$, $value2$);
1547                 }
1548                 assertEquals(success, true, "weakCompareAndSetRelease $type$");
1549                 $type$ x = ($type$) vh.get(array, i);
1550                 assertEquals(x, $value2$, "weakCompareAndSetRelease $type$");
1551             }
1552 
1553             {
1554                 boolean success = false;
1555                 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
1556                     success = vh.weakCompareAndSet(array, i, $value2$, $value1$);
1557                 }
1558                 assertEquals(success, true, "weakCompareAndSet $type$");
1559                 $type$ x = ($type$) vh.get(array, i);
1560                 assertEquals(x, $value1$, "weakCompareAndSet $type$");
1561             }
1562 
1563             // Compare set and get
1564             {
1565                 vh.set(array, i, $value1$);
1566 
1567                 $type$ o = ($type$) vh.getAndSet(array, i, $value2$);
1568                 assertEquals(o, $value1$, "getAndSet $type$");
1569                 $type$ x = ($type$) vh.get(array, i);
1570                 assertEquals(x, $value2$, "getAndSet $type$ value");
1571             }
1572 
1573             {
1574                 vh.set(array, i, $value1$);
1575 
1576                 $type$ o = ($type$) vh.getAndSetAcquire(array, i, $value2$);
1577                 assertEquals(o, $value1$, "getAndSetAcquire $type$");
1578                 $type$ x = ($type$) vh.get(array, i);
1579                 assertEquals(x, $value2$, "getAndSetAcquire $type$ value");
1580             }
1581 
1582             {
1583                 vh.set(array, i, $value1$);
1584 
1585                 $type$ o = ($type$) vh.getAndSetRelease(array, i, $value2$);
1586                 assertEquals(o, $value1$, "getAndSetRelease $type$");
1587                 $type$ x = ($type$) vh.get(array, i);
1588                 assertEquals(x, $value2$, "getAndSetRelease $type$ value");
1589             }
1590 #end[CAS]
1591 
1592 #if[AtomicAdd]
1593             // get and add, add and get
1594             {
1595                 vh.set(array, i, $value1$);
1596 
1597                 $type$ o = ($type$) vh.getAndAdd(array, i, $value2$);
1598                 assertEquals(o, $value1$, "getAndAdd $type$");
1599                 $type$ x = ($type$) vh.get(array, i);
1600                 assertEquals(x, ($type$)($value1$ + $value2$), "getAndAdd $type$ value");
1601             }
1602 
1603             {
1604                 vh.set(array, i, $value1$);
1605 
1606                 $type$ o = ($type$) vh.getAndAddAcquire(array, i, $value2$);
1607                 assertEquals(o, $value1$, "getAndAddAcquire $type$");
1608                 $type$ x = ($type$) vh.get(array, i);
1609                 assertEquals(x, ($type$)($value1$ + $value2$), "getAndAddAcquire $type$ value");
1610             }
1611 
1612             {
1613                 vh.set(array, i, $value1$);
1614 
1615                 $type$ o = ($type$) vh.getAndAddRelease(array, i, $value2$);
1616                 assertEquals(o, $value1$, "getAndAddRelease$type$");
1617                 $type$ x = ($type$) vh.get(array, i);
1618                 assertEquals(x, ($type$)($value1$ + $value2$), "getAndAddRelease $type$ value");
1619             }
1620 #end[AtomicAdd]
1621 
1622 #if[Bitwise]
1623             // get and bitwise or
1624             {
1625                 vh.set(array, i, $value1$);
1626 
1627                 $type$ o = ($type$) vh.getAndBitwiseOr(array, i, $value2$);
1628                 assertEquals(o, $value1$, "getAndBitwiseOr $type$");
1629                 $type$ x = ($type$) vh.get(array, i);
1630                 assertEquals(x, ($type$)($value1$ | $value2$), "getAndBitwiseOr $type$ value");
1631             }
1632 
1633             {
1634                 vh.set(array, i, $value1$);
1635 
1636                 $type$ o = ($type$) vh.getAndBitwiseOrAcquire(array, i, $value2$);
1637                 assertEquals(o, $value1$, "getAndBitwiseOrAcquire $type$");
1638                 $type$ x = ($type$) vh.get(array, i);
1639                 assertEquals(x, ($type$)($value1$ | $value2$), "getAndBitwiseOrAcquire $type$ value");
1640             }
1641 
1642             {
1643                 vh.set(array, i, $value1$);
1644 
1645                 $type$ o = ($type$) vh.getAndBitwiseOrRelease(array, i, $value2$);
1646                 assertEquals(o, $value1$, "getAndBitwiseOrRelease $type$");
1647                 $type$ x = ($type$) vh.get(array, i);
1648                 assertEquals(x, ($type$)($value1$ | $value2$), "getAndBitwiseOrRelease $type$ value");
1649             }
1650 
1651             // get and bitwise and
1652             {
1653                 vh.set(array, i, $value1$);
1654 
1655                 $type$ o = ($type$) vh.getAndBitwiseAnd(array, i, $value2$);
1656                 assertEquals(o, $value1$, "getAndBitwiseAnd $type$");
1657                 $type$ x = ($type$) vh.get(array, i);
1658                 assertEquals(x, ($type$)($value1$ & $value2$), "getAndBitwiseAnd $type$ value");
1659             }
1660 
1661             {
1662                 vh.set(array, i, $value1$);
1663 
1664                 $type$ o = ($type$) vh.getAndBitwiseAndAcquire(array, i, $value2$);
1665                 assertEquals(o, $value1$, "getAndBitwiseAndAcquire $type$");
1666                 $type$ x = ($type$) vh.get(array, i);
1667                 assertEquals(x, ($type$)($value1$ & $value2$), "getAndBitwiseAndAcquire $type$ value");
1668             }
1669 
1670             {
1671                 vh.set(array, i, $value1$);
1672 
1673                 $type$ o = ($type$) vh.getAndBitwiseAndRelease(array, i, $value2$);
1674                 assertEquals(o, $value1$, "getAndBitwiseAndRelease $type$");
1675                 $type$ x = ($type$) vh.get(array, i);
1676                 assertEquals(x, ($type$)($value1$ & $value2$), "getAndBitwiseAndRelease $type$ value");
1677             }
1678 
1679             // get and bitwise xor
1680             {
1681                 vh.set(array, i, $value1$);
1682 
1683                 $type$ o = ($type$) vh.getAndBitwiseXor(array, i, $value2$);
1684                 assertEquals(o, $value1$, "getAndBitwiseXor $type$");
1685                 $type$ x = ($type$) vh.get(array, i);
1686                 assertEquals(x, ($type$)($value1$ ^ $value2$), "getAndBitwiseXor $type$ value");
1687             }
1688 
1689             {
1690                 vh.set(array, i, $value1$);
1691 
1692                 $type$ o = ($type$) vh.getAndBitwiseXorAcquire(array, i, $value2$);
1693                 assertEquals(o, $value1$, "getAndBitwiseXorAcquire $type$");
1694                 $type$ x = ($type$) vh.get(array, i);
1695                 assertEquals(x, ($type$)($value1$ ^ $value2$), "getAndBitwiseXorAcquire $type$ value");
1696             }
1697 
1698             {
1699                 vh.set(array, i, $value1$);
1700 
1701                 $type$ o = ($type$) vh.getAndBitwiseXorRelease(array, i, $value2$);
1702                 assertEquals(o, $value1$, "getAndBitwiseXorRelease $type$");
1703                 $type$ x = ($type$) vh.get(array, i);
1704                 assertEquals(x, ($type$)($value1$ ^ $value2$), "getAndBitwiseXorRelease $type$ value");
1705             }
1706 #end[Bitwise]
1707         }
1708     }
1709 
1710     static void testArrayUnsupported(VarHandle vh) {
1711         $type$[] array = new $type$[10];
1712 
1713         int i = 0;
1714 #if[!CAS]
1715         checkUOE(() -> {
1716             boolean r = vh.compareAndSet(array, i, $value1$, $value2$);
1717         });
1718 
1719         checkUOE(() -> {
1720             $type$ r = ($type$) vh.compareAndExchange(array, i, $value1$, $value2$);
1721         });
1722 
1723         checkUOE(() -> {
1724             $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, $value1$, $value2$);
1725         });
1726 
1727         checkUOE(() -> {
1728             $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, $value1$, $value2$);
1729         });
1730 
1731         checkUOE(() -> {
1732             boolean r = vh.weakCompareAndSetPlain(array, i, $value1$, $value2$);
1733         });
1734 
1735         checkUOE(() -> {
1736             boolean r = vh.weakCompareAndSet(array, i, $value1$, $value2$);
1737         });
1738 
1739         checkUOE(() -> {
1740             boolean r = vh.weakCompareAndSetAcquire(array, i, $value1$, $value2$);
1741         });
1742 
1743         checkUOE(() -> {
1744             boolean r = vh.weakCompareAndSetRelease(array, i, $value1$, $value2$);
1745         });
1746 
1747         checkUOE(() -> {
1748             $type$ r = ($type$) vh.getAndSet(array, i, $value1$);
1749         });
1750 
1751         checkUOE(() -> {
1752             $type$ r = ($type$) vh.getAndSetAcquire(array, i, $value1$);
1753         });
1754 
1755         checkUOE(() -> {
1756             $type$ r = ($type$) vh.getAndSetRelease(array, i, $value1$);
1757         });
1758 #end[CAS]
1759 
1760 #if[!AtomicAdd]
1761         checkUOE(() -> {
1762             $type$ o = ($type$) vh.getAndAdd(array, i, $value1$);
1763         });
1764 
1765         checkUOE(() -> {
1766             $type$ o = ($type$) vh.getAndAddAcquire(array, i, $value1$);
1767         });
1768 
1769         checkUOE(() -> {
1770             $type$ o = ($type$) vh.getAndAddRelease(array, i, $value1$);
1771         });
1772 #end[AtomicAdd]
1773 
1774 #if[!Bitwise]
1775         checkUOE(() -> {
1776             $type$ o = ($type$) vh.getAndBitwiseOr(array, i, $value1$);
1777         });
1778 
1779         checkUOE(() -> {
1780             $type$ o = ($type$) vh.getAndBitwiseOrAcquire(array, i, $value1$);
1781         });
1782 
1783         checkUOE(() -> {
1784             $type$ o = ($type$) vh.getAndBitwiseOrRelease(array, i, $value1$);
1785         });
1786 
1787         checkUOE(() -> {
1788             $type$ o = ($type$) vh.getAndBitwiseAnd(array, i, $value1$);
1789         });
1790 
1791         checkUOE(() -> {
1792             $type$ o = ($type$) vh.getAndBitwiseAndAcquire(array, i, $value1$);
1793         });
1794 
1795         checkUOE(() -> {
1796             $type$ o = ($type$) vh.getAndBitwiseAndRelease(array, i, $value1$);
1797         });
1798 
1799         checkUOE(() -> {
1800             $type$ o = ($type$) vh.getAndBitwiseXor(array, i, $value1$);
1801         });
1802 
1803         checkUOE(() -> {
1804             $type$ o = ($type$) vh.getAndBitwiseXorAcquire(array, i, $value1$);
1805         });
1806 
1807         checkUOE(() -> {
1808             $type$ o = ($type$) vh.getAndBitwiseXorRelease(array, i, $value1$);
1809         });
1810 #end[Bitwise]
1811     }
1812 
1813     static void testArrayIndexOutOfBounds(VarHandle vh) throws Throwable {
1814         $type$[] array = new $type$[10];
1815 
1816         for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
1817             final int ci = i;
1818 
1819             checkIOOBE(() -> {
1820                 $type$ x = ($type$) vh.get(array, ci);
1821             });
1822 
1823             checkIOOBE(() -> {
1824                 vh.set(array, ci, $value1$);
1825             });
1826 
1827             checkIOOBE(() -> {
1828                 $type$ x = ($type$) vh.getVolatile(array, ci);
1829             });
1830 
1831             checkIOOBE(() -> {
1832                 vh.setVolatile(array, ci, $value1$);
1833             });
1834 
1835             checkIOOBE(() -> {
1836                 $type$ x = ($type$) vh.getAcquire(array, ci);
1837             });
1838 
1839             checkIOOBE(() -> {
1840                 vh.setRelease(array, ci, $value1$);
1841             });
1842 
1843             checkIOOBE(() -> {
1844                 $type$ x = ($type$) vh.getOpaque(array, ci);
1845             });
1846 
1847             checkIOOBE(() -> {
1848                 vh.setOpaque(array, ci, $value1$);
1849             });
1850 
1851 #if[CAS]
1852             checkIOOBE(() -> {
1853                 boolean r = vh.compareAndSet(array, ci, $value1$, $value2$);
1854             });
1855 
1856             checkIOOBE(() -> {
1857                 $type$ r = ($type$) vh.compareAndExchange(array, ci, $value2$, $value1$);
1858             });
1859 
1860             checkIOOBE(() -> {
1861                 $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, $value2$, $value1$);
1862             });
1863 
1864             checkIOOBE(() -> {
1865                 $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, $value2$, $value1$);
1866             });
1867 
1868             checkIOOBE(() -> {
1869                 boolean r = vh.weakCompareAndSetPlain(array, ci, $value1$, $value2$);
1870             });
1871 
1872             checkIOOBE(() -> {
1873                 boolean r = vh.weakCompareAndSet(array, ci, $value1$, $value2$);
1874             });
1875 
1876             checkIOOBE(() -> {
1877                 boolean r = vh.weakCompareAndSetAcquire(array, ci, $value1$, $value2$);
1878             });
1879 
1880             checkIOOBE(() -> {
1881                 boolean r = vh.weakCompareAndSetRelease(array, ci, $value1$, $value2$);
1882             });
1883 
1884             checkIOOBE(() -> {
1885                 $type$ o = ($type$) vh.getAndSet(array, ci, $value1$);
1886             });
1887 
1888             checkIOOBE(() -> {
1889                 $type$ o = ($type$) vh.getAndSetAcquire(array, ci, $value1$);
1890             });
1891 
1892             checkIOOBE(() -> {
1893                 $type$ o = ($type$) vh.getAndSetRelease(array, ci, $value1$);
1894             });
1895 #end[CAS]
1896 
1897 #if[AtomicAdd]
1898             checkIOOBE(() -> {
1899                 $type$ o = ($type$) vh.getAndAdd(array, ci, $value1$);
1900             });
1901 
1902             checkIOOBE(() -> {
1903                 $type$ o = ($type$) vh.getAndAddAcquire(array, ci, $value1$);
1904             });
1905 
1906             checkIOOBE(() -> {
1907                 $type$ o = ($type$) vh.getAndAddRelease(array, ci, $value1$);
1908             });
1909 #end[AtomicAdd]
1910 
1911 #if[Bitwise]
1912             checkIOOBE(() -> {
1913                 $type$ o = ($type$) vh.getAndBitwiseOr(array, ci, $value1$);
1914             });
1915 
1916             checkIOOBE(() -> {
1917                 $type$ o = ($type$) vh.getAndBitwiseOrAcquire(array, ci, $value1$);
1918             });
1919 
1920             checkIOOBE(() -> {
1921                 $type$ o = ($type$) vh.getAndBitwiseOrRelease(array, ci, $value1$);
1922             });
1923 
1924             checkIOOBE(() -> {
1925                 $type$ o = ($type$) vh.getAndBitwiseAnd(array, ci, $value1$);
1926             });
1927 
1928             checkIOOBE(() -> {
1929                 $type$ o = ($type$) vh.getAndBitwiseAndAcquire(array, ci, $value1$);
1930             });
1931 
1932             checkIOOBE(() -> {
1933                 $type$ o = ($type$) vh.getAndBitwiseAndRelease(array, ci, $value1$);
1934             });
1935 
1936             checkIOOBE(() -> {
1937                 $type$ o = ($type$) vh.getAndBitwiseXor(array, ci, $value1$);
1938             });
1939 
1940             checkIOOBE(() -> {
1941                 $type$ o = ($type$) vh.getAndBitwiseXorAcquire(array, ci, $value1$);
1942             });
1943 
1944             checkIOOBE(() -> {
1945                 $type$ o = ($type$) vh.getAndBitwiseXorRelease(array, ci, $value1$);
1946             });
1947 #end[Bitwise]
1948         }
1949     }
1950 
1951 #if[Class]]
1952     static void testArrayStoreException(VarHandle vh) throws Throwable {
1953         Object[] array = new $type$[10];
1954         Arrays.fill(array, $value1$);
1955         Object value = new Object();
1956 
1957         // Set
1958         checkASE(() -> {
1959             vh.set(array, 0, value);
1960         });
1961 
1962         // SetVolatile
1963         checkASE(() -> {
1964             vh.setVolatile(array, 0, value);
1965         });
1966 
1967         // SetOpaque
1968         checkASE(() -> {
1969             vh.setOpaque(array, 0, value);
1970         });
1971 
1972         // SetRelease
1973         checkASE(() -> {
1974             vh.setRelease(array, 0, value);
1975         });
1976 
1977         // CompareAndSet
1978         checkASE(() -> { // receiver reference class
1979             boolean r = vh.compareAndSet(array, 0, $value1$, value);
1980         });
1981 
1982         // WeakCompareAndSet
1983         checkASE(() -> { // receiver reference class
1984             boolean r = vh.weakCompareAndSetPlain(array, 0, $value1$, value);
1985         });
1986 
1987         // WeakCompareAndSetVolatile
1988         checkASE(() -> { // receiver reference class
1989             boolean r = vh.weakCompareAndSet(array, 0, $value1$, value);
1990         });
1991 
1992         // WeakCompareAndSetAcquire
1993         checkASE(() -> { // receiver reference class
1994             boolean r = vh.weakCompareAndSetAcquire(array, 0, $value1$, value);
1995         });
1996 
1997         // WeakCompareAndSetRelease
1998         checkASE(() -> { // receiver reference class
1999             boolean r = vh.weakCompareAndSetRelease(array, 0, $value1$, value);
2000         });
2001 
2002         // CompareAndExchange
2003         checkASE(() -> { // receiver reference class
2004             $type$ x = ($type$) vh.compareAndExchange(array, 0, $value1$, value);
2005         });
2006 
2007         // CompareAndExchangeAcquire
2008         checkASE(() -> { // receiver reference class
2009             $type$ x = ($type$) vh.compareAndExchangeAcquire(array, 0, $value1$, value);
2010         });
2011 
2012         // CompareAndExchangeRelease
2013         checkASE(() -> { // receiver reference class
2014             $type$ x = ($type$) vh.compareAndExchangeRelease(array, 0, $value1$, value);
2015         });
2016 
2017         // GetAndSet
2018         checkASE(() -> { // receiver reference class
2019             $type$ x = ($type$) vh.getAndSet(array, 0, value);
2020         });
2021 
2022         // GetAndSetAcquire
2023         checkASE(() -> { // receiver reference class
2024             $type$ x = ($type$) vh.getAndSetAcquire(array, 0, value);
2025         });
2026 
2027         // GetAndSetRelease
2028         checkASE(() -> { // receiver reference class
2029             $type$ x = ($type$) vh.getAndSetRelease(array, 0, value);
2030         });
2031     }
2032 #end[Class]]
2033 }
2034