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