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