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