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