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