1 /*
   2  * Copyright (c) 2015, 2025, 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 /*
  25  * @test
  26  * @comment Set CompileThresholdScaling to 0.1 so that the warmup loop sets to 2000 iterations
  27  *          to hit compilation thresholds
  28  * @run junit/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestMethodHandleAccess$Type$
  29  */
  30 
  31 import java.lang.invoke.MethodHandle;
  32 import java.lang.invoke.MethodHandles;
  33 import java.lang.invoke.VarHandle;
  34 import java.util.ArrayList;
  35 import java.util.List;
  36 
  37 import static org.junit.jupiter.api.Assertions.*;
  38 import org.junit.jupiter.api.BeforeAll;
  39 import org.junit.jupiter.api.TestInstance;
  40 import org.junit.jupiter.params.ParameterizedTest;
  41 import org.junit.jupiter.params.provider.MethodSource;
  42 
  43 @TestInstance(TestInstance.Lifecycle.PER_CLASS)
  44 public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest {
  45     static final $type$ static_final_v = $value1$;
  46 
  47     static $type$ static_v;
  48 
  49     final $type$ final_v = $value1$;
  50 
  51     $type$ v;
  52 
  53     VarHandle vhFinalField;
  54 
  55     VarHandle vhField;
  56 
  57     VarHandle vhStaticField;
  58 
  59     VarHandle vhStaticFinalField;
  60 
  61     VarHandle vhArray;
  62 
  63     @BeforeAll
  64     public void setup() throws Exception {
  65         vhFinalField = MethodHandles.lookup().findVarHandle(
  66                 VarHandleTestMethodHandleAccess$Type$.class, "final_v", $type$.class);
  67 
  68         vhField = MethodHandles.lookup().findVarHandle(
  69                 VarHandleTestMethodHandleAccess$Type$.class, "v", $type$.class);
  70 
  71         vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
  72             VarHandleTestMethodHandleAccess$Type$.class, "static_final_v", $type$.class);
  73 
  74         vhStaticField = MethodHandles.lookup().findStaticVarHandle(
  75             VarHandleTestMethodHandleAccess$Type$.class, "static_v", $type$.class);
  76 
  77         vhArray = MethodHandles.arrayElementVarHandle($type$[].class);
  78     }
  79 
  80     public Object[][] accessTestCaseProvider() throws Exception {
  81         List<AccessTestCase<?>> cases = new ArrayList<>();
  82 
  83         for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
  84             cases.add(new MethodHandleAccessTestCase("Instance field",
  85                                                      vhField, f, hs -> testInstanceField(this, hs)));
  86             cases.add(new MethodHandleAccessTestCase("Instance field unsupported",
  87                                                      vhField, f, hs -> testInstanceFieldUnsupported(this, hs),
  88                                                      false));
  89 
  90             cases.add(new MethodHandleAccessTestCase("Static field",
  91                                                      vhStaticField, f, VarHandleTestMethodHandleAccess$Type$::testStaticField));
  92             cases.add(new MethodHandleAccessTestCase("Static field unsupported",
  93                                                      vhStaticField, f, VarHandleTestMethodHandleAccess$Type$::testStaticFieldUnsupported,
  94                                                      false));
  95 
  96             cases.add(new MethodHandleAccessTestCase("Array",
  97                                                      vhArray, f, VarHandleTestMethodHandleAccess$Type$::testArray));
  98             cases.add(new MethodHandleAccessTestCase("Array unsupported",
  99                                                      vhArray, f, VarHandleTestMethodHandleAccess$Type$::testArrayUnsupported,
 100                                                      false));
 101             cases.add(new MethodHandleAccessTestCase("Array index out of bounds",
 102                                                      vhArray, f, VarHandleTestMethodHandleAccess$Type$::testArrayIndexOutOfBounds,
 103                                                      false));
 104         }
 105 
 106         // Work around issue with jtreg summary reporting which truncates
 107         // the String result of Object.toString to 30 characters, hence
 108         // the first dummy argument
 109         return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
 110     }
 111 
 112     @ParameterizedTest
 113     @MethodSource("accessTestCaseProvider")
 114     public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
 115         T t = atc.get();
 116         int iters = atc.requiresLoop() ? ITERS : 1;
 117         for (int c = 0; c < iters; c++) {
 118             atc.testAccess(t);
 119         }
 120     }
 121 
 122     static void testInstanceField(VarHandleTestMethodHandleAccess$Type$ recv, Handles hs) throws Throwable {
 123         // Plain
 124         {
 125             hs.get(TestAccessMode.SET).invokeExact(recv, $value1$);
 126             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
 127             assertEquals($value1$, x, "set $type$ value");
 128         }
 129 
 130 
 131         // Volatile
 132         {
 133             hs.get(TestAccessMode.SET_VOLATILE).invokeExact(recv, $value2$);
 134             $type$ x = ($type$) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(recv);
 135             assertEquals($value2$, x, "setVolatile $type$ value");
 136         }
 137 
 138         // Lazy
 139         {
 140             hs.get(TestAccessMode.SET_RELEASE).invokeExact(recv, $value1$);
 141             $type$ x = ($type$) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(recv);
 142             assertEquals($value1$, x, "setRelease $type$ value");
 143         }
 144 
 145         // Opaque
 146         {
 147             hs.get(TestAccessMode.SET_OPAQUE).invokeExact(recv, $value2$);
 148             $type$ x = ($type$) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(recv);
 149             assertEquals($value2$, x, "setOpaque $type$ value");
 150         }
 151 
 152 #if[CAS]
 153         hs.get(TestAccessMode.SET).invokeExact(recv, $value1$);
 154 
 155         // Compare
 156         {
 157             boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(recv, $value1$, $value2$);
 158             assertEquals(r, true, "success compareAndSet $type$");
 159             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
 160             assertEquals($value2$, x, "success compareAndSet $type$ value");
 161         }
 162 
 163         {
 164             boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(recv, $value1$, $value3$);
 165             assertEquals(r, false, "failing compareAndSet $type$");
 166             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
 167             assertEquals($value2$, x, "failing compareAndSet $type$ value");
 168         }
 169 
 170         {
 171             $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(recv, $value2$, $value1$);
 172             assertEquals(r, $value2$, "success compareAndExchange $type$");
 173             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
 174             assertEquals($value1$, x, "success compareAndExchange $type$ value");
 175         }
 176 
 177         {
 178             $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(recv, $value2$, $value3$);
 179             assertEquals(r, $value1$, "failing compareAndExchange $type$");
 180             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
 181             assertEquals($value1$, x, "failing compareAndExchange $type$ value");
 182         }
 183 
 184         {
 185             $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(recv, $value1$, $value2$);
 186             assertEquals(r, $value1$, "success compareAndExchangeAcquire $type$");
 187             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
 188             assertEquals($value2$, x, "success compareAndExchangeAcquire $type$ value");
 189         }
 190 
 191         {
 192             $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(recv, $value1$, $value3$);
 193             assertEquals(r, $value2$, "failing compareAndExchangeAcquire $type$");
 194             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
 195             assertEquals($value2$, x, "failing compareAndExchangeAcquire $type$ value");
 196         }
 197 
 198         {
 199             $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(recv, $value2$, $value1$);
 200             assertEquals(r, $value2$, "success compareAndExchangeRelease $type$");
 201             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
 202             assertEquals($value1$, x, "success compareAndExchangeRelease $type$ value");
 203         }
 204 
 205         {
 206             $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(recv, $value2$, $value3$);
 207             assertEquals(r, $value1$, "failing compareAndExchangeRelease $type$");
 208             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
 209             assertEquals($value1$, x, "failing compareAndExchangeRelease $type$ value");
 210         }
 211 
 212         {
 213             MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN);
 214             boolean success = false;
 215             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 216                 success = (boolean) mh.invokeExact(recv, $value1$, $value2$);
 217                 if (!success) weakDelay();
 218             }
 219             assertEquals(success, true, "success weakCompareAndSetPlain $type$");
 220             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
 221             assertEquals($value2$, x, "success weakCompareAndSetPlain $type$ value");
 222         }
 223 
 224         {
 225             boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, $value1$, $value3$);
 226             assertEquals(success, false, "failing weakCompareAndSetPlain $type$");
 227             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
 228             assertEquals($value2$, x, "failing weakCompareAndSetPlain $type$ value");
 229         }
 230 
 231         {
 232             MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE);
 233             boolean success = false;
 234             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 235                 success = (boolean) mh.invokeExact(recv, $value2$, $value1$);
 236                 if (!success) weakDelay();
 237             }
 238             assertEquals(success, true, "success weakCompareAndSetAcquire $type$");
 239             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
 240             assertEquals($value1$, x, "success weakCompareAndSetAcquire $type$");
 241         }
 242 
 243         {
 244             boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, $value2$, $value3$);
 245             assertEquals(success, false, "failing weakCompareAndSetAcquire $type$");
 246             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
 247             assertEquals($value1$, x, "failing weakCompareAndSetAcquire $type$ value");
 248         }
 249 
 250         {
 251             MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE);
 252             boolean success = false;
 253             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 254                 success = (boolean) mh.invokeExact(recv, $value1$, $value2$);
 255                 if (!success) weakDelay();
 256             }
 257             assertEquals(success, true, "success weakCompareAndSetRelease $type$");
 258             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
 259             assertEquals($value2$, x, "success weakCompareAndSetRelease $type$");
 260         }
 261 
 262         {
 263             boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, $value1$, $value3$);
 264             assertEquals(success, false, "failing weakCompareAndSetRelease $type$");
 265             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
 266             assertEquals($value2$, x, "failing weakCompareAndSetRelease $type$ value");
 267         }
 268 
 269         {
 270             boolean success = false;
 271             MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET);
 272             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 273                 success = (boolean) mh.invokeExact(recv, $value2$, $value1$);
 274                 if (!success) weakDelay();
 275             }
 276             assertEquals(success, true, "success weakCompareAndSet $type$");
 277             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
 278             assertEquals($value1$, x, "success weakCompareAndSet $type$");
 279         }
 280 
 281         {
 282             boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, $value2$, $value3$);
 283             assertEquals(success, false, "failing weakCompareAndSet $type$");
 284             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
 285             assertEquals($value1$, x, "failing weakCompareAndSet $type$ value");
 286         }
 287 
 288         // Compare set and get
 289         {
 290             $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_SET).invokeExact(recv, $value2$);
 291             assertEquals($value1$, o, "getAndSet $type$");
 292             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
 293             assertEquals($value2$, x, "getAndSet $type$ value");
 294         }
 295 #end[CAS]
 296 
 297 #if[AtomicAdd]
 298         // get and add, add and get
 299         {
 300             hs.get(TestAccessMode.SET).invokeExact(recv, $value1$);
 301 
 302             $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_ADD).invokeExact(recv, $value2$);
 303             assertEquals($value1$, o, "getAndAdd $type$");
 304             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
 305             assertEquals(($type$)($value1$ + $value2$), x, "getAndAdd $type$ value");
 306         }
 307 
 308         {
 309             hs.get(TestAccessMode.SET).invokeExact(recv, $value1$);
 310 
 311             $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_ADD_ACQUIRE).invokeExact(recv, $value2$);
 312             assertEquals($value1$, o, "getAndAddAcquire $type$");
 313             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
 314             assertEquals(($type$)($value1$ + $value2$), x, "getAndAddAcquire $type$ value");
 315         }
 316 
 317         {
 318             hs.get(TestAccessMode.SET).invokeExact(recv, $value1$);
 319 
 320             $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_ADD_RELEASE).invokeExact(recv, $value2$);
 321             assertEquals($value1$, o, "getAndAddRelease $type$");
 322             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
 323             assertEquals(($type$)($value1$ + $value2$), x, "getAndAddRelease $type$ value");
 324         }
 325 #end[AtomicAdd]
 326 
 327 #if[Bitwise]
 328         // get and bitwise or
 329         {
 330             hs.get(TestAccessMode.SET).invokeExact(recv, $value1$);
 331 
 332             $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_OR).invokeExact(recv, $value2$);
 333             assertEquals($value1$, o, "getAndBitwiseOr $type$");
 334             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
 335             assertEquals(($type$)($value1$ | $value2$), x, "getAndBitwiseOr $type$ value");
 336         }
 337 
 338         {
 339             hs.get(TestAccessMode.SET).invokeExact(recv, $value1$);
 340 
 341             $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_OR_ACQUIRE).invokeExact(recv, $value2$);
 342             assertEquals($value1$, o, "getAndBitwiseOrAcquire $type$");
 343             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
 344             assertEquals(($type$)($value1$ | $value2$), x, "getAndBitwiseOrAcquire $type$ value");
 345         }
 346 
 347         {
 348             hs.get(TestAccessMode.SET).invokeExact(recv, $value1$);
 349 
 350             $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_OR_RELEASE).invokeExact(recv, $value2$);
 351             assertEquals($value1$, o, "getAndBitwiseOrRelease $type$");
 352             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
 353             assertEquals(($type$)($value1$ | $value2$), x, "getAndBitwiseOrRelease $type$ value");
 354         }
 355 
 356         // get and bitwise and
 357         {
 358             hs.get(TestAccessMode.SET).invokeExact(recv, $value1$);
 359 
 360             $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_AND).invokeExact(recv, $value2$);
 361             assertEquals($value1$, o, "getAndBitwiseAnd $type$");
 362             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
 363             assertEquals(($type$)($value1$ & $value2$), x, "getAndBitwiseAnd $type$ value");
 364         }
 365 
 366         {
 367             hs.get(TestAccessMode.SET).invokeExact(recv, $value1$);
 368 
 369             $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_AND_ACQUIRE).invokeExact(recv, $value2$);
 370             assertEquals($value1$, o, "getAndBitwiseAndAcquire $type$");
 371             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
 372             assertEquals(($type$)($value1$ & $value2$), x, "getAndBitwiseAndAcquire $type$ value");
 373         }
 374 
 375         {
 376             hs.get(TestAccessMode.SET).invokeExact(recv, $value1$);
 377 
 378             $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_AND_RELEASE).invokeExact(recv, $value2$);
 379             assertEquals($value1$, o, "getAndBitwiseAndRelease $type$");
 380             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
 381             assertEquals(($type$)($value1$ & $value2$), x, "getAndBitwiseAndRelease $type$ value");
 382         }
 383 
 384         // get and bitwise xor
 385         {
 386             hs.get(TestAccessMode.SET).invokeExact(recv, $value1$);
 387 
 388             $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_XOR).invokeExact(recv, $value2$);
 389             assertEquals($value1$, o, "getAndBitwiseXor $type$");
 390             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
 391             assertEquals(($type$)($value1$ ^ $value2$), x, "getAndBitwiseXor $type$ value");
 392         }
 393 
 394         {
 395             hs.get(TestAccessMode.SET).invokeExact(recv, $value1$);
 396 
 397             $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_ACQUIRE).invokeExact(recv, $value2$);
 398             assertEquals($value1$, o, "getAndBitwiseXorAcquire $type$");
 399             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
 400             assertEquals(($type$)($value1$ ^ $value2$), x, "getAndBitwiseXorAcquire $type$ value");
 401         }
 402 
 403         {
 404             hs.get(TestAccessMode.SET).invokeExact(recv, $value1$);
 405 
 406             $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_RELEASE).invokeExact(recv, $value2$);
 407             assertEquals($value1$, o, "getAndBitwiseXorRelease $type$");
 408             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
 409             assertEquals(($type$)($value1$ ^ $value2$), x, "getAndBitwiseXorRelease $type$ value");
 410         }
 411 #end[Bitwise]
 412     }
 413 
 414     static void testInstanceFieldUnsupported(VarHandleTestMethodHandleAccess$Type$ recv, Handles hs) throws Throwable {
 415 #if[!CAS]
 416         for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) {
 417             checkUOE(am, () -> {
 418                 boolean r = (boolean) hs.get(am).invokeExact(recv, $value1$, $value2$);
 419             });
 420         }
 421 
 422         for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) {
 423             checkUOE(am, () -> {
 424                 $type$ r = ($type$) hs.get(am).invokeExact(recv, $value1$, $value2$);
 425             });
 426         }
 427 
 428         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) {
 429             checkUOE(am, () -> {
 430                 $type$ r = ($type$) hs.get(am).invokeExact(recv, $value1$);
 431             });
 432         }
 433 #end[CAS]
 434 
 435 #if[!AtomicAdd]
 436         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_ADD)) {
 437             checkUOE(am, () -> {
 438                 $type$ r = ($type$) hs.get(am).invokeExact(recv, $value1$);
 439             });
 440         }
 441 #end[AtomicAdd]
 442 
 443 #if[!Bitwise]
 444         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_BITWISE)) {
 445             checkUOE(am, () -> {
 446                 $type$ r = ($type$) hs.get(am).invokeExact(recv, $value1$);
 447             });
 448         }
 449 #end[Bitwise]
 450     }
 451 
 452 
 453     static void testStaticField(Handles hs) throws Throwable {
 454         // Plain
 455         {
 456             hs.get(TestAccessMode.SET).invokeExact($value1$);
 457             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 458             assertEquals($value1$, x, "set $type$ value");
 459         }
 460 
 461 
 462         // Volatile
 463         {
 464             hs.get(TestAccessMode.SET_VOLATILE).invokeExact($value2$);
 465             $type$ x = ($type$) hs.get(TestAccessMode.GET_VOLATILE).invokeExact();
 466             assertEquals($value2$, x, "setVolatile $type$ value");
 467         }
 468 
 469         // Lazy
 470         {
 471             hs.get(TestAccessMode.SET_RELEASE).invokeExact($value1$);
 472             $type$ x = ($type$) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact();
 473             assertEquals($value1$, x, "setRelease $type$ value");
 474         }
 475 
 476         // Opaque
 477         {
 478             hs.get(TestAccessMode.SET_OPAQUE).invokeExact($value2$);
 479             $type$ x = ($type$) hs.get(TestAccessMode.GET_OPAQUE).invokeExact();
 480             assertEquals($value2$, x, "setOpaque $type$ value");
 481         }
 482 
 483 #if[CAS]
 484         hs.get(TestAccessMode.SET).invokeExact($value1$);
 485 
 486         // Compare
 487         {
 488             boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact($value1$, $value2$);
 489             assertEquals(r, true, "success compareAndSet $type$");
 490             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 491             assertEquals($value2$, x, "success compareAndSet $type$ value");
 492         }
 493 
 494         {
 495             boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact($value1$, $value3$);
 496             assertEquals(r, false, "failing compareAndSet $type$");
 497             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 498             assertEquals($value2$, x, "failing compareAndSet $type$ value");
 499         }
 500 
 501         {
 502             $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact($value2$, $value1$);
 503             assertEquals(r, $value2$, "success compareAndExchange $type$");
 504             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 505             assertEquals($value1$, x, "success compareAndExchange $type$ value");
 506         }
 507 
 508         {
 509             $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact($value2$, $value3$);
 510             assertEquals(r, $value1$, "failing compareAndExchange $type$");
 511             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 512             assertEquals($value1$, x, "failing compareAndExchange $type$ value");
 513         }
 514 
 515         {
 516             $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact($value1$, $value2$);
 517             assertEquals(r, $value1$, "success compareAndExchangeAcquire $type$");
 518             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 519             assertEquals($value2$, x, "success compareAndExchangeAcquire $type$ value");
 520         }
 521 
 522         {
 523             $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact($value1$, $value3$);
 524             assertEquals(r, $value2$, "failing compareAndExchangeAcquire $type$");
 525             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 526             assertEquals($value2$, x, "failing compareAndExchangeAcquire $type$ value");
 527         }
 528 
 529         {
 530             $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact($value2$, $value1$);
 531             assertEquals(r, $value2$, "success compareAndExchangeRelease $type$");
 532             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 533             assertEquals($value1$, x, "success compareAndExchangeRelease $type$ value");
 534         }
 535 
 536         {
 537             $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact($value2$, $value3$);
 538             assertEquals(r, $value1$, "failing compareAndExchangeRelease $type$");
 539             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 540             assertEquals($value1$, x, "failing compareAndExchangeRelease $type$ value");
 541         }
 542 
 543         {
 544             MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN);
 545             boolean success = false;
 546             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 547                 success = (boolean) mh.invokeExact($value1$, $value2$);
 548                 if (!success) weakDelay();
 549             }
 550             assertEquals(success, true, "success weakCompareAndSetPlain $type$");
 551             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 552             assertEquals($value2$, x, "success weakCompareAndSetPlain $type$ value");
 553         }
 554 
 555         {
 556             boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact($value1$, $value3$);
 557             assertEquals(success, false, "failing weakCompareAndSetPlain $type$");
 558             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 559             assertEquals($value2$, x, "failing weakCompareAndSetPlain $type$ value");
 560         }
 561 
 562         {
 563             MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE);
 564             boolean success = false;
 565             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 566                 success = (boolean) mh.invokeExact($value2$, $value1$);
 567                 if (!success) weakDelay();
 568             }
 569             assertEquals(success, true, "success weakCompareAndSetAcquire $type$");
 570             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 571             assertEquals($value1$, x, "success weakCompareAndSetAcquire $type$");
 572         }
 573 
 574         {
 575             MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE);
 576             boolean success = (boolean) mh.invokeExact($value2$, $value3$);
 577             assertEquals(success, false, "failing weakCompareAndSetAcquire $type$");
 578             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 579             assertEquals($value1$, x, "failing weakCompareAndSetAcquire $type$ value");
 580         }
 581 
 582         {
 583             MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE);
 584             boolean success = false;
 585             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 586                 success = (boolean) mh.invokeExact($value1$, $value2$);
 587                 if (!success) weakDelay();
 588             }
 589             assertEquals(success, true, "success weakCompareAndSetRelease $type$");
 590             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 591             assertEquals($value2$, x, "success weakCompareAndSetRelease $type$");
 592         }
 593 
 594         {
 595             boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact($value1$, $value3$);
 596             assertEquals(success, false, "failing weakCompareAndSetRelease $type$");
 597             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 598             assertEquals($value2$, x, "failing weakCompareAndSetRelease $type$ value");
 599         }
 600 
 601         {
 602             MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET);
 603             boolean success = false;
 604             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 605                 success = (boolean) mh.invokeExact($value2$, $value1$);
 606                 if (!success) weakDelay();
 607             }
 608             assertEquals(success, true, "success weakCompareAndSet $type$");
 609             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 610             assertEquals($value1$, x, "success weakCompareAndSet $type$");
 611         }
 612 
 613         {
 614             boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact($value2$, $value3$);
 615             assertEquals(success, false, "failing weakCompareAndSet $type$");
 616             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 617             assertEquals($value1$, x, "failing weakCompareAndSetRe $type$ value");
 618         }
 619 
 620         // Compare set and get
 621         {
 622             hs.get(TestAccessMode.SET).invokeExact($value1$);
 623 
 624             $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_SET).invokeExact($value2$);
 625             assertEquals($value1$, o, "getAndSet $type$");
 626             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 627             assertEquals($value2$, x, "getAndSet $type$ value");
 628         }
 629 
 630         // Compare set and get
 631         {
 632             hs.get(TestAccessMode.SET).invokeExact($value1$);
 633 
 634             $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_SET_ACQUIRE).invokeExact($value2$);
 635             assertEquals($value1$, o, "getAndSetAcquire $type$");
 636             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 637             assertEquals($value2$, x, "getAndSetAcquire $type$ value");
 638         }
 639 
 640         // Compare set and get
 641         {
 642             hs.get(TestAccessMode.SET).invokeExact($value1$);
 643 
 644             $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_SET_RELEASE).invokeExact($value2$);
 645             assertEquals($value1$, o, "getAndSetRelease $type$");
 646             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 647             assertEquals($value2$, x, "getAndSetRelease $type$ value");
 648         }
 649 #end[CAS]
 650 
 651 #if[AtomicAdd]
 652         // get and add, add and get
 653         {
 654             hs.get(TestAccessMode.SET).invokeExact($value1$);
 655 
 656             $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_ADD).invokeExact($value2$);
 657             assertEquals($value1$, o, "getAndAdd $type$");
 658             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 659             assertEquals(($type$)($value1$ + $value2$), x, "getAndAdd $type$ value");
 660         }
 661 
 662         {
 663             hs.get(TestAccessMode.SET).invokeExact($value1$);
 664 
 665             $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_ADD_ACQUIRE).invokeExact($value2$);
 666             assertEquals($value1$, o, "getAndAddAcquire $type$");
 667             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 668             assertEquals(($type$)($value1$ + $value2$), x, "getAndAddAcquire $type$ value");
 669         }
 670 
 671         {
 672             hs.get(TestAccessMode.SET).invokeExact($value1$);
 673 
 674             $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_ADD_RELEASE).invokeExact($value2$);
 675             assertEquals($value1$, o, "getAndAddRelease $type$");
 676             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 677             assertEquals(($type$)($value1$ + $value2$), x, "getAndAddRelease $type$ value");
 678         }
 679 #end[AtomicAdd]
 680 
 681 #if[Bitwise]
 682         // get and bitwise or
 683         {
 684             hs.get(TestAccessMode.SET).invokeExact($value1$);
 685 
 686             $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_OR).invokeExact($value2$);
 687             assertEquals($value1$, o, "getAndBitwiseOr $type$");
 688             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 689             assertEquals(($type$)($value1$ | $value2$), x, "getAndBitwiseOr $type$ value");
 690         }
 691 
 692         {
 693             hs.get(TestAccessMode.SET).invokeExact($value1$);
 694 
 695             $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_OR_ACQUIRE).invokeExact($value2$);
 696             assertEquals($value1$, o, "getAndBitwiseOrAcquire $type$");
 697             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 698             assertEquals(($type$)($value1$ | $value2$), x, "getAndBitwiseOrAcquire $type$ value");
 699         }
 700 
 701         {
 702             hs.get(TestAccessMode.SET).invokeExact($value1$);
 703 
 704             $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_OR_RELEASE).invokeExact($value2$);
 705             assertEquals($value1$, o, "getAndBitwiseOrRelease $type$");
 706             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 707             assertEquals(($type$)($value1$ | $value2$), x, "getAndBitwiseOrRelease $type$ value");
 708         }
 709 
 710         // get and bitwise and
 711         {
 712             hs.get(TestAccessMode.SET).invokeExact($value1$);
 713 
 714             $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_AND).invokeExact($value2$);
 715             assertEquals($value1$, o, "getAndBitwiseAnd $type$");
 716             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 717             assertEquals(($type$)($value1$ & $value2$), x, "getAndBitwiseAnd $type$ value");
 718         }
 719 
 720         {
 721             hs.get(TestAccessMode.SET).invokeExact($value1$);
 722 
 723             $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_AND_ACQUIRE).invokeExact($value2$);
 724             assertEquals($value1$, o, "getAndBitwiseAndAcquire $type$");
 725             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 726             assertEquals(($type$)($value1$ & $value2$), x, "getAndBitwiseAndAcquire $type$ value");
 727         }
 728 
 729         {
 730             hs.get(TestAccessMode.SET).invokeExact($value1$);
 731 
 732             $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_AND_RELEASE).invokeExact($value2$);
 733             assertEquals($value1$, o, "getAndBitwiseAndRelease $type$");
 734             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 735             assertEquals(($type$)($value1$ & $value2$), x, "getAndBitwiseAndRelease $type$ value");
 736         }
 737 
 738         // get and bitwise xor
 739         {
 740             hs.get(TestAccessMode.SET).invokeExact($value1$);
 741 
 742             $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_XOR).invokeExact($value2$);
 743             assertEquals($value1$, o, "getAndBitwiseXor $type$");
 744             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 745             assertEquals(($type$)($value1$ ^ $value2$), x, "getAndBitwiseXor $type$ value");
 746         }
 747 
 748         {
 749             hs.get(TestAccessMode.SET).invokeExact($value1$);
 750 
 751             $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_ACQUIRE).invokeExact($value2$);
 752             assertEquals($value1$, o, "getAndBitwiseXorAcquire $type$");
 753             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 754             assertEquals(($type$)($value1$ ^ $value2$), x, "getAndBitwiseXorAcquire $type$ value");
 755         }
 756 
 757         {
 758             hs.get(TestAccessMode.SET).invokeExact($value1$);
 759 
 760             $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_RELEASE).invokeExact($value2$);
 761             assertEquals($value1$, o, "getAndBitwiseXorRelease $type$");
 762             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 763             assertEquals(($type$)($value1$ ^ $value2$), x, "getAndBitwiseXorRelease $type$ value");
 764         }
 765 #end[Bitwise]
 766     }
 767 
 768     static void testStaticFieldUnsupported(Handles hs) throws Throwable {
 769 #if[!CAS]
 770         for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) {
 771             checkUOE(am, () -> {
 772                 boolean r = (boolean) hs.get(am).invokeExact($value1$, $value2$);
 773             });
 774         }
 775 
 776         for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) {
 777             checkUOE(am, () -> {
 778                 $type$ r = ($type$) hs.get(am).invokeExact($value1$, $value2$);
 779             });
 780         }
 781 
 782         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) {
 783             checkUOE(am, () -> {
 784                 $type$ r = ($type$) hs.get(am).invokeExact($value1$);
 785             });
 786         }
 787 #end[CAS]
 788 
 789 #if[!AtomicAdd]
 790         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_ADD)) {
 791             checkUOE(am, () -> {
 792                 $type$ r = ($type$) hs.get(am).invokeExact($value1$);
 793             });
 794         }
 795 #end[AtomicAdd]
 796 
 797 #if[!Bitwise]
 798         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_BITWISE)) {
 799             checkUOE(am, () -> {
 800                 $type$ r = ($type$) hs.get(am).invokeExact($value1$);
 801             });
 802         }
 803 #end[Bitwise]
 804     }
 805 
 806 
 807     static void testArray(Handles hs) throws Throwable {
 808         $type$[] array = new $type$[10];
 809 
 810         for (int i = 0; i < array.length; i++) {
 811             // Plain
 812             {
 813                 hs.get(TestAccessMode.SET).invokeExact(array, i, $value1$);
 814                 $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
 815                 assertEquals($value1$, x, "get $type$ value");
 816             }
 817 
 818 
 819             // Volatile
 820             {
 821                 hs.get(TestAccessMode.SET_VOLATILE).invokeExact(array, i, $value2$);
 822                 $type$ x = ($type$) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(array, i);
 823                 assertEquals($value2$, x, "setVolatile $type$ value");
 824             }
 825 
 826             // Lazy
 827             {
 828                 hs.get(TestAccessMode.SET_RELEASE).invokeExact(array, i, $value1$);
 829                 $type$ x = ($type$) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(array, i);
 830                 assertEquals($value1$, x, "setRelease $type$ value");
 831             }
 832 
 833             // Opaque
 834             {
 835                 hs.get(TestAccessMode.SET_OPAQUE).invokeExact(array, i, $value2$);
 836                 $type$ x = ($type$) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(array, i);
 837                 assertEquals($value2$, x, "setOpaque $type$ value");
 838             }
 839 
 840 #if[CAS]
 841             hs.get(TestAccessMode.SET).invokeExact(array, i, $value1$);
 842 
 843             // Compare
 844             {
 845                 boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(array, i, $value1$, $value2$);
 846                 assertEquals(r, true, "success compareAndSet $type$");
 847                 $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
 848                 assertEquals($value2$, x, "success compareAndSet $type$ value");
 849             }
 850 
 851             {
 852                 boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(array, i, $value1$, $value3$);
 853                 assertEquals(r, false, "failing compareAndSet $type$");
 854                 $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
 855                 assertEquals($value2$, x, "failing compareAndSet $type$ value");
 856             }
 857 
 858             {
 859                 $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(array, i, $value2$, $value1$);
 860                 assertEquals(r, $value2$, "success compareAndExchange $type$");
 861                 $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
 862                 assertEquals($value1$, x, "success compareAndExchange $type$ value");
 863             }
 864 
 865             {
 866                 $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(array, i, $value2$, $value3$);
 867                 assertEquals(r, $value1$, "failing compareAndExchange $type$");
 868                 $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
 869                 assertEquals($value1$, x, "failing compareAndExchange $type$ value");
 870             }
 871 
 872             {
 873                 $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(array, i, $value1$, $value2$);
 874                 assertEquals(r, $value1$, "success compareAndExchangeAcquire $type$");
 875                 $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
 876                 assertEquals($value2$, x, "success compareAndExchangeAcquire $type$ value");
 877             }
 878 
 879             {
 880                 $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(array, i, $value1$, $value3$);
 881                 assertEquals(r, $value2$, "failing compareAndExchangeAcquire $type$");
 882                 $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
 883                 assertEquals($value2$, x, "failing compareAndExchangeAcquire $type$ value");
 884             }
 885 
 886             {
 887                 $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(array, i, $value2$, $value1$);
 888                 assertEquals(r, $value2$, "success compareAndExchangeRelease $type$");
 889                 $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
 890                 assertEquals($value1$, x, "success compareAndExchangeRelease $type$ value");
 891             }
 892 
 893             {
 894                 $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(array, i, $value2$, $value3$);
 895                 assertEquals(r, $value1$, "failing compareAndExchangeRelease $type$");
 896                 $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
 897                 assertEquals($value1$, x, "failing compareAndExchangeRelease $type$ value");
 898             }
 899 
 900             {
 901                 MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN);
 902                 boolean success = false;
 903                 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 904                     success = (boolean) mh.invokeExact(array, i, $value1$, $value2$);
 905                     if (!success) weakDelay();
 906                 }
 907                 assertEquals(success, true, "success weakCompareAndSetPlain $type$");
 908                 $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
 909                 assertEquals($value2$, x, "success weakCompareAndSetPlain $type$ value");
 910             }
 911 
 912             {
 913                 boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, $value1$, $value3$);
 914                 assertEquals(success, false, "failing weakCompareAndSetPlain $type$");
 915                 $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
 916                 assertEquals($value2$, x, "failing weakCompareAndSetPlain $type$ value");
 917             }
 918 
 919             {
 920                 MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE);
 921                 boolean success = false;
 922                 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 923                     success = (boolean) mh.invokeExact(array, i, $value2$, $value1$);
 924                     if (!success) weakDelay();
 925                 }
 926                 assertEquals(success, true, "success weakCompareAndSetAcquire $type$");
 927                 $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
 928                 assertEquals($value1$, x, "success weakCompareAndSetAcquire $type$");
 929             }
 930 
 931             {
 932                 boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, $value2$, $value3$);
 933                 assertEquals(success, false, "failing weakCompareAndSetAcquire $type$");
 934                 $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
 935                 assertEquals($value1$, x, "failing weakCompareAndSetAcquire $type$ value");
 936             }
 937 
 938             {
 939                 MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE);
 940                 boolean success = false;
 941                 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 942                     success = (boolean) mh.invokeExact(array, i, $value1$, $value2$);
 943                     if (!success) weakDelay();
 944                 }
 945                 assertEquals(success, true, "success weakCompareAndSetRelease $type$");
 946                 $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
 947                 assertEquals($value2$, x, "success weakCompareAndSetRelease $type$");
 948             }
 949 
 950             {
 951                 boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, $value1$, $value3$);
 952                 assertEquals(success, false, "failing weakCompareAndSetAcquire $type$");
 953                 $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
 954                 assertEquals($value2$, x, "failing weakCompareAndSetAcquire $type$ value");
 955             }
 956 
 957             {
 958                 MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET);
 959                 boolean success = false;
 960                 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 961                     success = (boolean) mh.invokeExact(array, i, $value2$, $value1$);
 962                     if (!success) weakDelay();
 963                 }
 964                 assertEquals(success, true, "success weakCompareAndSet $type$");
 965                 $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
 966                 assertEquals($value1$, x, "success weakCompareAndSet $type$");
 967             }
 968 
 969             {
 970                 boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, $value2$, $value3$);
 971                 assertEquals(success, false, "failing weakCompareAndSet $type$");
 972                 $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
 973                 assertEquals($value1$, x, "failing weakCompareAndSet $type$ value");
 974             }
 975 
 976             // Compare set and get
 977             {
 978                 hs.get(TestAccessMode.SET).invokeExact(array, i, $value1$);
 979 
 980                 $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_SET).invokeExact(array, i, $value2$);
 981                 assertEquals($value1$, o, "getAndSet $type$");
 982                 $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
 983                 assertEquals($value2$, x, "getAndSet $type$ value");
 984             }
 985 
 986             {
 987                 hs.get(TestAccessMode.SET).invokeExact(array, i, $value1$);
 988 
 989                 $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_SET_ACQUIRE).invokeExact(array, i, $value2$);
 990                 assertEquals($value1$, o, "getAndSetAcquire $type$");
 991                 $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
 992                 assertEquals($value2$, x, "getAndSetAcquire $type$ value");
 993             }
 994 
 995             {
 996                 hs.get(TestAccessMode.SET).invokeExact(array, i, $value1$);
 997 
 998                 $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_SET_RELEASE).invokeExact(array, i, $value2$);
 999                 assertEquals($value1$, o, "getAndSetRelease $type$");
