1 /*
   2  * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccess$Type$
  27  */
  28 
  29 import org.testng.annotations.BeforeClass;
  30 import org.testng.annotations.DataProvider;
  31 import org.testng.annotations.Test;
  32 
  33 import java.lang.invoke.MethodHandles;
  34 import java.lang.invoke.VarHandle;
  35 import java.util.ArrayList;
  36 import java.util.Arrays;
  37 import java.util.List;
  38 
  39 import static org.testng.Assert.*;
  40 
  41 public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest {
  42     static final $type$ static_final_v = $value1$;
  43 
  44     static $type$ static_v;
  45 
  46     final $type$ final_v = $value1$;
  47 
  48     $type$ v;
  49 
  50     VarHandle vhFinalField;
  51 
  52     VarHandle vhField;
  53 
  54     VarHandle vhStaticField;
  55 
  56     VarHandle vhStaticFinalField;
  57 
  58     VarHandle vhArray;
  59 
  60     @BeforeClass
  61     public void setup() throws Exception {
  62         vhFinalField = MethodHandles.lookup().findVarHandle(
  63                 VarHandleTestMethodHandleAccess$Type$.class, "final_v", $type$.class);
  64 
  65         vhField = MethodHandles.lookup().findVarHandle(
  66                 VarHandleTestMethodHandleAccess$Type$.class, "v", $type$.class);
  67 
  68         vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
  69             VarHandleTestMethodHandleAccess$Type$.class, "static_final_v", $type$.class);
  70 
  71         vhStaticField = MethodHandles.lookup().findStaticVarHandle(
  72             VarHandleTestMethodHandleAccess$Type$.class, "static_v", $type$.class);
  73 
  74         vhArray = MethodHandles.arrayElementVarHandle($type$[].class);
  75     }
  76 
  77 
  78     @DataProvider
  79     public Object[][] accessTestCaseProvider() throws Exception {
  80         List<AccessTestCase<?>> cases = new ArrayList<>();
  81 
  82         for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
  83             cases.add(new MethodHandleAccessTestCase("Instance field",
  84                                                      vhField, f, hs -> testInstanceField(this, hs)));
  85             cases.add(new MethodHandleAccessTestCase("Instance field unsupported",
  86                                                      vhField, f, hs -> testInstanceFieldUnsupported(this, hs),
  87                                                      false));
  88 
  89             cases.add(new MethodHandleAccessTestCase("Static field",
  90                                                      vhStaticField, f, VarHandleTestMethodHandleAccess$Type$::testStaticField));
  91             cases.add(new MethodHandleAccessTestCase("Static field unsupported",
  92                                                      vhStaticField, f, VarHandleTestMethodHandleAccess$Type$::testStaticFieldUnsupported,
  93                                                      false));
  94 
  95             cases.add(new MethodHandleAccessTestCase("Array",
  96                                                      vhArray, f, VarHandleTestMethodHandleAccess$Type$::testArray));
  97             cases.add(new MethodHandleAccessTestCase("Array unsupported",
  98                                                      vhArray, f, VarHandleTestMethodHandleAccess$Type$::testArrayUnsupported,
  99                                                      false));
 100             cases.add(new MethodHandleAccessTestCase("Array index out of bounds",
 101                                                      vhArray, f, VarHandleTestMethodHandleAccess$Type$::testArrayIndexOutOfBounds,
 102                                                      false));
 103         }
 104 
 105         // Work around issue with jtreg summary reporting which truncates
 106         // the String result of Object.toString to 30 characters, hence
 107         // the first dummy argument
 108         return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
 109     }
 110 
 111     @Test(dataProvider = "accessTestCaseProvider")
 112     public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
 113         T t = atc.get();
 114         int iters = atc.requiresLoop() ? ITERS : 1;
 115         for (int c = 0; c < iters; c++) {
 116             atc.testAccess(t);
 117         }
 118     }
 119 
 120 
 121     static void testInstanceField(VarHandleTestMethodHandleAccess$Type$ recv, Handles hs) throws Throwable {
 122         // Plain
 123         {
 124             hs.get(TestAccessMode.SET).invokeExact(recv, $value1$);
 125             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
 126             assertEquals(x, $value1$, "set $type$ value");
 127         }
 128 
 129 
 130         // Volatile
 131         {
 132             hs.get(TestAccessMode.SET_VOLATILE).invokeExact(recv, $value2$);
 133             $type$ x = ($type$) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(recv);
 134             assertEquals(x, $value2$, "setVolatile $type$ value");
 135         }
 136 
 137         // Lazy
 138         {
 139             hs.get(TestAccessMode.SET_RELEASE).invokeExact(recv, $value1$);
 140             $type$ x = ($type$) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(recv);
 141             assertEquals(x, $value1$, "setRelease $type$ value");
 142         }
 143 
 144         // Opaque
 145         {
 146             hs.get(TestAccessMode.SET_OPAQUE).invokeExact(recv, $value2$);
 147             $type$ x = ($type$) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(recv);
 148             assertEquals(x, $value2$, "setOpaque $type$ value");
 149         }
 150 
 151 #if[CAS]
 152         hs.get(TestAccessMode.SET).invokeExact(recv, $value1$);
 153 
 154         // Compare
 155         {
 156             boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(recv, $value1$, $value2$);
 157             assertEquals(r, true, "success compareAndSet $type$");
 158             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
 159             assertEquals(x, $value2$, "success compareAndSet $type$ value");
 160         }
 161 
 162         {
 163             boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(recv, $value1$, $value3$);
 164             assertEquals(r, false, "failing compareAndSet $type$");
 165             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
 166             assertEquals(x, $value2$, "failing compareAndSet $type$ value");
 167         }
 168 
 169         {
 170             $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_VOLATILE).invokeExact(recv, $value2$, $value1$);
 171             assertEquals(r, $value2$, "success compareAndExchangeVolatile $type$");
 172             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
 173             assertEquals(x, $value1$, "success compareAndExchangeVolatile $type$ value");
 174         }
 175 
 176         {
 177             $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_VOLATILE).invokeExact(recv, $value2$, $value3$);
 178             assertEquals(r, $value1$, "failing compareAndExchangeVolatile $type$");
 179             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
 180             assertEquals(x, $value1$, "failing compareAndExchangeVolatile $type$ value");
 181         }
 182 
 183         {
 184             $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(recv, $value1$, $value2$);
 185             assertEquals(r, $value1$, "success compareAndExchangeAcquire $type$");
 186             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
 187             assertEquals(x, $value2$, "success compareAndExchangeAcquire $type$ value");
 188         }
 189 
 190         {
 191             $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(recv, $value1$, $value3$);
 192             assertEquals(r, $value2$, "failing compareAndExchangeAcquire $type$");
 193             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
 194             assertEquals(x, $value2$, "failing compareAndExchangeAcquire $type$ value");
 195         }
 196 
 197         {
 198             $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(recv, $value2$, $value1$);
 199             assertEquals(r, $value2$, "success compareAndExchangeRelease $type$");
 200             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
 201             assertEquals(x, $value1$, "success compareAndExchangeRelease $type$ value");
 202         }
 203 
 204         {
 205             $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(recv, $value2$, $value3$);
 206             assertEquals(r, $value1$, "failing compareAndExchangeRelease $type$");
 207             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
 208             assertEquals(x, $value1$, "failing compareAndExchangeRelease $type$ value");
 209         }
 210 
 211         {
 212             boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, $value1$, $value2$);
 213             assertEquals(r, true, "weakCompareAndSet $type$");
 214             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
 215             assertEquals(x, $value2$, "weakCompareAndSet $type$ value");
 216         }
 217 
 218         {
 219             boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, $value2$, $value1$);
 220             assertEquals(r, true, "weakCompareAndSetAcquire $type$");
 221             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
 222             assertEquals(x, $value1$, "weakCompareAndSetAcquire $type$");
 223         }
 224 
 225         {
 226             boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, $value1$, $value2$);
 227             assertEquals(r, true, "weakCompareAndSetRelease $type$");
 228             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
 229             assertEquals(x, $value2$, "weakCompareAndSetRelease $type$");
 230         }
 231 
 232         // Compare set and get
 233         {
 234             $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_SET).invokeExact(recv, $value1$);
 235             assertEquals(o, $value2$, "getAndSet $type$");
 236             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
 237             assertEquals(x, $value1$, "getAndSet $type$ value");
 238         }
 239 #end[CAS]
 240 
 241 #if[AtomicAdd]
 242         hs.get(TestAccessMode.SET).invokeExact(recv, $value1$);
 243 
 244         // get and add, add and get
 245         {
 246             $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_ADD).invokeExact(recv, $value3$);
 247             assertEquals(o, $value1$, "getAndAdd $type$");
 248             $type$ c = ($type$) hs.get(TestAccessMode.ADD_AND_GET).invokeExact(recv, $value3$);
 249             assertEquals(c, $value1$ + $value3$ + $value3$, "getAndAdd $type$ value");
 250         }
 251 #end[AtomicAdd]
 252     }
 253 
 254     static void testInstanceFieldUnsupported(VarHandleTestMethodHandleAccess$Type$ recv, Handles hs) throws Throwable {
 255 #if[!CAS]
 256         for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) {
 257             checkUOE(am, () -> {
 258                 boolean r = (boolean) hs.get(am).invokeExact(recv, $value1$, $value2$);
 259             });
 260         }
 261 
 262         for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) {
 263             checkUOE(am, () -> {
 264                 $type$ r = ($type$) hs.get(am).invokeExact(recv, $value1$, $value2$);
 265             });
 266         }
 267 
 268         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) {
 269             checkUOE(am, () -> {
 270                 $type$ r = ($type$) hs.get(am).invokeExact(recv, $value1$);
 271             });
 272         }
 273 #end[CAS]
 274 
 275 #if[!AtomicAdd]
 276         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_ADD)) {
 277             checkUOE(am, () -> {
 278                 $type$ r = ($type$) hs.get(am).invokeExact(recv, $value1$);
 279             });
 280         }
 281 #end[AtomicAdd]
 282     }
 283 
 284 
 285     static void testStaticField(Handles hs) throws Throwable {
 286         // Plain
 287         {
 288             hs.get(TestAccessMode.SET).invokeExact($value1$);
 289             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 290             assertEquals(x, $value1$, "set $type$ value");
 291         }
 292 
 293 
 294         // Volatile
 295         {
 296             hs.get(TestAccessMode.SET_VOLATILE).invokeExact($value2$);
 297             $type$ x = ($type$) hs.get(TestAccessMode.GET_VOLATILE).invokeExact();
 298             assertEquals(x, $value2$, "setVolatile $type$ value");
 299         }
 300 
 301         // Lazy
 302         {
 303             hs.get(TestAccessMode.SET_RELEASE).invokeExact($value1$);
 304             $type$ x = ($type$) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact();
 305             assertEquals(x, $value1$, "setRelease $type$ value");
 306         }
 307 
 308         // Opaque
 309         {
 310             hs.get(TestAccessMode.SET_OPAQUE).invokeExact($value2$);
 311             $type$ x = ($type$) hs.get(TestAccessMode.GET_OPAQUE).invokeExact();
 312             assertEquals(x, $value2$, "setOpaque $type$ value");
 313         }
 314 
 315 #if[CAS]
 316         hs.get(TestAccessMode.SET).invokeExact($value1$);
 317 
 318         // Compare
 319         {
 320             boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact($value1$, $value2$);
 321             assertEquals(r, true, "success compareAndSet $type$");
 322             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 323             assertEquals(x, $value2$, "success compareAndSet $type$ value");
 324         }
 325 
 326         {
 327             boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact($value1$, $value3$);
 328             assertEquals(r, false, "failing compareAndSet $type$");
 329             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 330             assertEquals(x, $value2$, "failing compareAndSet $type$ value");
 331         }
 332 
 333         {
 334             $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_VOLATILE).invokeExact($value2$, $value1$);
 335             assertEquals(r, $value2$, "success compareAndExchangeVolatile $type$");
 336             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 337             assertEquals(x, $value1$, "success compareAndExchangeVolatile $type$ value");
 338         }
 339 
 340         {
 341             $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_VOLATILE).invokeExact($value2$, $value3$);
 342             assertEquals(r, $value1$, "failing compareAndExchangeVolatile $type$");
 343             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 344             assertEquals(x, $value1$, "failing compareAndExchangeVolatile $type$ value");
 345         }
 346 
 347         {
 348             $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact($value1$, $value2$);
 349             assertEquals(r, $value1$, "success compareAndExchangeAcquire $type$");
 350             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 351             assertEquals(x, $value2$, "success compareAndExchangeAcquire $type$ value");
 352         }
 353 
 354         {
 355             $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact($value1$, $value3$);
 356             assertEquals(r, $value2$, "failing compareAndExchangeAcquire $type$");
 357             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 358             assertEquals(x, $value2$, "failing compareAndExchangeAcquire $type$ value");
 359         }
 360 
 361         {
 362             $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact($value2$, $value1$);
 363             assertEquals(r, $value2$, "success compareAndExchangeRelease $type$");
 364             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 365             assertEquals(x, $value1$, "success compareAndExchangeRelease $type$ value");
 366         }
 367 
 368         {
 369             $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact($value2$, $value3$);
 370             assertEquals(r, $value1$, "failing compareAndExchangeRelease $type$");
 371             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 372             assertEquals(x, $value1$, "failing compareAndExchangeRelease $type$ value");
 373         }
 374 
 375         {
 376             boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact($value1$, $value2$);
 377             assertEquals(r, true, "weakCompareAndSet $type$");
 378             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 379             assertEquals(x, $value2$, "weakCompareAndSet $type$ value");
 380         }
 381 
 382         {
 383             boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact($value2$, $value1$);
 384             assertEquals(r, true, "weakCompareAndSetAcquire $type$");
 385             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 386             assertEquals(x, $value1$, "weakCompareAndSetAcquire $type$");
 387         }
 388 
 389         {
 390             boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact( $value1$, $value2$);
 391             assertEquals(r, true, "weakCompareAndSetRelease $type$");
 392             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 393             assertEquals(x, $value2$, "weakCompareAndSetRelease $type$");
 394         }
 395 
 396         // Compare set and get
 397         {
 398             $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_SET).invokeExact( $value1$);
 399             assertEquals(o, $value2$, "getAndSet $type$");
 400             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
 401             assertEquals(x, $value1$, "getAndSet $type$ value");
 402         }
 403 #end[CAS]
 404 
 405 #if[AtomicAdd]
 406         hs.get(TestAccessMode.SET).invokeExact($value1$);
 407 
 408         // get and add, add and get
 409         {
 410             $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_ADD).invokeExact( $value3$);
 411             assertEquals(o, $value1$, "getAndAdd $type$");
 412             $type$ c = ($type$) hs.get(TestAccessMode.ADD_AND_GET).invokeExact($value3$);
 413             assertEquals(c, $value1$ + $value3$ + $value3$, "getAndAdd $type$ value");
 414         }
 415 #end[AtomicAdd]
 416     }
 417 
 418     static void testStaticFieldUnsupported(Handles hs) throws Throwable {
 419 #if[!CAS]
 420         for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) {
 421             checkUOE(am, () -> {
 422                 boolean r = (boolean) hs.get(am).invokeExact($value1$, $value2$);
 423             });
 424         }
 425 
 426         for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) {
 427             checkUOE(am, () -> {
 428                 $type$ r = ($type$) hs.get(am).invokeExact($value1$, $value2$);
 429             });
 430         }
 431 
 432         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) {
 433             checkUOE(am, () -> {
 434                 $type$ r = ($type$) hs.get(am).invokeExact($value1$);
 435             });
 436         }
 437 #end[CAS]
 438 
 439 #if[!AtomicAdd]
 440         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_ADD)) {
 441             checkUOE(am, () -> {
 442                 $type$ r = ($type$) hs.get(am).invokeExact($value1$);
 443             });
 444         }
 445 #end[AtomicAdd]
 446     }
 447 
 448 
 449     static void testArray(Handles hs) throws Throwable {
 450         $type$[] array = new $type$[10];
 451 
 452         for (int i = 0; i < array.length; i++) {
 453             // Plain
 454             {
 455                 hs.get(TestAccessMode.SET).invokeExact(array, i, $value1$);
 456                 $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
 457                 assertEquals(x, $value1$, "get $type$ value");
 458             }
 459 
 460 
 461             // Volatile
 462             {
 463                 hs.get(TestAccessMode.SET_VOLATILE).invokeExact(array, i, $value2$);
 464                 $type$ x = ($type$) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(array, i);
 465                 assertEquals(x, $value2$, "setVolatile $type$ value");
 466             }
 467 
 468             // Lazy
 469             {
 470                 hs.get(TestAccessMode.SET_RELEASE).invokeExact(array, i, $value1$);
 471                 $type$ x = ($type$) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(array, i);
 472                 assertEquals(x, $value1$, "setRelease $type$ value");
 473             }
 474 
 475             // Opaque
 476             {
 477                 hs.get(TestAccessMode.SET_OPAQUE).invokeExact(array, i, $value2$);
 478                 $type$ x = ($type$) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(array, i);
 479                 assertEquals(x, $value2$, "setOpaque $type$ value");
 480             }
 481 
 482 #if[CAS]
 483             hs.get(TestAccessMode.SET).invokeExact(array, i, $value1$);
 484 
 485             // Compare
 486             {
 487                 boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(array, i, $value1$, $value2$);
 488                 assertEquals(r, true, "success compareAndSet $type$");
 489                 $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
 490                 assertEquals(x, $value2$, "success compareAndSet $type$ value");
 491             }
 492 
 493             {
 494                 boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(array, i, $value1$, $value3$);
 495                 assertEquals(r, false, "failing compareAndSet $type$");
 496                 $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
 497                 assertEquals(x, $value2$, "failing compareAndSet $type$ value");
 498             }
 499 
 500             {
 501                 $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_VOLATILE).invokeExact(array, i, $value2$, $value1$);
 502                 assertEquals(r, $value2$, "success compareAndExchangeVolatile $type$");
 503                 $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
 504                 assertEquals(x, $value1$, "success compareAndExchangeVolatile $type$ value");
 505             }
 506 
 507             {
 508                 $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_VOLATILE).invokeExact(array, i, $value2$, $value3$);
 509                 assertEquals(r, $value1$, "failing compareAndExchangeVolatile $type$");
 510                 $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
 511                 assertEquals(x, $value1$, "failing compareAndExchangeVolatile $type$ value");
 512             }
 513 
 514             {
 515                 $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(array, i, $value1$, $value2$);
 516                 assertEquals(r, $value1$, "success compareAndExchangeAcquire $type$");
 517                 $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
 518                 assertEquals(x, $value2$, "success compareAndExchangeAcquire $type$ value");
 519             }
 520 
 521             {
 522                 $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(array, i, $value1$, $value3$);
 523                 assertEquals(r, $value2$, "failing compareAndExchangeAcquire $type$");
 524                 $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
 525                 assertEquals(x, $value2$, "failing compareAndExchangeAcquire $type$ value");
 526             }
 527 
 528             {
 529                 $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(array, i, $value2$, $value1$);
 530                 assertEquals(r, $value2$, "success compareAndExchangeRelease $type$");
 531                 $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
 532                 assertEquals(x, $value1$, "success compareAndExchangeRelease $type$ value");
 533             }
 534 
 535             {
 536                 $type$ r = ($type$) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(array, i, $value2$, $value3$);
 537                 assertEquals(r, $value1$, "failing compareAndExchangeRelease $type$");
 538                 $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
 539                 assertEquals(x, $value1$, "failing compareAndExchangeRelease $type$ value");
 540             }
 541 
 542             {
 543                 boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, $value1$, $value2$);
 544                 assertEquals(r, true, "weakCompareAndSet $type$");
 545                 $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
 546                 assertEquals(x, $value2$, "weakCompareAndSet $type$ value");
 547             }
 548 
 549             {
 550                 boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, $value2$, $value1$);
 551                 assertEquals(r, true, "weakCompareAndSetAcquire $type$");
 552                 $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
 553                 assertEquals(x, $value1$, "weakCompareAndSetAcquire $type$");
 554             }
 555 
 556             {
 557                 boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(array, i, $value1$, $value2$);
 558                 assertEquals(r, true, "weakCompareAndSetRelease $type$");
 559                 $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
 560                 assertEquals(x, $value2$, "weakCompareAndSetRelease $type$");
 561             }
 562 
 563             // Compare set and get
 564             {
 565                 $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_SET).invokeExact(array, i, $value1$);
 566                 assertEquals(o, $value2$, "getAndSet $type$");
 567                 $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
 568                 assertEquals(x, $value1$, "getAndSet $type$ value");
 569             }
 570 #end[CAS]
 571 
 572 #if[AtomicAdd]
 573             hs.get(TestAccessMode.SET).invokeExact(array, i, $value1$);
 574 
 575             // get and add, add and get
 576             {
 577                 $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_ADD).invokeExact(array, i, $value3$);
 578                 assertEquals(o, $value1$, "getAndAdd $type$");
 579                 $type$ c = ($type$) hs.get(TestAccessMode.ADD_AND_GET).invokeExact(array, i, $value3$);
 580                 assertEquals(c, $value1$ + $value3$ + $value3$, "getAndAdd $type$ value");
 581             }
 582 #end[AtomicAdd]
 583         }
 584     }
 585 
 586     static void testArrayUnsupported(Handles hs) throws Throwable {
 587         $type$[] array = new $type$[10];
 588 
 589         final int i = 0;
 590 #if[!CAS]
 591         for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) {
 592             checkUOE(am, () -> {
 593                 boolean r = (boolean) hs.get(am).invokeExact(array, i, $value1$, $value2$);
 594             });
 595         }
 596 
 597         for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) {
 598             checkUOE(am, () -> {
 599                 $type$ r = ($type$) hs.get(am).invokeExact(array, i, $value1$, $value2$);
 600             });
 601         }
 602 
 603         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) {
 604             checkUOE(am, () -> {
 605                 $type$ r = ($type$) hs.get(am).invokeExact(array, i, $value1$);
 606             });
 607         }
 608 #end[CAS]
 609 
 610 #if[!AtomicAdd]
 611         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_ADD)) {
 612             checkUOE(am, () -> {
 613                 $type$ o = ($type$) hs.get(am).invokeExact(array, i, $value1$);
 614             });
 615         }
 616 #end[AtomicAdd]
 617     }
 618 
 619     static void testArrayIndexOutOfBounds(Handles hs) throws Throwable {
 620         $type$[] array = new $type$[10];
 621 
 622         for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
 623             final int ci = i;
 624 
 625             for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET)) {
 626                 checkIOOBE(am, () -> {
 627                     $type$ x = ($type$) hs.get(am).invokeExact(array, ci);
 628                 });
 629             }
 630 
 631             for (TestAccessMode am : testAccessModesOfType(TestAccessType.SET)) {
 632                 checkIOOBE(am, () -> {
 633                     hs.get(am).invokeExact(array, ci, $value1$);
 634                 });
 635             }
 636 
 637 #if[CAS]
 638             for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) {
 639                 checkIOOBE(am, () -> {
 640                     boolean r = (boolean) hs.get(am).invokeExact(array, ci, $value1$, $value2$);
 641                 });
 642             }
 643 
 644             for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) {
 645                 checkIOOBE(am, () -> {
 646                     $type$ r = ($type$) hs.get(am).invokeExact(array, ci, $value2$, $value1$);
 647                 });
 648             }
 649 
 650             for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) {
 651                 checkIOOBE(am, () -> {
 652                     $type$ o = ($type$) hs.get(am).invokeExact(array, ci, $value1$);
 653                 });
 654             }
 655 #end[CAS]
 656 
 657 #if[AtomicAdd]
 658             for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_ADD)) {
 659                 checkIOOBE(am, () -> {
 660                     $type$ o = ($type$) hs.get(am).invokeExact(array, ci, $value3$);
 661                 });
 662             }
 663 #end[AtomicAdd]
 664         }
 665     }
 666 }
 667