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