1000                 $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
1001                 assertEquals($value2$, x, "getAndSetRelease $type$ value");
1002             }
1003 #end[CAS]
1004 
1005 #if[AtomicAdd]
1006             // get and add, add and get
1007             {
1008                 hs.get(TestAccessMode.SET).invokeExact(array, i, $value1$);
1009 
1010                 $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_ADD).invokeExact(array, i, $value2$);
1011                 assertEquals($value1$, o, "getAndAdd $type$");
1012                 $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
1013                 assertEquals(($type$)($value1$ + $value2$), x, "getAndAdd $type$ value");
1014             }
1015 
1016             {
1017                 hs.get(TestAccessMode.SET).invokeExact(array, i, $value1$);
1018 
1019                 $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_ADD_ACQUIRE).invokeExact(array, i, $value2$);
1020                 assertEquals($value1$, o, "getAndAddAcquire $type$");
1021                 $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
1022                 assertEquals(($type$)($value1$ + $value2$), x, "getAndAddAcquire $type$ value");
1023             }
1024 
1025             {
1026                 hs.get(TestAccessMode.SET).invokeExact(array, i, $value1$);
1027 
1028                 $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_ADD_RELEASE).invokeExact(array, i, $value2$);
1029                 assertEquals($value1$, o, "getAndAddRelease $type$");
1030                 $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
1031                 assertEquals(($type$)($value1$ + $value2$), x, "getAndAddRelease $type$ value");
1032             }
1033 #end[AtomicAdd]
1034 
1035 #if[Bitwise]
1036         // get and bitwise or
1037         {
1038             hs.get(TestAccessMode.SET).invokeExact(array, i, $value1$);
1039 
1040             $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_OR).invokeExact(array, i, $value2$);
1041             assertEquals($value1$, o, "getAndBitwiseOr $type$");
1042             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
1043             assertEquals(($type$)($value1$ | $value2$), x, "getAndBitwiseOr $type$ value");
1044         }
1045 
1046         {
1047             hs.get(TestAccessMode.SET).invokeExact(array, i, $value1$);
1048 
1049             $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_OR_ACQUIRE).invokeExact(array, i, $value2$);
1050             assertEquals($value1$, o, "getAndBitwiseOrAcquire $type$");
1051             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
1052             assertEquals(($type$)($value1$ | $value2$), x, "getAndBitwiseOrAcquire $type$ value");
1053         }
1054 
1055         {
1056             hs.get(TestAccessMode.SET).invokeExact(array, i, $value1$);
1057 
1058             $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_OR_RELEASE).invokeExact(array, i, $value2$);
1059             assertEquals($value1$, o, "getAndBitwiseOrRelease $type$");
1060             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
1061             assertEquals(($type$)($value1$ | $value2$), x, "getAndBitwiseOrRelease $type$ value");
1062         }
1063 
1064         // get and bitwise and
1065         {
1066             hs.get(TestAccessMode.SET).invokeExact(array, i, $value1$);
1067 
1068             $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_AND).invokeExact(array, i, $value2$);
1069             assertEquals($value1$, o, "getAndBitwiseAnd $type$");
1070             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
1071             assertEquals(($type$)($value1$ & $value2$), x, "getAndBitwiseAnd $type$ value");
1072         }
1073 
1074         {
1075             hs.get(TestAccessMode.SET).invokeExact(array, i, $value1$);
1076 
1077             $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_AND_ACQUIRE).invokeExact(array, i, $value2$);
1078             assertEquals($value1$, o, "getAndBitwiseAndAcquire $type$");
1079             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
1080             assertEquals(($type$)($value1$ & $value2$), x, "getAndBitwiseAndAcquire $type$ value");
1081         }
1082 
1083         {
1084             hs.get(TestAccessMode.SET).invokeExact(array, i, $value1$);
1085 
1086             $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_AND_RELEASE).invokeExact(array, i, $value2$);
1087             assertEquals($value1$, o, "getAndBitwiseAndRelease $type$");
1088             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
1089             assertEquals(($type$)($value1$ & $value2$), x, "getAndBitwiseAndRelease $type$ value");
1090         }
1091 
1092         // get and bitwise xor
1093         {
1094             hs.get(TestAccessMode.SET).invokeExact(array, i, $value1$);
1095 
1096             $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_XOR).invokeExact(array, i, $value2$);
1097             assertEquals($value1$, o, "getAndBitwiseXor $type$");
1098             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
1099             assertEquals(($type$)($value1$ ^ $value2$), x, "getAndBitwiseXor $type$ value");
1100         }
1101 
1102         {
1103             hs.get(TestAccessMode.SET).invokeExact(array, i, $value1$);
1104 
1105             $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_ACQUIRE).invokeExact(array, i, $value2$);
1106             assertEquals($value1$, o, "getAndBitwiseXorAcquire $type$");
1107             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
1108             assertEquals(($type$)($value1$ ^ $value2$), x, "getAndBitwiseXorAcquire $type$ value");
1109         }
1110 
1111         {
1112             hs.get(TestAccessMode.SET).invokeExact(array, i, $value1$);
1113 
1114             $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_BITWISE_XOR_RELEASE).invokeExact(array, i, $value2$);
1115             assertEquals($value1$, o, "getAndBitwiseXorRelease $type$");
1116             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
1117             assertEquals(($type$)($value1$ ^ $value2$), x, "getAndBitwiseXorRelease $type$ value");
1118         }
1119 #end[Bitwise]
1120         }
1121     }
1122 
1123     static void testArrayUnsupported(Handles hs) throws Throwable {
1124         $type$[] array = new $type$[10];
1125 
1126         final int i = 0;
1127 #if[!CAS]
1128         for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) {
1129             checkUOE(am, () -> {
1130                 boolean r = (boolean) hs.get(am).invokeExact(array, i, $value1$, $value2$);
1131             });
1132         }
1133 
1134         for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) {
1135             checkUOE(am, () -> {
1136                 $type$ r = ($type$) hs.get(am).invokeExact(array, i, $value1$, $value2$);
1137             });
1138         }
1139 
1140         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) {
1141             checkUOE(am, () -> {
1142                 $type$ r = ($type$) hs.get(am).invokeExact(array, i, $value1$);
1143             });
1144         }
1145 #end[CAS]
1146 
1147 #if[!AtomicAdd]
1148         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_ADD)) {
1149             checkUOE(am, () -> {
1150                 $type$ o = ($type$) hs.get(am).invokeExact(array, i, $value1$);
1151             });
1152         }
1153 #end[AtomicAdd]
1154 
1155 #if[!Bitwise]
1156         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_BITWISE)) {
1157             checkUOE(am, () -> {
1158                 $type$ o = ($type$) hs.get(am).invokeExact(array, i, $value1$);
1159             });
1160         }
1161 #end[Bitwise]
1162     }
1163 
1164     static void testArrayIndexOutOfBounds(Handles hs) throws Throwable {
1165         $type$[] array = new $type$[10];
1166 
1167         for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
1168             final int ci = i;
1169 
1170             for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET)) {
1171                 checkAIOOBE(am, () -> {
1172                     $type$ x = ($type$) hs.get(am).invokeExact(array, ci);
1173                 });
1174             }
1175 
1176             for (TestAccessMode am : testAccessModesOfType(TestAccessType.SET)) {
1177                 checkAIOOBE(am, () -> {
1178                     hs.get(am).invokeExact(array, ci, $value1$);
1179                 });
1180             }
1181 
1182 #if[CAS]
1183             for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) {
1184                 checkAIOOBE(am, () -> {
1185                     boolean r = (boolean) hs.get(am).invokeExact(array, ci, $value1$, $value2$);
1186                 });
1187             }
1188 
1189             for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) {
1190                 checkAIOOBE(am, () -> {
1191                     $type$ r = ($type$) hs.get(am).invokeExact(array, ci, $value2$, $value1$);
1192                 });
1193             }
1194 
1195             for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) {
1196                 checkAIOOBE(am, () -> {
1197                     $type$ o = ($type$) hs.get(am).invokeExact(array, ci, $value1$);
1198                 });
1199             }
1200 #end[CAS]
1201 
1202 #if[AtomicAdd]
1203             for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_ADD)) {
1204                 checkAIOOBE(am, () -> {
1205                     $type$ o = ($type$) hs.get(am).invokeExact(array, ci, $value3$);
1206                 });
1207             }
1208 #end[AtomicAdd]
1209 
1210 #if[Bitwise]
1211             for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_BITWISE)) {
1212                 checkAIOOBE(am, () -> {
1213                     $type$ o = ($type$) hs.get(am).invokeExact(array, ci, $value3$);
1214                 });
1215             }
1216 #end[Bitwise]
1217         }
1218     }
1219 }
1220