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