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