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