1 /*
   2  * Copyright (c) 2015, 2018, 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  * @bug 8154556
  27  * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAs$Type$
  28  * @run testng/othervm -Diters=20000                         VarHandleTestByteArrayAs$Type$
  29  * @run testng/othervm -Diters=20000 -XX:-TieredCompilation  VarHandleTestByteArrayAs$Type$
  30  */
  31 
  32 import org.testng.annotations.DataProvider;
  33 import org.testng.annotations.Test;
  34 
  35 import java.lang.invoke.MethodHandles;
  36 import java.lang.invoke.VarHandle;
  37 import java.nio.ByteBuffer;
  38 import java.nio.ByteOrder;
  39 import java.util.ArrayList;
  40 import java.util.Arrays;
  41 import java.util.EnumSet;
  42 import java.util.List;
  43 
  44 import static org.testng.Assert.*;
  45 
  46 public class VarHandleTestByteArrayAs$Type$ extends VarHandleBaseByteArrayTest {
  47     static final int SIZE = $BoxType$.BYTES;
  48 
  49     static final $type$ VALUE_1 = $value1$;
  50 
  51     static final $type$ VALUE_2 = $value2$;
  52 
  53     static final $type$ VALUE_3 = $value3$;
  54 
  55 
  56     @Override
  57     public void setupVarHandleSources() {
  58         // Combinations of VarHandle byte[] or ByteBuffer
  59         vhss = new ArrayList<>();
  60         for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) {
  61 
  62             ByteOrder bo = endianess == MemoryMode.BIG_ENDIAN
  63                     ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
  64             VarHandleSource aeh = new VarHandleSource(
  65                     MethodHandles.byteArrayViewVarHandle($type$[].class, bo),
  66                     endianess, MemoryMode.READ_WRITE);
  67             vhss.add(aeh);
  68 
  69             VarHandleSource bbh = new VarHandleSource(
  70                     MethodHandles.byteBufferViewVarHandle($type$[].class, bo),
  71                     endianess, MemoryMode.READ_WRITE);
  72             vhss.add(bbh);
  73         }
  74     }
  75 
  76 
  77     @Test(dataProvider = "varHandlesProvider")
  78     public void testIsAccessModeSupported(VarHandleSource vhs) {
  79         VarHandle vh = vhs.s;
  80 
  81         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET));
  82         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET));
  83 
  84         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_VOLATILE));
  85         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_VOLATILE));
  86         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_ACQUIRE));
  87         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_RELEASE));
  88         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_OPAQUE));
  89         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_OPAQUE));
  90 
  91 #if[CAS]
  92         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_SET));
  93         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE));
  94         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
  95         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
  96         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_PLAIN));
  97         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
  98         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
  99         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
 100         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
 101         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET_ACQUIRE));
 102         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET_RELEASE));
 103 #else[CAS]
 104         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_SET));
 105         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE));
 106         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
 107         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
 108         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_PLAIN));
 109         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
 110         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
 111         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
 112         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
 113         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET_ACQUIRE));
 114         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET_RELEASE));
 115 #end[CAS]
 116 
 117 #if[AtomicAdd]
 118         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
 119         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD_ACQUIRE));
 120         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD_RELEASE));
 121 #else[AtomicAdd]
 122         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
 123         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD_ACQUIRE));
 124         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD_RELEASE));
 125 #end[AtomicAdd]
 126 
 127 #if[Bitwise]
 128         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR));
 129         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR_ACQUIRE));
 130         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR_RELEASE));
 131         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND));
 132         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND_ACQUIRE));
 133         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND_RELEASE));
 134         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR));
 135         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_ACQUIRE));
 136         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_RELEASE));
 137 #else[Bitwise]
 138         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR));
 139         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR_ACQUIRE));
 140         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR_RELEASE));
 141         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND));
 142         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND_ACQUIRE));
 143         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND_RELEASE));
 144         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR));
 145         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_ACQUIRE));
 146         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_RELEASE));
 147 #end[Bitwise]
 148     }
 149 
 150     @Test(dataProvider = "typesProvider")
 151     public void testTypes(VarHandle vh, List<java.lang.Class<?>> pts) {
 152         assertEquals(vh.varType(), $type$.class);
 153 
 154         assertEquals(vh.coordinateTypes(), pts);
 155 
 156         testTypes(vh);
 157     }
 158 
 159 
 160     @DataProvider
 161     public Object[][] accessTestCaseProvider() throws Exception {
 162         List<AccessTestCase<?>> cases = new ArrayList<>();
 163 
 164         for (ByteArrayViewSource<?> bav : bavss) {
 165             for (VarHandleSource vh : vhss) {
 166                 if (vh.matches(bav)) {
 167                     if (bav instanceof ByteArraySource) {
 168                         ByteArraySource bas = (ByteArraySource) bav;
 169 
 170                         cases.add(new VarHandleSourceAccessTestCase(
 171                                 "read write", bav, vh, h -> testArrayReadWrite(bas, h),
 172                                 true));
 173                         cases.add(new VarHandleSourceAccessTestCase(
 174                                 "null array", bav, vh, h -> testArrayNPE(bas, h),
 175                                 false));
 176                         cases.add(new VarHandleSourceAccessTestCase(
 177                                 "unsupported", bav, vh, h -> testArrayUnsupported(bas, h),
 178                                 false));
 179                         cases.add(new VarHandleSourceAccessTestCase(
 180                                 "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bas, h),
 181                                 false));
 182                         cases.add(new VarHandleSourceAccessTestCase(
 183                                 "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bas, h),
 184                                 false));
 185                     }
 186                     else {
 187                         ByteBufferSource bbs = (ByteBufferSource) bav;
 188 
 189                         if (MemoryMode.READ_WRITE.isSet(bav.memoryModes)) {
 190                             cases.add(new VarHandleSourceAccessTestCase(
 191                                     "read write", bav, vh, h -> testArrayReadWrite(bbs, h),
 192                                     true));
 193                         }
 194                         else {
 195                             cases.add(new VarHandleSourceAccessTestCase(
 196                                     "read only", bav, vh, h -> testArrayReadOnly(bbs, h),
 197                                     true));
 198                         }
 199 
 200                         cases.add(new VarHandleSourceAccessTestCase(
 201                                 "null buffer", bav, vh, h -> testArrayNPE(bbs, h),
 202                                 false));
 203                         cases.add(new VarHandleSourceAccessTestCase(
 204                                 "unsupported", bav, vh, h -> testArrayUnsupported(bbs, h),
 205                                 false));
 206                         cases.add(new VarHandleSourceAccessTestCase(
 207                                 "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bbs, h),
 208                                 false));
 209                         cases.add(new VarHandleSourceAccessTestCase(
 210                                 "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bbs, h),
 211                                 false));
 212                     }
 213                 }
 214             }
 215         }
 216 
 217         // Work around issue with jtreg summary reporting which truncates
 218         // the String result of Object.toString to 30 characters, hence
 219         // the first dummy argument
 220         return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
 221     }
 222 
 223     @Test(dataProvider = "accessTestCaseProvider")
 224     public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
 225         T t = atc.get();
 226         int iters = atc.requiresLoop() ? ITERS : 1;
 227         for (int c = 0; c < iters; c++) {
 228             atc.testAccess(t);
 229         }
 230     }
 231 
 232 
 233     static void testArrayNPE(ByteArraySource bs, VarHandleSource vhs) {
 234         VarHandle vh = vhs.s;
 235         byte[] array = null;
 236         int ci = 1;
 237 
 238         checkNPE(() -> {
 239             $type$ x = ($type$) vh.get(array, ci);
 240         });
 241 
 242         checkNPE(() -> {
 243             vh.set(array, ci, VALUE_1);
 244         });
 245 
 246         checkNPE(() -> {
 247             $type$ x = ($type$) vh.getVolatile(array, ci);
 248         });
 249 
 250         checkNPE(() -> {
 251             $type$ x = ($type$) vh.getAcquire(array, ci);
 252         });
 253 
 254         checkNPE(() -> {
 255             $type$ x = ($type$) vh.getOpaque(array, ci);
 256         });
 257 
 258         checkNPE(() -> {
 259             vh.setVolatile(array, ci, VALUE_1);
 260         });
 261 
 262         checkNPE(() -> {
 263             vh.setRelease(array, ci, VALUE_1);
 264         });
 265 
 266         checkNPE(() -> {
 267             vh.setOpaque(array, ci, VALUE_1);
 268         });
 269 
 270 #if[CAS]
 271         checkNPE(() -> {
 272             boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
 273         });
 274 
 275         checkNPE(() -> {
 276             $type$ r = ($type$) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
 277         });
 278 
 279         checkNPE(() -> {
 280             $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
 281         });
 282 
 283         checkNPE(() -> {
 284             $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
 285         });
 286 
 287         checkNPE(() -> {
 288             boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
 289         });
 290 
 291         checkNPE(() -> {
 292             boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
 293         });
 294 
 295         checkNPE(() -> {
 296             boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
 297         });
 298 
 299         checkNPE(() -> {
 300             boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
 301         });
 302 
 303         checkNPE(() -> {
 304             $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
 305         });
 306 
 307         checkNPE(() -> {
 308             $type$ o = ($type$) vh.getAndSetAcquire(array, ci, VALUE_1);
 309         });
 310 
 311         checkNPE(() -> {
 312             $type$ o = ($type$) vh.getAndSetRelease(array, ci, VALUE_1);
 313         });
 314 #end[CAS]
 315 
 316 #if[AtomicAdd]
 317         checkNPE(() -> {
 318             $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
 319         });
 320 
 321         checkNPE(() -> {
 322             $type$ o = ($type$) vh.getAndAddAcquire(array, ci, VALUE_1);
 323         });
 324 
 325         checkNPE(() -> {
 326             $type$ o = ($type$) vh.getAndAddRelease(array, ci, VALUE_1);
 327         });
 328 #end[AtomicAdd]
 329 
 330 #if[Bitwise]
 331         checkNPE(() -> {
 332             $type$ o = ($type$) vh.getAndBitwiseOr(array, ci, VALUE_1);
 333         });
 334 
 335         checkNPE(() -> {
 336             $type$ o = ($type$) vh.getAndBitwiseOrAcquire(array, ci, VALUE_1);
 337         });
 338 
 339         checkNPE(() -> {
 340             $type$ o = ($type$) vh.getAndBitwiseOrRelease(array, ci, VALUE_1);
 341         });
 342 
 343         checkNPE(() -> {
 344             $type$ o = ($type$) vh.getAndBitwiseAnd(array, ci, VALUE_1);
 345         });
 346 
 347         checkNPE(() -> {
 348             $type$ o = ($type$) vh.getAndBitwiseAndAcquire(array, ci, VALUE_1);
 349         });
 350 
 351         checkNPE(() -> {
 352             $type$ o = ($type$) vh.getAndBitwiseAndRelease(array, ci, VALUE_1);
 353         });
 354 
 355         checkNPE(() -> {
 356             $type$ o = ($type$) vh.getAndBitwiseXor(array, ci, VALUE_1);
 357         });
 358 
 359         checkNPE(() -> {
 360             $type$ o = ($type$) vh.getAndBitwiseXorAcquire(array, ci, VALUE_1);
 361         });
 362 
 363         checkNPE(() -> {
 364             $type$ o = ($type$) vh.getAndBitwiseXorRelease(array, ci, VALUE_1);
 365         });
 366 #end[Bitwise]
 367     }
 368 
 369     static void testArrayNPE(ByteBufferSource bs, VarHandleSource vhs) {
 370         VarHandle vh = vhs.s;
 371         ByteBuffer array = null;
 372         int ci = 1;
 373 
 374         checkNPE(() -> {
 375             $type$ x = ($type$) vh.get(array, ci);
 376         });
 377 
 378         checkNPE(() -> {
 379             vh.set(array, ci, VALUE_1);
 380         });
 381 
 382         checkNPE(() -> {
 383             $type$ x = ($type$) vh.getVolatile(array, ci);
 384         });
 385 
 386         checkNPE(() -> {
 387             $type$ x = ($type$) vh.getAcquire(array, ci);
 388         });
 389 
 390         checkNPE(() -> {
 391             $type$ x = ($type$) vh.getOpaque(array, ci);
 392         });
 393 
 394         checkNPE(() -> {
 395             vh.setVolatile(array, ci, VALUE_1);
 396         });
 397 
 398         checkNPE(() -> {
 399             vh.setRelease(array, ci, VALUE_1);
 400         });
 401 
 402         checkNPE(() -> {
 403             vh.setOpaque(array, ci, VALUE_1);
 404         });
 405 
 406 #if[CAS]
 407         checkNPE(() -> {
 408             boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
 409         });
 410 
 411         checkNPE(() -> {
 412             $type$ r = ($type$) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
 413         });
 414 
 415         checkNPE(() -> {
 416             $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
 417         });
 418 
 419         checkNPE(() -> {
 420             $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
 421         });
 422 
 423         checkNPE(() -> {
 424             boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
 425         });
 426 
 427         checkNPE(() -> {
 428             boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
 429         });
 430 
 431         checkNPE(() -> {
 432             boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
 433         });
 434 
 435         checkNPE(() -> {
 436             boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
 437         });
 438 
 439         checkNPE(() -> {
 440             $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
 441         });
 442 
 443         checkNPE(() -> {
 444             $type$ o = ($type$) vh.getAndSetAcquire(array, ci, VALUE_1);
 445         });
 446 
 447         checkNPE(() -> {
 448             $type$ o = ($type$) vh.getAndSetRelease(array, ci, VALUE_1);
 449         });
 450 #end[CAS]
 451 
 452 #if[AtomicAdd]
 453         checkNPE(() -> {
 454             $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
 455         });
 456 
 457         checkNPE(() -> {
 458             $type$ o = ($type$) vh.getAndAddAcquire(array, ci, VALUE_1);
 459         });
 460 
 461         checkNPE(() -> {
 462             $type$ o = ($type$) vh.getAndAddRelease(array, ci, VALUE_1);
 463         });
 464 #end[AtomicAdd]
 465 
 466 #if[Bitwise]
 467         checkNPE(() -> {
 468             $type$ o = ($type$) vh.getAndBitwiseOr(array, ci, VALUE_1);
 469         });
 470 
 471         checkNPE(() -> {
 472             $type$ o = ($type$) vh.getAndBitwiseOrAcquire(array, ci, VALUE_1);
 473         });
 474 
 475         checkNPE(() -> {
 476             $type$ o = ($type$) vh.getAndBitwiseOrRelease(array, ci, VALUE_1);
 477         });
 478 
 479         checkNPE(() -> {
 480             $type$ o = ($type$) vh.getAndBitwiseAnd(array, ci, VALUE_1);
 481         });
 482 
 483         checkNPE(() -> {
 484             $type$ o = ($type$) vh.getAndBitwiseAndAcquire(array, ci, VALUE_1);
 485         });
 486 
 487         checkNPE(() -> {
 488             $type$ o = ($type$) vh.getAndBitwiseAndRelease(array, ci, VALUE_1);
 489         });
 490 
 491         checkNPE(() -> {
 492             $type$ o = ($type$) vh.getAndBitwiseXor(array, ci, VALUE_1);
 493         });
 494 
 495         checkNPE(() -> {
 496             $type$ o = ($type$) vh.getAndBitwiseXorAcquire(array, ci, VALUE_1);
 497         });
 498 
 499         checkNPE(() -> {
 500             $type$ o = ($type$) vh.getAndBitwiseXorRelease(array, ci, VALUE_1);
 501         });
 502 #end[Bitwise]
 503     }
 504 
 505     static void testArrayUnsupported(ByteArraySource bs, VarHandleSource vhs) {
 506         VarHandle vh = vhs.s;
 507         byte[] array = bs.s;
 508         int ci = 1;
 509 
 510 #if[!CAS]
 511         checkUOE(() -> {
 512             boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
 513         });
 514 
 515         checkUOE(() -> {
 516             $type$ r = ($type$) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
 517         });
 518 
 519         checkUOE(() -> {
 520             $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
 521         });
 522 
 523         checkUOE(() -> {
 524             $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
 525         });
 526 
 527         checkUOE(() -> {
 528             boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
 529         });
 530 
 531         checkUOE(() -> {
 532             boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
 533         });
 534 
 535         checkUOE(() -> {
 536             boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
 537         });
 538 
 539         checkUOE(() -> {
 540             boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
 541         });
 542 
 543         checkUOE(() -> {
 544             $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
 545         });
 546 
 547         checkUOE(() -> {
 548             $type$ o = ($type$) vh.getAndSetAcquire(array, ci, VALUE_1);
 549         });
 550 
 551         checkUOE(() -> {
 552             $type$ o = ($type$) vh.getAndSetRelease(array, ci, VALUE_1);
 553         });
 554 #end[CAS]
 555 
 556 #if[!AtomicAdd]
 557         checkUOE(() -> {
 558             $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
 559         });
 560 
 561         checkUOE(() -> {
 562             $type$ o = ($type$) vh.getAndAddAcquire(array, ci, VALUE_1);
 563         });
 564 
 565         checkUOE(() -> {
 566             $type$ o = ($type$) vh.getAndAddRelease(array, ci, VALUE_1);
 567         });
 568 #end[AtomicAdd]
 569 
 570 #if[!Bitwise]
 571         checkUOE(() -> {
 572             $type$ o = ($type$) vh.getAndBitwiseOr(array, ci, VALUE_1);
 573         });
 574 
 575         checkUOE(() -> {
 576             $type$ o = ($type$) vh.getAndBitwiseOrAcquire(array, ci, VALUE_1);
 577         });
 578 
 579         checkUOE(() -> {
 580             $type$ o = ($type$) vh.getAndBitwiseOrRelease(array, ci, VALUE_1);
 581         });
 582 
 583         checkUOE(() -> {
 584             $type$ o = ($type$) vh.getAndBitwiseAnd(array, ci, VALUE_1);
 585         });
 586 
 587         checkUOE(() -> {
 588             $type$ o = ($type$) vh.getAndBitwiseAndAcquire(array, ci, VALUE_1);
 589         });
 590 
 591         checkUOE(() -> {
 592             $type$ o = ($type$) vh.getAndBitwiseAndRelease(array, ci, VALUE_1);
 593         });
 594 
 595         checkUOE(() -> {
 596             $type$ o = ($type$) vh.getAndBitwiseXor(array, ci, VALUE_1);
 597         });
 598 
 599         checkUOE(() -> {
 600             $type$ o = ($type$) vh.getAndBitwiseXorAcquire(array, ci, VALUE_1);
 601         });
 602 
 603         checkUOE(() -> {
 604             $type$ o = ($type$) vh.getAndBitwiseXorRelease(array, ci, VALUE_1);
 605         });
 606 #end[Bitwise]
 607     }
 608 
 609     static void testArrayUnsupported(ByteBufferSource bs, VarHandleSource vhs) {
 610         VarHandle vh = vhs.s;
 611         ByteBuffer array = bs.s;
 612         int ci = 0;
 613         boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
 614 
 615         if (readOnly) {
 616             checkROBE(() -> {
 617                 vh.set(array, ci, VALUE_1);
 618             });
 619         }
 620 
 621         if (readOnly) {
 622             checkROBE(() -> {
 623                 vh.setVolatile(array, ci, VALUE_1);
 624             });
 625 
 626             checkROBE(() -> {
 627                 vh.setRelease(array, ci, VALUE_1);
 628             });
 629 
 630             checkROBE(() -> {
 631                 vh.setOpaque(array, ci, VALUE_1);
 632             });
 633 #if[CAS]
 634 
 635             checkROBE(() -> {
 636                 boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
 637             });
 638 
 639             checkROBE(() -> {
 640                 $type$ r = ($type$) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
 641             });
 642 
 643             checkROBE(() -> {
 644                 $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
 645             });
 646 
 647             checkROBE(() -> {
 648                 $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
 649             });
 650 
 651             checkROBE(() -> {
 652                 boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
 653             });
 654 
 655             checkROBE(() -> {
 656                 boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
 657             });
 658 
 659             checkROBE(() -> {
 660                 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
 661             });
 662 
 663             checkROBE(() -> {
 664                 boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
 665             });
 666 
 667             checkROBE(() -> {
 668                 $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
 669             });
 670 
 671             checkROBE(() -> {
 672                 $type$ o = ($type$) vh.getAndSetAcquire(array, ci, VALUE_1);
 673             });
 674 
 675             checkROBE(() -> {
 676                 $type$ o = ($type$) vh.getAndSetRelease(array, ci, VALUE_1);
 677             });
 678 
 679 #else[CAS]
 680             checkUOE(() -> {
 681                 boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
 682             });
 683 
 684             checkUOE(() -> {
 685                 $type$ r = ($type$) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
 686             });
 687 
 688             checkUOE(() -> {
 689                 $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
 690             });
 691 
 692             checkUOE(() -> {
 693                 $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
 694             });
 695 
 696             checkUOE(() -> {
 697                 boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
 698             });
 699 
 700             checkUOE(() -> {
 701                 boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
 702             });
 703 
 704             checkUOE(() -> {
 705                 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
 706             });
 707 
 708             checkUOE(() -> {
 709                 boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
 710             });
 711 
 712             checkUOE(() -> {
 713                 $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
 714             });
 715 
 716             checkUOE(() -> {
 717                 $type$ o = ($type$) vh.getAndSetAcquire(array, ci, VALUE_1);
 718             });
 719 
 720             checkUOE(() -> {
 721                 $type$ o = ($type$) vh.getAndSetRelease(array, ci, VALUE_1);
 722             });
 723 #end[CAS]
 724 
 725 #if[AtomicAdd]
 726             checkROBE(() -> {
 727                 $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
 728             });
 729 
 730             checkROBE(() -> {
 731                 $type$ o = ($type$) vh.getAndAddAcquire(array, ci, VALUE_1);
 732             });
 733 
 734             checkROBE(() -> {
 735                 $type$ o = ($type$) vh.getAndAddRelease(array, ci, VALUE_1);
 736             });
 737 #else[AtomicAdd]
 738             checkUOE(() -> {
 739                 $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
 740             });
 741 
 742             checkUOE(() -> {
 743                 $type$ o = ($type$) vh.getAndAddAcquire(array, ci, VALUE_1);
 744             });
 745 
 746             checkUOE(() -> {
 747                 $type$ o = ($type$) vh.getAndAddRelease(array, ci, VALUE_1);
 748             });
 749 #end[AtomicAdd]
 750 
 751 #if[Bitwise]
 752             checkROBE(() -> {
 753                 $type$ o = ($type$) vh.getAndBitwiseOr(array, ci, VALUE_1);
 754             });
 755 
 756             checkROBE(() -> {
 757                 $type$ o = ($type$) vh.getAndBitwiseOrAcquire(array, ci, VALUE_1);
 758             });
 759 
 760             checkROBE(() -> {
 761                 $type$ o = ($type$) vh.getAndBitwiseOrRelease(array, ci, VALUE_1);
 762             });
 763 
 764             checkROBE(() -> {
 765                 $type$ o = ($type$) vh.getAndBitwiseAnd(array, ci, VALUE_1);
 766             });
 767 
 768             checkROBE(() -> {
 769                 $type$ o = ($type$) vh.getAndBitwiseAndAcquire(array, ci, VALUE_1);
 770             });
 771 
 772             checkROBE(() -> {
 773                 $type$ o = ($type$) vh.getAndBitwiseAndRelease(array, ci, VALUE_1);
 774             });
 775 
 776             checkROBE(() -> {
 777                 $type$ o = ($type$) vh.getAndBitwiseXor(array, ci, VALUE_1);
 778             });
 779 
 780             checkROBE(() -> {
 781                 $type$ o = ($type$) vh.getAndBitwiseXorAcquire(array, ci, VALUE_1);
 782             });
 783 
 784             checkROBE(() -> {
 785                 $type$ o = ($type$) vh.getAndBitwiseXorRelease(array, ci, VALUE_1);
 786             });
 787 #else[Bitwise]
 788             checkUOE(() -> {
 789                 $type$ o = ($type$) vh.getAndBitwiseOr(array, ci, VALUE_1);
 790             });
 791 
 792             checkUOE(() -> {
 793                 $type$ o = ($type$) vh.getAndBitwiseOrAcquire(array, ci, VALUE_1);
 794             });
 795 
 796             checkUOE(() -> {
 797                 $type$ o = ($type$) vh.getAndBitwiseOrRelease(array, ci, VALUE_1);
 798             });
 799 
 800             checkUOE(() -> {
 801                 $type$ o = ($type$) vh.getAndBitwiseAnd(array, ci, VALUE_1);
 802             });
 803 
 804             checkUOE(() -> {
 805                 $type$ o = ($type$) vh.getAndBitwiseAndAcquire(array, ci, VALUE_1);
 806             });
 807 
 808             checkUOE(() -> {
 809                 $type$ o = ($type$) vh.getAndBitwiseAndRelease(array, ci, VALUE_1);
 810             });
 811 
 812             checkUOE(() -> {
 813                 $type$ o = ($type$) vh.getAndBitwiseXor(array, ci, VALUE_1);
 814             });
 815 
 816             checkUOE(() -> {
 817                 $type$ o = ($type$) vh.getAndBitwiseXorAcquire(array, ci, VALUE_1);
 818             });
 819 
 820             checkUOE(() -> {
 821                 $type$ o = ($type$) vh.getAndBitwiseXorRelease(array, ci, VALUE_1);
 822             });
 823 #end[Bitwise]
 824         }
 825         else {
 826 #if[!CAS]
 827             checkUOE(() -> {
 828                 boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
 829             });
 830 
 831             checkUOE(() -> {
 832                 $type$ r = ($type$) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
 833             });
 834 
 835             checkUOE(() -> {
 836                 $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
 837             });
 838 
 839             checkUOE(() -> {
 840                 $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
 841             });
 842 
 843             checkUOE(() -> {
 844                 boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
 845             });
 846 
 847             checkUOE(() -> {
 848                 boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
 849             });
 850 
 851             checkUOE(() -> {
 852                 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
 853             });
 854 
 855             checkUOE(() -> {
 856                 boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
 857             });
 858 
 859             checkUOE(() -> {
 860                 $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
 861             });
 862 
 863             checkUOE(() -> {
 864                 $type$ o = ($type$) vh.getAndSetAcquire(array, ci, VALUE_1);
 865             });
 866 
 867             checkUOE(() -> {
 868                 $type$ o = ($type$) vh.getAndSetRelease(array, ci, VALUE_1);
 869             });
 870 #end[CAS]
 871 #if[!AtomicAdd]
 872             checkUOE(() -> {
 873                 $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
 874             });
 875 
 876             checkUOE(() -> {
 877                 $type$ o = ($type$) vh.getAndAddAcquire(array, ci, VALUE_1);
 878             });
 879 
 880             checkUOE(() -> {
 881                 $type$ o = ($type$) vh.getAndAddRelease(array, ci, VALUE_1);
 882             });
 883 #end[AtomicAdd]
 884 #if[!Bitwise]
 885             checkUOE(() -> {
 886                 $type$ o = ($type$) vh.getAndBitwiseOr(array, ci, VALUE_1);
 887             });
 888 
 889             checkUOE(() -> {
 890                 $type$ o = ($type$) vh.getAndBitwiseOrAcquire(array, ci, VALUE_1);
 891             });
 892 
 893             checkUOE(() -> {
 894                 $type$ o = ($type$) vh.getAndBitwiseOrRelease(array, ci, VALUE_1);
 895             });
 896 
 897             checkUOE(() -> {
 898                 $type$ o = ($type$) vh.getAndBitwiseAnd(array, ci, VALUE_1);
 899             });
 900 
 901             checkUOE(() -> {
 902                 $type$ o = ($type$) vh.getAndBitwiseAndAcquire(array, ci, VALUE_1);
 903             });
 904 
 905             checkUOE(() -> {
 906                 $type$ o = ($type$) vh.getAndBitwiseAndRelease(array, ci, VALUE_1);
 907             });
 908 
 909             checkUOE(() -> {
 910                 $type$ o = ($type$) vh.getAndBitwiseXor(array, ci, VALUE_1);
 911             });
 912 
 913             checkUOE(() -> {
 914                 $type$ o = ($type$) vh.getAndBitwiseXorAcquire(array, ci, VALUE_1);
 915             });
 916 
 917             checkUOE(() -> {
 918                 $type$ o = ($type$) vh.getAndBitwiseXorRelease(array, ci, VALUE_1);
 919             });
 920 #end[Bitwise]
 921         }
 922     }
 923 
 924 
 925     static void testArrayIndexOutOfBounds(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
 926         VarHandle vh = vhs.s;
 927         byte[] array = bs.s;
 928 
 929         int length = array.length - SIZE + 1;
 930         for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
 931             final int ci = i;
 932 
 933             checkIOOBE(() -> {
 934                 $type$ x = ($type$) vh.get(array, ci);
 935             });
 936 
 937             checkIOOBE(() -> {
 938                 vh.set(array, ci, VALUE_1);
 939             });
 940 
 941             checkIOOBE(() -> {
 942                 $type$ x = ($type$) vh.getVolatile(array, ci);
 943             });
 944 
 945             checkIOOBE(() -> {
 946                 $type$ x = ($type$) vh.getAcquire(array, ci);
 947             });
 948 
 949             checkIOOBE(() -> {
 950                 $type$ x = ($type$) vh.getOpaque(array, ci);
 951             });
 952 
 953             checkIOOBE(() -> {
 954                 vh.setVolatile(array, ci, VALUE_1);
 955             });
 956 
 957             checkIOOBE(() -> {
 958                 vh.setRelease(array, ci, VALUE_1);
 959             });
 960 
 961             checkIOOBE(() -> {
 962                 vh.setOpaque(array, ci, VALUE_1);
 963             });
 964 #if[CAS]
 965 
 966             checkIOOBE(() -> {
 967                 boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
 968             });
 969 
 970             checkIOOBE(() -> {
 971                 $type$ r = ($type$) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
 972             });
 973 
 974             checkIOOBE(() -> {
 975                 $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
 976             });
 977 
 978             checkIOOBE(() -> {
 979                 $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
 980             });
 981 
 982             checkIOOBE(() -> {
 983                 boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
 984             });
 985 
 986             checkIOOBE(() -> {
 987                 boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
 988             });
 989 
 990             checkIOOBE(() -> {
 991                 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
 992             });
 993 
 994             checkIOOBE(() -> {
 995                 boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
 996             });
 997 
 998             checkIOOBE(() -> {
 999                 $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
1000             });
1001 
1002             checkIOOBE(() -> {
1003                 $type$ o = ($type$) vh.getAndSetAcquire(array, ci, VALUE_1);
1004             });
1005 
1006             checkIOOBE(() -> {
1007                 $type$ o = ($type$) vh.getAndSetRelease(array, ci, VALUE_1);
1008             });
1009 #end[CAS]
1010 
1011 #if[AtomicAdd]
1012             checkIOOBE(() -> {
1013                 $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
1014             });
1015 
1016             checkIOOBE(() -> {
1017                 $type$ o = ($type$) vh.getAndAddAcquire(array, ci, VALUE_1);
1018             });
1019 
1020             checkIOOBE(() -> {
1021                 $type$ o = ($type$) vh.getAndAddRelease(array, ci, VALUE_1);
1022             });
1023 #end[AtomicAdd]
1024 
1025 #if[Bitwise]
1026             checkIOOBE(() -> {
1027                 $type$ o = ($type$) vh.getAndBitwiseOr(array, ci, VALUE_1);
1028             });
1029 
1030             checkIOOBE(() -> {
1031                 $type$ o = ($type$) vh.getAndBitwiseOrAcquire(array, ci, VALUE_1);
1032             });
1033 
1034             checkIOOBE(() -> {
1035                 $type$ o = ($type$) vh.getAndBitwiseOrRelease(array, ci, VALUE_1);
1036             });
1037 
1038             checkIOOBE(() -> {
1039                 $type$ o = ($type$) vh.getAndBitwiseAnd(array, ci, VALUE_1);
1040             });
1041 
1042             checkIOOBE(() -> {
1043                 $type$ o = ($type$) vh.getAndBitwiseAndAcquire(array, ci, VALUE_1);
1044             });
1045 
1046             checkIOOBE(() -> {
1047                 $type$ o = ($type$) vh.getAndBitwiseAndRelease(array, ci, VALUE_1);
1048             });
1049 
1050             checkIOOBE(() -> {
1051                 $type$ o = ($type$) vh.getAndBitwiseXor(array, ci, VALUE_1);
1052             });
1053 
1054             checkIOOBE(() -> {
1055                 $type$ o = ($type$) vh.getAndBitwiseXorAcquire(array, ci, VALUE_1);
1056             });
1057 
1058             checkIOOBE(() -> {
1059                 $type$ o = ($type$) vh.getAndBitwiseXorRelease(array, ci, VALUE_1);
1060             });
1061 #end[Bitwise]
1062 
1063         }
1064     }
1065 
1066     static void testArrayIndexOutOfBounds(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
1067         VarHandle vh = vhs.s;
1068         ByteBuffer array = bs.s;
1069 
1070         boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
1071 
1072         int length = array.limit() - SIZE + 1;
1073         for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
1074             final int ci = i;
1075 
1076             checkIOOBE(() -> {
1077                 $type$ x = ($type$) vh.get(array, ci);
1078             });
1079 
1080             if (!readOnly) {
1081                 checkIOOBE(() -> {
1082                     vh.set(array, ci, VALUE_1);
1083                 });
1084             }
1085 
1086             checkIOOBE(() -> {
1087                 $type$ x = ($type$) vh.getVolatile(array, ci);
1088             });
1089 
1090             checkIOOBE(() -> {
1091                 $type$ x = ($type$) vh.getAcquire(array, ci);
1092             });
1093 
1094             checkIOOBE(() -> {
1095                 $type$ x = ($type$) vh.getOpaque(array, ci);
1096             });
1097 
1098             if (!readOnly) {
1099                 checkIOOBE(() -> {
1100                     vh.setVolatile(array, ci, VALUE_1);
1101                 });
1102 
1103                 checkIOOBE(() -> {
1104                     vh.setRelease(array, ci, VALUE_1);
1105                 });
1106 
1107                 checkIOOBE(() -> {
1108                     vh.setOpaque(array, ci, VALUE_1);
1109                 });
1110 
1111 #if[CAS]
1112                 checkIOOBE(() -> {
1113                     boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
1114                 });
1115 
1116                 checkIOOBE(() -> {
1117                     $type$ r = ($type$) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
1118                 });
1119 
1120                 checkIOOBE(() -> {
1121                     $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
1122                 });
1123 
1124                 checkIOOBE(() -> {
1125                     $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
1126                 });
1127 
1128                 checkIOOBE(() -> {
1129                     boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
1130                 });
1131 
1132                 checkIOOBE(() -> {
1133                     boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
1134                 });
1135 
1136                 checkIOOBE(() -> {
1137                     boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
1138                 });
1139 
1140                 checkIOOBE(() -> {
1141                     boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
1142                 });
1143 
1144                 checkIOOBE(() -> {
1145                     $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
1146                 });
1147 
1148                 checkIOOBE(() -> {
1149                     $type$ o = ($type$) vh.getAndSetAcquire(array, ci, VALUE_1);
1150                 });
1151 
1152                 checkIOOBE(() -> {
1153                     $type$ o = ($type$) vh.getAndSetRelease(array, ci, VALUE_1);
1154                 });
1155 #end[CAS]
1156 
1157 #if[AtomicAdd]
1158                 checkIOOBE(() -> {
1159                     $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
1160                 });
1161 
1162                 checkIOOBE(() -> {
1163                     $type$ o = ($type$) vh.getAndAddAcquire(array, ci, VALUE_1);
1164                 });
1165 
1166                 checkIOOBE(() -> {
1167                     $type$ o = ($type$) vh.getAndAddRelease(array, ci, VALUE_1);
1168                 });
1169 #end[AtomicAdd]
1170 
1171 #if[Bitwise]
1172                 checkIOOBE(() -> {
1173                     $type$ o = ($type$) vh.getAndBitwiseOr(array, ci, VALUE_1);
1174                 });
1175 
1176                 checkIOOBE(() -> {
1177                     $type$ o = ($type$) vh.getAndBitwiseOrAcquire(array, ci, VALUE_1);
1178                 });
1179 
1180                 checkIOOBE(() -> {
1181                     $type$ o = ($type$) vh.getAndBitwiseOrRelease(array, ci, VALUE_1);
1182                 });
1183 
1184                 checkIOOBE(() -> {
1185                     $type$ o = ($type$) vh.getAndBitwiseAnd(array, ci, VALUE_1);
1186                 });
1187 
1188                 checkIOOBE(() -> {
1189                     $type$ o = ($type$) vh.getAndBitwiseAndAcquire(array, ci, VALUE_1);
1190                 });
1191 
1192                 checkIOOBE(() -> {
1193                     $type$ o = ($type$) vh.getAndBitwiseAndRelease(array, ci, VALUE_1);
1194                 });
1195 
1196                 checkIOOBE(() -> {
1197                     $type$ o = ($type$) vh.getAndBitwiseXor(array, ci, VALUE_1);
1198                 });
1199 
1200                 checkIOOBE(() -> {
1201                     $type$ o = ($type$) vh.getAndBitwiseXorAcquire(array, ci, VALUE_1);
1202                 });
1203 
1204                 checkIOOBE(() -> {
1205                     $type$ o = ($type$) vh.getAndBitwiseXorRelease(array, ci, VALUE_1);
1206                 });
1207 #end[Bitwise]
1208             }
1209         }
1210     }
1211 
1212     static void testArrayMisalignedAccess(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
1213         VarHandle vh = vhs.s;
1214         byte[] array = bs.s;
1215 
1216         int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
1217 
1218         int length = array.length - SIZE + 1;
1219         for (int i = 0; i < length; i++) {
1220             boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
1221             final int ci = i;
1222 
1223             if (!iAligned) {
1224                 checkISE(() -> {
1225                     $type$ x = ($type$) vh.getVolatile(array, ci);
1226                 });
1227 
1228                 checkISE(() -> {
1229                     $type$ x = ($type$) vh.getAcquire(array, ci);
1230                 });
1231 
1232                 checkISE(() -> {
1233                     $type$ x = ($type$) vh.getOpaque(array, ci);
1234                 });
1235 
1236                 checkISE(() -> {
1237                     vh.setVolatile(array, ci, VALUE_1);
1238                 });
1239 
1240                 checkISE(() -> {
1241                     vh.setRelease(array, ci, VALUE_1);
1242                 });
1243 
1244                 checkISE(() -> {
1245                     vh.setOpaque(array, ci, VALUE_1);
1246                 });
1247 #if[CAS]
1248 
1249                 checkISE(() -> {
1250                     boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
1251                 });
1252 
1253                 checkISE(() -> {
1254                     $type$ r = ($type$) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
1255                 });
1256 
1257                 checkISE(() -> {
1258                     $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
1259                 });
1260 
1261                 checkISE(() -> {
1262                     $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
1263                 });
1264 
1265                 checkISE(() -> {
1266                     boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
1267                 });
1268 
1269                 checkISE(() -> {
1270                     boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
1271                 });
1272 
1273                 checkISE(() -> {
1274                     boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
1275                 });
1276 
1277                 checkISE(() -> {
1278                     boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
1279                 });
1280 
1281                 checkISE(() -> {
1282                     $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
1283                 });
1284 
1285                 checkISE(() -> {
1286                     $type$ o = ($type$) vh.getAndSetAcquire(array, ci, VALUE_1);
1287                 });
1288 
1289                 checkISE(() -> {
1290                     $type$ o = ($type$) vh.getAndSetRelease(array, ci, VALUE_1);
1291                 });
1292 #end[CAS]
1293 
1294 #if[AtomicAdd]
1295                 checkISE(() -> {
1296                     $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
1297                 });
1298 
1299                 checkISE(() -> {
1300                     $type$ o = ($type$) vh.getAndAddAcquire(array, ci, VALUE_1);
1301                 });
1302 
1303                 checkISE(() -> {
1304                     $type$ o = ($type$) vh.getAndAddRelease(array, ci, VALUE_1);
1305                 });
1306 #end[AtomicAdd]
1307 
1308 #if[Bitwise]
1309                 checkISE(() -> {
1310                     $type$ o = ($type$) vh.getAndBitwiseOr(array, ci, VALUE_1);
1311                 });
1312 
1313                 checkISE(() -> {
1314                     $type$ o = ($type$) vh.getAndBitwiseOrAcquire(array, ci, VALUE_1);
1315                 });
1316 
1317                 checkISE(() -> {
1318                     $type$ o = ($type$) vh.getAndBitwiseOrRelease(array, ci, VALUE_1);
1319                 });
1320 
1321                 checkISE(() -> {
1322                     $type$ o = ($type$) vh.getAndBitwiseAnd(array, ci, VALUE_1);
1323                 });
1324 
1325                 checkISE(() -> {
1326                     $type$ o = ($type$) vh.getAndBitwiseAndAcquire(array, ci, VALUE_1);
1327                 });
1328 
1329                 checkISE(() -> {
1330                     $type$ o = ($type$) vh.getAndBitwiseAndRelease(array, ci, VALUE_1);
1331                 });
1332 
1333                 checkISE(() -> {
1334                     $type$ o = ($type$) vh.getAndBitwiseXor(array, ci, VALUE_1);
1335                 });
1336 
1337                 checkISE(() -> {
1338                     $type$ o = ($type$) vh.getAndBitwiseXorAcquire(array, ci, VALUE_1);
1339                 });
1340 
1341                 checkISE(() -> {
1342                     $type$ o = ($type$) vh.getAndBitwiseXorRelease(array, ci, VALUE_1);
1343                 });
1344 #end[Bitwise]
1345             }
1346         }
1347     }
1348 
1349     static void testArrayMisalignedAccess(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
1350         VarHandle vh = vhs.s;
1351         ByteBuffer array = bs.s;
1352 
1353         boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
1354         int misalignmentAtZero = array.alignmentOffset(0, SIZE);
1355 
1356         int length = array.limit() - SIZE + 1;
1357         for (int i = 0; i < length; i++) {
1358             boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
1359             final int ci = i;
1360 
1361             if (!iAligned) {
1362                 checkISE(() -> {
1363                     $type$ x = ($type$) vh.getVolatile(array, ci);
1364                 });
1365 
1366                 checkISE(() -> {
1367                     $type$ x = ($type$) vh.getAcquire(array, ci);
1368                 });
1369 
1370                 checkISE(() -> {
1371                     $type$ x = ($type$) vh.getOpaque(array, ci);
1372                 });
1373 
1374                 if (!readOnly) {
1375                     checkISE(() -> {
1376                         vh.setVolatile(array, ci, VALUE_1);
1377                     });
1378 
1379                     checkISE(() -> {
1380                         vh.setRelease(array, ci, VALUE_1);
1381                     });
1382 
1383                     checkISE(() -> {
1384                         vh.setOpaque(array, ci, VALUE_1);
1385                     });
1386 
1387 #if[CAS]
1388                     checkISE(() -> {
1389                         boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
1390                     });
1391 
1392                     checkISE(() -> {
1393                         $type$ r = ($type$) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
1394                     });
1395 
1396                     checkISE(() -> {
1397                         $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
1398                     });
1399 
1400                     checkISE(() -> {
1401                         $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
1402                     });
1403 
1404                     checkISE(() -> {
1405                         boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
1406                     });
1407 
1408                     checkISE(() -> {
1409                         boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
1410                     });
1411 
1412                     checkISE(() -> {
1413                         boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
1414                     });
1415 
1416                     checkISE(() -> {
1417                         boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
1418                     });
1419 
1420                     checkISE(() -> {
1421                         $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
1422                     });
1423 
1424                     checkISE(() -> {
1425                         $type$ o = ($type$) vh.getAndSetAcquire(array, ci, VALUE_1);
1426                     });
1427 
1428                     checkISE(() -> {
1429                         $type$ o = ($type$) vh.getAndSetRelease(array, ci, VALUE_1);
1430                     });
1431 #end[CAS]
1432 
1433 #if[AtomicAdd]
1434                     checkISE(() -> {
1435                         $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
1436                     });
1437 
1438                     checkISE(() -> {
1439                         $type$ o = ($type$) vh.getAndAddAcquire(array, ci, VALUE_1);
1440                     });
1441 
1442                     checkISE(() -> {
1443                         $type$ o = ($type$) vh.getAndAddRelease(array, ci, VALUE_1);
1444                     });
1445 #end[AtomicAdd]
1446 
1447 #if[Bitwise]
1448                     checkISE(() -> {
1449                         $type$ o = ($type$) vh.getAndBitwiseOr(array, ci, VALUE_1);
1450                     });
1451 
1452                     checkISE(() -> {
1453                         $type$ o = ($type$) vh.getAndBitwiseOrAcquire(array, ci, VALUE_1);
1454                     });
1455 
1456                     checkISE(() -> {
1457                         $type$ o = ($type$) vh.getAndBitwiseOrRelease(array, ci, VALUE_1);
1458                     });
1459 
1460                     checkISE(() -> {
1461                         $type$ o = ($type$) vh.getAndBitwiseAnd(array, ci, VALUE_1);
1462                     });
1463 
1464                     checkISE(() -> {
1465                         $type$ o = ($type$) vh.getAndBitwiseAndAcquire(array, ci, VALUE_1);
1466                     });
1467 
1468                     checkISE(() -> {
1469                         $type$ o = ($type$) vh.getAndBitwiseAndRelease(array, ci, VALUE_1);
1470                     });
1471 
1472                     checkISE(() -> {
1473                         $type$ o = ($type$) vh.getAndBitwiseXor(array, ci, VALUE_1);
1474                     });
1475 
1476                     checkISE(() -> {
1477                         $type$ o = ($type$) vh.getAndBitwiseXorAcquire(array, ci, VALUE_1);
1478                     });
1479 
1480                     checkISE(() -> {
1481                         $type$ o = ($type$) vh.getAndBitwiseXorRelease(array, ci, VALUE_1);
1482                     });
1483 #end[Bitwise]
1484                 }
1485             }
1486         }
1487     }
1488 
1489     static void testArrayReadWrite(ByteArraySource bs, VarHandleSource vhs) {
1490         VarHandle vh = vhs.s;
1491         byte[] array = bs.s;
1492 
1493         int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
1494 
1495         bs.fill((byte) 0xff);
1496         int length = array.length - SIZE + 1;
1497         for (int i = 0; i < length; i++) {
1498             boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
1499 
1500             // Plain
1501             {
1502                 vh.set(array, i, VALUE_1);
1503                 $type$ x = ($type$) vh.get(array, i);
1504                 assertEquals(x, VALUE_1, "get $type$ value");
1505             }
1506 
1507 
1508             if (iAligned) {
1509                 // Volatile
1510                 {
1511                     vh.setVolatile(array, i, VALUE_2);
1512                     $type$ x = ($type$) vh.getVolatile(array, i);
1513                     assertEquals(x, VALUE_2, "setVolatile $type$ value");
1514                 }
1515 
1516                 // Lazy
1517                 {
1518                     vh.setRelease(array, i, VALUE_1);
1519                     $type$ x = ($type$) vh.getAcquire(array, i);
1520                     assertEquals(x, VALUE_1, "setRelease $type$ value");
1521                 }
1522 
1523                 // Opaque
1524                 {
1525                     vh.setOpaque(array, i, VALUE_2);
1526                     $type$ x = ($type$) vh.getOpaque(array, i);
1527                     assertEquals(x, VALUE_2, "setOpaque $type$ value");
1528                 }
1529 #if[CAS]
1530 
1531                 vh.set(array, i, VALUE_1);
1532 
1533                 // Compare
1534                 {
1535                     boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2);
1536                     assertEquals(r, true, "success compareAndSet $type$");
1537                     $type$ x = ($type$) vh.get(array, i);
1538                     assertEquals(x, VALUE_2, "success compareAndSet $type$ value");
1539                 }
1540 
1541                 {
1542                     boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3);
1543                     assertEquals(r, false, "failing compareAndSet $type$");
1544                     $type$ x = ($type$) vh.get(array, i);
1545                     assertEquals(x, VALUE_2, "failing compareAndSet $type$ value");
1546                 }
1547 
1548                 {
1549                     $type$ r = ($type$) vh.compareAndExchange(array, i, VALUE_2, VALUE_1);
1550                     assertEquals(r, VALUE_2, "success compareAndExchange $type$");
1551                     $type$ x = ($type$) vh.get(array, i);
1552                     assertEquals(x, VALUE_1, "success compareAndExchange $type$ value");
1553                 }
1554 
1555                 {
1556                     $type$ r = ($type$) vh.compareAndExchange(array, i, VALUE_2, VALUE_3);
1557                     assertEquals(r, VALUE_1, "failing compareAndExchange $type$");
1558                     $type$ x = ($type$) vh.get(array, i);
1559                     assertEquals(x, VALUE_1, "failing compareAndExchange $type$ value");
1560                 }
1561 
1562                 {
1563                     $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2);
1564                     assertEquals(r, VALUE_1, "success compareAndExchangeAcquire $type$");
1565                     $type$ x = ($type$) vh.get(array, i);
1566                     assertEquals(x, VALUE_2, "success compareAndExchangeAcquire $type$ value");
1567                 }
1568 
1569                 {
1570                     $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3);
1571                     assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire $type$");
1572                     $type$ x = ($type$) vh.get(array, i);
1573                     assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire $type$ value");
1574                 }
1575 
1576                 {
1577                     $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1);
1578                     assertEquals(r, VALUE_2, "success compareAndExchangeRelease $type$");
1579                     $type$ x = ($type$) vh.get(array, i);
1580                     assertEquals(x, VALUE_1, "success compareAndExchangeRelease $type$ value");
1581                 }
1582 
1583                 {
1584                     $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3);
1585                     assertEquals(r, VALUE_1, "failing compareAndExchangeRelease $type$");
1586                     $type$ x = ($type$) vh.get(array, i);
1587                     assertEquals(x, VALUE_1, "failing compareAndExchangeRelease $type$ value");
1588                 }
1589 
1590                 {
1591                     boolean success = false;
1592                     for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
1593                         success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_2);
1594                     }
1595                     assertEquals(success, true, "weakCompareAndSetPlain $type$");
1596                     $type$ x = ($type$) vh.get(array, i);
1597                     assertEquals(x, VALUE_2, "weakCompareAndSetPlain $type$ value");
1598                 }
1599 
1600                 {
1601                     boolean success = false;
1602                     for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
1603                         success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1);
1604                     }
1605                     assertEquals(success, true, "weakCompareAndSetAcquire $type$");
1606                     $type$ x = ($type$) vh.get(array, i);
1607                     assertEquals(x, VALUE_1, "weakCompareAndSetAcquire $type$");
1608                 }
1609 
1610                 {
1611                     boolean success = false;
1612                     for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
1613                         success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2);
1614                     }
1615                     assertEquals(success, true, "weakCompareAndSetRelease $type$");
1616                     $type$ x = ($type$) vh.get(array, i);
1617                     assertEquals(x, VALUE_2, "weakCompareAndSetRelease $type$");
1618                 }
1619 
1620                 {
1621                     boolean success = false;
1622                     for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
1623                         success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_1);
1624                     }
1625                     assertEquals(success, true, "weakCompareAndSet $type$");
1626                     $type$ x = ($type$) vh.get(array, i);
1627                     assertEquals(x, VALUE_1, "weakCompareAndSet $type$");
1628                 }
1629 
1630                 // Compare set and get
1631                 {
1632                     vh.set(array, i, VALUE_1);
1633 
1634                     $type$ o = ($type$) vh.getAndSet(array, i, VALUE_2);
1635                     assertEquals(o, VALUE_1, "getAndSet $type$");
1636                     $type$ x = ($type$) vh.get(array, i);
1637                     assertEquals(x, VALUE_2, "getAndSet $type$ value");
1638                 }
1639 
1640                 {
1641                     vh.set(array, i, VALUE_1);
1642 
1643                     $type$ o = ($type$) vh.getAndSetAcquire(array, i, VALUE_2);
1644                     assertEquals(o, VALUE_1, "getAndSetAcquire $type$");
1645                     $type$ x = ($type$) vh.get(array, i);
1646                     assertEquals(x, VALUE_2, "getAndSetAcquire $type$ value");
1647                 }
1648 
1649                 {
1650                     vh.set(array, i, VALUE_1);
1651 
1652                     $type$ o = ($type$) vh.getAndSetRelease(array, i, VALUE_2);
1653                     assertEquals(o, VALUE_1, "getAndSetRelease $type$");
1654                     $type$ x = ($type$) vh.get(array, i);
1655                     assertEquals(x, VALUE_2, "getAndSetRelease $type$ value");
1656                 }
1657 #end[CAS]
1658 
1659 #if[AtomicAdd]
1660                 // get and add, add and get
1661                 {
1662                     vh.set(array, i, VALUE_1);
1663 
1664                     $type$ o = ($type$) vh.getAndAdd(array, i, VALUE_2);
1665                     assertEquals(o, VALUE_1, "getAndAdd $type$");
1666                     $type$ x = ($type$) vh.get(array, i);
1667                     assertEquals(x, VALUE_1 + VALUE_2, "getAndAdd $type$ value");
1668                 }
1669 
1670                 {
1671                     vh.set(array, i, VALUE_1);
1672 
1673                     $type$ o = ($type$) vh.getAndAddAcquire(array, i, VALUE_2);
1674                     assertEquals(o, VALUE_1, "getAndAddAcquire $type$");
1675                     $type$ x = ($type$) vh.get(array, i);
1676                     assertEquals(x, VALUE_1 + VALUE_2, "getAndAddAcquire $type$ value");
1677                 }
1678 
1679                 {
1680                     vh.set(array, i, VALUE_1);
1681 
1682                     $type$ o = ($type$) vh.getAndAddRelease(array, i, VALUE_2);
1683                     assertEquals(o, VALUE_1, "getAndAddRelease $type$");
1684                     $type$ x = ($type$) vh.get(array, i);
1685                     assertEquals(x, VALUE_1 + VALUE_2, "getAndAddRelease $type$ value");
1686                 }
1687 #end[AtomicAdd]
1688 
1689 #if[Bitwise]
1690                 // get and bitwise or
1691                 {
1692                     vh.set(array, i, VALUE_1);
1693 
1694                     $type$ o = ($type$) vh.getAndBitwiseOr(array, i, VALUE_2);
1695                     assertEquals(o, VALUE_1, "getAndBitwiseOr $type$");
1696                     $type$ x = ($type$) vh.get(array, i);
1697                     assertEquals(x, VALUE_1 | VALUE_2, "getAndBitwiseOr $type$ value");
1698                 }
1699 
1700                 {
1701                     vh.set(array, i, VALUE_1);
1702 
1703                     $type$ o = ($type$) vh.getAndBitwiseOrAcquire(array, i, VALUE_2);
1704                     assertEquals(o, VALUE_1, "getAndBitwiseOrAcquire $type$");
1705                     $type$ x = ($type$) vh.get(array, i);
1706                     assertEquals(x, VALUE_1 | VALUE_2, "getAndBitwiseOrAcquire $type$ value");
1707                 }
1708 
1709                 {
1710                     vh.set(array, i, VALUE_1);
1711 
1712                     $type$ o = ($type$) vh.getAndBitwiseOrRelease(array, i, VALUE_2);
1713                     assertEquals(o, VALUE_1, "getAndBitwiseOrRelease $type$");
1714                     $type$ x = ($type$) vh.get(array, i);
1715                     assertEquals(x, VALUE_1 | VALUE_2, "getAndBitwiseOrRelease $type$ value");
1716                 }
1717 
1718                 // get and bitwise and
1719                 {
1720                     vh.set(array, i, VALUE_1);
1721 
1722                     $type$ o = ($type$) vh.getAndBitwiseAnd(array, i, VALUE_2);
1723                     assertEquals(o, VALUE_1, "getAndBitwiseAnd $type$");
1724                     $type$ x = ($type$) vh.get(array, i);
1725                     assertEquals(x, VALUE_1 & VALUE_2, "getAndBitwiseAnd $type$ value");
1726                 }
1727 
1728                 {
1729                     vh.set(array, i, VALUE_1);
1730 
1731                     $type$ o = ($type$) vh.getAndBitwiseAndAcquire(array, i, VALUE_2);
1732                     assertEquals(o, VALUE_1, "getAndBitwiseAndAcquire $type$");
1733                     $type$ x = ($type$) vh.get(array, i);
1734                     assertEquals(x, VALUE_1 & VALUE_2, "getAndBitwiseAndAcquire $type$ value");
1735                 }
1736 
1737                 {
1738                     vh.set(array, i, VALUE_1);
1739 
1740                     $type$ o = ($type$) vh.getAndBitwiseAndRelease(array, i, VALUE_2);
1741                     assertEquals(o, VALUE_1, "getAndBitwiseAndRelease $type$");
1742                     $type$ x = ($type$) vh.get(array, i);
1743                     assertEquals(x, VALUE_1 & VALUE_2, "getAndBitwiseAndRelease $type$ value");
1744                 }
1745 
1746                 // get and bitwise xor
1747                 {
1748                     vh.set(array, i, VALUE_1);
1749 
1750                     $type$ o = ($type$) vh.getAndBitwiseXor(array, i, VALUE_2);
1751                     assertEquals(o, VALUE_1, "getAndBitwiseXor $type$");
1752                     $type$ x = ($type$) vh.get(array, i);
1753                     assertEquals(x, VALUE_1 ^ VALUE_2, "getAndBitwiseXor $type$ value");
1754                 }
1755 
1756                 {
1757                     vh.set(array, i, VALUE_1);
1758 
1759                     $type$ o = ($type$) vh.getAndBitwiseXorAcquire(array, i, VALUE_2);
1760                     assertEquals(o, VALUE_1, "getAndBitwiseXorAcquire $type$");
1761                     $type$ x = ($type$) vh.get(array, i);
1762                     assertEquals(x, VALUE_1 ^ VALUE_2, "getAndBitwiseXorAcquire $type$ value");
1763                 }
1764 
1765                 {
1766                     vh.set(array, i, VALUE_1);
1767 
1768                     $type$ o = ($type$) vh.getAndBitwiseXorRelease(array, i, VALUE_2);
1769                     assertEquals(o, VALUE_1, "getAndBitwiseXorRelease $type$");
1770                     $type$ x = ($type$) vh.get(array, i);
1771                     assertEquals(x, VALUE_1 ^ VALUE_2, "getAndBitwiseXorRelease $type$ value");
1772                 }
1773 #end[Bitwise]
1774             }
1775         }
1776     }
1777 
1778 
1779     static void testArrayReadWrite(ByteBufferSource bs, VarHandleSource vhs) {
1780         VarHandle vh = vhs.s;
1781         ByteBuffer array = bs.s;
1782 
1783         int misalignmentAtZero = array.alignmentOffset(0, SIZE);
1784 
1785         bs.fill((byte) 0xff);
1786         int length = array.limit() - SIZE + 1;
1787         for (int i = 0; i < length; i++) {
1788             boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
1789 
1790             // Plain
1791             {
1792                 vh.set(array, i, VALUE_1);
1793                 $type$ x = ($type$) vh.get(array, i);
1794                 assertEquals(x, VALUE_1, "get $type$ value");
1795             }
1796 
1797             if (iAligned) {
1798                 // Volatile
1799                 {
1800                     vh.setVolatile(array, i, VALUE_2);
1801                     $type$ x = ($type$) vh.getVolatile(array, i);
1802                     assertEquals(x, VALUE_2, "setVolatile $type$ value");
1803                 }
1804 
1805                 // Lazy
1806                 {
1807                     vh.setRelease(array, i, VALUE_1);
1808                     $type$ x = ($type$) vh.getAcquire(array, i);
1809                     assertEquals(x, VALUE_1, "setRelease $type$ value");
1810                 }
1811 
1812                 // Opaque
1813                 {
1814                     vh.setOpaque(array, i, VALUE_2);
1815                     $type$ x = ($type$) vh.getOpaque(array, i);
1816                     assertEquals(x, VALUE_2, "setOpaque $type$ value");
1817                 }
1818 #if[CAS]
1819 
1820                 vh.set(array, i, VALUE_1);
1821 
1822                 // Compare
1823                 {
1824                     boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2);
1825                     assertEquals(r, true, "success compareAndSet $type$");
1826                     $type$ x = ($type$) vh.get(array, i);
1827                     assertEquals(x, VALUE_2, "success compareAndSet $type$ value");
1828                 }
1829 
1830                 {
1831                     boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3);
1832                     assertEquals(r, false, "failing compareAndSet $type$");
1833                     $type$ x = ($type$) vh.get(array, i);
1834                     assertEquals(x, VALUE_2, "failing compareAndSet $type$ value");
1835                 }
1836 
1837                 {
1838                     $type$ r = ($type$) vh.compareAndExchange(array, i, VALUE_2, VALUE_1);
1839                     assertEquals(r, VALUE_2, "success compareAndExchange $type$");
1840                     $type$ x = ($type$) vh.get(array, i);
1841                     assertEquals(x, VALUE_1, "success compareAndExchange $type$ value");
1842                 }
1843 
1844                 {
1845                     $type$ r = ($type$) vh.compareAndExchange(array, i, VALUE_2, VALUE_3);
1846                     assertEquals(r, VALUE_1, "failing compareAndExchange $type$");
1847                     $type$ x = ($type$) vh.get(array, i);
1848                     assertEquals(x, VALUE_1, "failing compareAndExchange $type$ value");
1849                 }
1850 
1851                 {
1852                     $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2);
1853                     assertEquals(r, VALUE_1, "success compareAndExchangeAcquire $type$");
1854                     $type$ x = ($type$) vh.get(array, i);
1855                     assertEquals(x, VALUE_2, "success compareAndExchangeAcquire $type$ value");
1856                 }
1857 
1858                 {
1859                     $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3);
1860                     assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire $type$");
1861                     $type$ x = ($type$) vh.get(array, i);
1862                     assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire $type$ value");
1863                 }
1864 
1865                 {
1866                     $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1);
1867                     assertEquals(r, VALUE_2, "success compareAndExchangeRelease $type$");
1868                     $type$ x = ($type$) vh.get(array, i);
1869                     assertEquals(x, VALUE_1, "success compareAndExchangeRelease $type$ value");
1870                 }
1871 
1872                 {
1873                     $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3);
1874                     assertEquals(r, VALUE_1, "failing compareAndExchangeRelease $type$");
1875                     $type$ x = ($type$) vh.get(array, i);
1876                     assertEquals(x, VALUE_1, "failing compareAndExchangeRelease $type$ value");
1877                 }
1878 
1879                 {
1880                     boolean success = false;
1881                     for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
1882                         success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_2);
1883                     }
1884                     assertEquals(success, true, "weakCompareAndSetPlain $type$");
1885                     $type$ x = ($type$) vh.get(array, i);
1886                     assertEquals(x, VALUE_2, "weakCompareAndSetPlain $type$ value");
1887                 }
1888 
1889                 {
1890                     boolean success = false;
1891                     for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
1892                         success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1);
1893                     }
1894                     assertEquals(success, true, "weakCompareAndSetAcquire $type$");
1895                     $type$ x = ($type$) vh.get(array, i);
1896                     assertEquals(x, VALUE_1, "weakCompareAndSetAcquire $type$");
1897                 }
1898 
1899                 {
1900                     boolean success = false;
1901                     for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
1902                         success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2);
1903                     }
1904                     assertEquals(success, true, "weakCompareAndSetRelease $type$");
1905                     $type$ x = ($type$) vh.get(array, i);
1906                     assertEquals(x, VALUE_2, "weakCompareAndSetRelease $type$");
1907                 }
1908 
1909                 {
1910                     boolean success = false;
1911                     for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
1912                         success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_1);
1913                     }
1914                     assertEquals(success, true, "weakCompareAndSet $type$");
1915                     $type$ x = ($type$) vh.get(array, i);
1916                     assertEquals(x, VALUE_1, "weakCompareAndSet $type$");
1917                 }
1918 
1919                 // Compare set and get
1920                 {
1921                     vh.set(array, i, VALUE_1);
1922 
1923                     $type$ o = ($type$) vh.getAndSet(array, i, VALUE_2);
1924                     assertEquals(o, VALUE_1, "getAndSet $type$");
1925                     $type$ x = ($type$) vh.get(array, i);
1926                     assertEquals(x, VALUE_2, "getAndSet $type$ value");
1927                 }
1928 
1929                 {
1930                     vh.set(array, i, VALUE_1);
1931 
1932                     $type$ o = ($type$) vh.getAndSetAcquire(array, i, VALUE_2);
1933                     assertEquals(o, VALUE_1, "getAndSetAcquire $type$");
1934                     $type$ x = ($type$) vh.get(array, i);
1935                     assertEquals(x, VALUE_2, "getAndSetAcquire $type$ value");
1936                 }
1937 
1938                 {
1939                     vh.set(array, i, VALUE_1);
1940 
1941                     $type$ o = ($type$) vh.getAndSetRelease(array, i, VALUE_2);
1942                     assertEquals(o, VALUE_1, "getAndSetRelease $type$");
1943                     $type$ x = ($type$) vh.get(array, i);
1944                     assertEquals(x, VALUE_2, "getAndSetRelease $type$ value");
1945                 }
1946 #end[CAS]
1947 
1948 #if[AtomicAdd]
1949                 // get and add, add and get
1950                 {
1951                     vh.set(array, i, VALUE_1);
1952 
1953                     $type$ o = ($type$) vh.getAndAdd(array, i, VALUE_2);
1954                     assertEquals(o, VALUE_1, "getAndAdd $type$");
1955                     $type$ x = ($type$) vh.get(array, i);
1956                     assertEquals(x, VALUE_1 + VALUE_2, "getAndAdd $type$ value");
1957                 }
1958 
1959                 {
1960                     vh.set(array, i, VALUE_1);
1961 
1962                     $type$ o = ($type$) vh.getAndAddAcquire(array, i, VALUE_2);
1963                     assertEquals(o, VALUE_1, "getAndAddAcquire $type$");
1964                     $type$ x = ($type$) vh.get(array, i);
1965                     assertEquals(x, VALUE_1 + VALUE_2, "getAndAddAcquire $type$ value");
1966                 }
1967 
1968                 {
1969                     vh.set(array, i, VALUE_1);
1970 
1971                     $type$ o = ($type$) vh.getAndAddRelease(array, i, VALUE_2);
1972                     assertEquals(o, VALUE_1, "getAndAddRelease $type$");
1973                     $type$ x = ($type$) vh.get(array, i);
1974                     assertEquals(x, VALUE_1 + VALUE_2, "getAndAddRelease $type$ value");
1975                 }
1976 #end[AtomicAdd]
1977 
1978 #if[Bitwise]
1979                 // get and bitwise or
1980                 {
1981                     vh.set(array, i, VALUE_1);
1982 
1983                     $type$ o = ($type$) vh.getAndBitwiseOr(array, i, VALUE_2);
1984                     assertEquals(o, VALUE_1, "getAndBitwiseOr $type$");
1985                     $type$ x = ($type$) vh.get(array, i);
1986                     assertEquals(x, VALUE_1 | VALUE_2, "getAndBitwiseOr $type$ value");
1987                 }
1988 
1989                 {
1990                     vh.set(array, i, VALUE_1);
1991 
1992                     $type$ o = ($type$) vh.getAndBitwiseOrAcquire(array, i, VALUE_2);
1993                     assertEquals(o, VALUE_1, "getAndBitwiseOrAcquire $type$");
1994                     $type$ x = ($type$) vh.get(array, i);
1995                     assertEquals(x, VALUE_1 | VALUE_2, "getAndBitwiseOrAcquire $type$ value");
1996                 }
1997 
1998                 {
1999                     vh.set(array, i, VALUE_1);
2000 
2001                     $type$ o = ($type$) vh.getAndBitwiseOrRelease(array, i, VALUE_2);
2002                     assertEquals(o, VALUE_1, "getAndBitwiseOrRelease $type$");
2003                     $type$ x = ($type$) vh.get(array, i);
2004                     assertEquals(x, VALUE_1 | VALUE_2, "getAndBitwiseOrRelease $type$ value");
2005                 }
2006 
2007                 // get and bitwise and
2008                 {
2009                     vh.set(array, i, VALUE_1);
2010 
2011                     $type$ o = ($type$) vh.getAndBitwiseAnd(array, i, VALUE_2);
2012                     assertEquals(o, VALUE_1, "getAndBitwiseAnd $type$");
2013                     $type$ x = ($type$) vh.get(array, i);
2014                     assertEquals(x, VALUE_1 & VALUE_2, "getAndBitwiseAnd $type$ value");
2015                 }
2016 
2017                 {
2018                     vh.set(array, i, VALUE_1);
2019 
2020                     $type$ o = ($type$) vh.getAndBitwiseAndAcquire(array, i, VALUE_2);
2021                     assertEquals(o, VALUE_1, "getAndBitwiseAndAcquire $type$");
2022                     $type$ x = ($type$) vh.get(array, i);
2023                     assertEquals(x, VALUE_1 & VALUE_2, "getAndBitwiseAndAcquire $type$ value");
2024                 }
2025 
2026                 {
2027                     vh.set(array, i, VALUE_1);
2028 
2029                     $type$ o = ($type$) vh.getAndBitwiseAndRelease(array, i, VALUE_2);
2030                     assertEquals(o, VALUE_1, "getAndBitwiseAndRelease $type$");
2031                     $type$ x = ($type$) vh.get(array, i);
2032                     assertEquals(x, VALUE_1 & VALUE_2, "getAndBitwiseAndRelease $type$ value");
2033                 }
2034 
2035                 // get and bitwise xor
2036                 {
2037                     vh.set(array, i, VALUE_1);
2038 
2039                     $type$ o = ($type$) vh.getAndBitwiseXor(array, i, VALUE_2);
2040                     assertEquals(o, VALUE_1, "getAndBitwiseXor $type$");
2041                     $type$ x = ($type$) vh.get(array, i);
2042                     assertEquals(x, VALUE_1 ^ VALUE_2, "getAndBitwiseXor $type$ value");
2043                 }
2044 
2045                 {
2046                     vh.set(array, i, VALUE_1);
2047 
2048                     $type$ o = ($type$) vh.getAndBitwiseXorAcquire(array, i, VALUE_2);
2049                     assertEquals(o, VALUE_1, "getAndBitwiseXorAcquire $type$");
2050                     $type$ x = ($type$) vh.get(array, i);
2051                     assertEquals(x, VALUE_1 ^ VALUE_2, "getAndBitwiseXorAcquire $type$ value");
2052                 }
2053 
2054                 {
2055                     vh.set(array, i, VALUE_1);
2056 
2057                     $type$ o = ($type$) vh.getAndBitwiseXorRelease(array, i, VALUE_2);
2058                     assertEquals(o, VALUE_1, "getAndBitwiseXorRelease $type$");
2059                     $type$ x = ($type$) vh.get(array, i);
2060                     assertEquals(x, VALUE_1 ^ VALUE_2, "getAndBitwiseXorRelease $type$ value");
2061                 }
2062 #end[Bitwise]
2063             }
2064         }
2065     }
2066 
2067     static void testArrayReadOnly(ByteBufferSource bs, VarHandleSource vhs) {
2068         VarHandle vh = vhs.s;
2069         ByteBuffer array = bs.s;
2070 
2071         int misalignmentAtZero = array.alignmentOffset(0, SIZE);
2072 
2073         ByteBuffer bb = ByteBuffer.allocate(SIZE);
2074         bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN);
2075         bs.fill(bb.put$Type$(0, VALUE_2).array());
2076 
2077         int length = array.limit() - SIZE + 1;
2078         for (int i = 0; i < length; i++) {
2079             boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
2080 
2081             $type$ v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes)
2082                     ? rotateLeft(VALUE_2, (i % SIZE) << 3)
2083                     : rotateRight(VALUE_2, (i % SIZE) << 3);
2084             // Plain
2085             {
2086                 $type$ x = ($type$) vh.get(array, i);
2087                 assertEquals(x, v, "get $type$ value");
2088             }
2089 
2090             if (iAligned) {
2091                 // Volatile
2092                 {
2093                     $type$ x = ($type$) vh.getVolatile(array, i);
2094                     assertEquals(x, v, "getVolatile $type$ value");
2095                 }
2096 
2097                 // Lazy
2098                 {
2099                     $type$ x = ($type$) vh.getAcquire(array, i);
2100                     assertEquals(x, v, "getRelease $type$ value");
2101                 }
2102 
2103                 // Opaque
2104                 {
2105                     $type$ x = ($type$) vh.getOpaque(array, i);
2106                     assertEquals(x, v, "getOpaque $type$ value");
2107                 }
2108             }
2109         }
2110     }
2111 
2112 }
2113