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 VarHandleTestByteArrayAsDouble
  28  * @run testng/othervm -Diters=20000                         VarHandleTestByteArrayAsDouble
  29  * @run testng/othervm -Diters=20000 -XX:-TieredCompilation  VarHandleTestByteArrayAsDouble
  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 VarHandleTestByteArrayAsDouble extends VarHandleBaseByteArrayTest {
  47     static final int SIZE = Double.BYTES;
  48 
  49     static final double VALUE_1 = 0x0102030405060708L;
  50 
  51     static final double VALUE_2 = 0x1112131415161718L;
  52 
  53     static final double 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 = double[].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                 }
  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         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
 138         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD_ACQUIRE));
 139         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD_RELEASE));
 140 
 141         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR));
 142         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR_ACQUIRE));
 143         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR_RELEASE));
 144         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND));
 145         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND_ACQUIRE));
 146         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND_RELEASE));
 147         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR));
 148         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_ACQUIRE));
 149         assertFalse(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(), double.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             double x = (double) vh.get(array, ci);
 242         });
 243 
 244         checkNPE(() -> {
 245             vh.set(array, ci, VALUE_1);
 246         });
 247 
 248         checkNPE(() -> {
 249             double x = (double) vh.getVolatile(array, ci);
 250         });
 251 
 252         checkNPE(() -> {
 253             double x = (double) vh.getAcquire(array, ci);
 254         });
 255 
 256         checkNPE(() -> {
 257             double x = (double) 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             double r = (double) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
 278         });
 279 
 280         checkNPE(() -> {
 281             double r = (double) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
 282         });
 283 
 284         checkNPE(() -> {
 285             double r = (double) 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             double o = (double) vh.getAndSet(array, ci, VALUE_1);
 306         });
 307 
 308         checkNPE(() -> {
 309             double o = (double) vh.getAndSetAcquire(array, ci, VALUE_1);
 310         });
 311 
 312         checkNPE(() -> {
 313             double o = (double) vh.getAndSetRelease(array, ci, VALUE_1);
 314         });
 315 
 316 
 317     }
 318 
 319     static void testArrayNPE(ByteBufferSource bs, VarHandleSource vhs) {
 320         VarHandle vh = vhs.s;
 321         ByteBuffer array = null;
 322         int ci = 1;
 323 
 324         checkNPE(() -> {
 325             double x = (double) vh.get(array, ci);
 326         });
 327 
 328         checkNPE(() -> {
 329             vh.set(array, ci, VALUE_1);
 330         });
 331 
 332         checkNPE(() -> {
 333             double x = (double) vh.getVolatile(array, ci);
 334         });
 335 
 336         checkNPE(() -> {
 337             double x = (double) vh.getAcquire(array, ci);
 338         });
 339 
 340         checkNPE(() -> {
 341             double x = (double) vh.getOpaque(array, ci);
 342         });
 343 
 344         checkNPE(() -> {
 345             vh.setVolatile(array, ci, VALUE_1);
 346         });
 347 
 348         checkNPE(() -> {
 349             vh.setRelease(array, ci, VALUE_1);
 350         });
 351 
 352         checkNPE(() -> {
 353             vh.setOpaque(array, ci, VALUE_1);
 354         });
 355 
 356         checkNPE(() -> {
 357             boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
 358         });
 359 
 360         checkNPE(() -> {
 361             double r = (double) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
 362         });
 363 
 364         checkNPE(() -> {
 365             double r = (double) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
 366         });
 367 
 368         checkNPE(() -> {
 369             double r = (double) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
 370         });
 371 
 372         checkNPE(() -> {
 373             boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
 374         });
 375 
 376         checkNPE(() -> {
 377             boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
 378         });
 379 
 380         checkNPE(() -> {
 381             boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
 382         });
 383 
 384         checkNPE(() -> {
 385             boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
 386         });
 387 
 388         checkNPE(() -> {
 389             double o = (double) vh.getAndSet(array, ci, VALUE_1);
 390         });
 391 
 392         checkNPE(() -> {
 393             double o = (double) vh.getAndSetAcquire(array, ci, VALUE_1);
 394         });
 395 
 396         checkNPE(() -> {
 397             double o = (double) vh.getAndSetRelease(array, ci, VALUE_1);
 398         });
 399 
 400 
 401     }
 402 
 403     static void testArrayUnsupported(ByteArraySource bs, VarHandleSource vhs) {
 404         VarHandle vh = vhs.s;
 405         byte[] array = bs.s;
 406         int ci = 1;
 407 
 408 
 409         checkUOE(() -> {
 410             double o = (double) vh.getAndAdd(array, ci, VALUE_1);
 411         });
 412 
 413         checkUOE(() -> {
 414             double o = (double) vh.getAndAddAcquire(array, ci, VALUE_1);
 415         });
 416 
 417         checkUOE(() -> {
 418             double o = (double) vh.getAndAddRelease(array, ci, VALUE_1);
 419         });
 420 
 421         checkUOE(() -> {
 422             double o = (double) vh.getAndBitwiseOr(array, ci, VALUE_1);
 423         });
 424 
 425         checkUOE(() -> {
 426             double o = (double) vh.getAndBitwiseOrAcquire(array, ci, VALUE_1);
 427         });
 428 
 429         checkUOE(() -> {
 430             double o = (double) vh.getAndBitwiseOrRelease(array, ci, VALUE_1);
 431         });
 432 
 433         checkUOE(() -> {
 434             double o = (double) vh.getAndBitwiseAnd(array, ci, VALUE_1);
 435         });
 436 
 437         checkUOE(() -> {
 438             double o = (double) vh.getAndBitwiseAndAcquire(array, ci, VALUE_1);
 439         });
 440 
 441         checkUOE(() -> {
 442             double o = (double) vh.getAndBitwiseAndRelease(array, ci, VALUE_1);
 443         });
 444 
 445         checkUOE(() -> {
 446             double o = (double) vh.getAndBitwiseXor(array, ci, VALUE_1);
 447         });
 448 
 449         checkUOE(() -> {
 450             double o = (double) vh.getAndBitwiseXorAcquire(array, ci, VALUE_1);
 451         });
 452 
 453         checkUOE(() -> {
 454             double o = (double) vh.getAndBitwiseXorRelease(array, ci, VALUE_1);
 455         });
 456     }
 457 
 458     static void testArrayUnsupported(ByteBufferSource bs, VarHandleSource vhs) {
 459         VarHandle vh = vhs.s;
 460         ByteBuffer array = bs.s;
 461         int ci = 0;
 462         boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
 463 
 464         if (readOnly) {
 465             checkROBE(() -> {
 466                 vh.set(array, ci, VALUE_1);
 467             });
 468         }
 469 
 470         if (readOnly) {
 471             checkROBE(() -> {
 472                 vh.setVolatile(array, ci, VALUE_1);
 473             });
 474 
 475             checkROBE(() -> {
 476                 vh.setRelease(array, ci, VALUE_1);
 477             });
 478 
 479             checkROBE(() -> {
 480                 vh.setOpaque(array, ci, VALUE_1);
 481             });
 482 
 483             checkROBE(() -> {
 484                 boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
 485             });
 486 
 487             checkROBE(() -> {
 488                 double r = (double) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
 489             });
 490 
 491             checkROBE(() -> {
 492                 double r = (double) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
 493             });
 494 
 495             checkROBE(() -> {
 496                 double r = (double) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
 497             });
 498 
 499             checkROBE(() -> {
 500                 boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
 501             });
 502 
 503             checkROBE(() -> {
 504                 boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
 505             });
 506 
 507             checkROBE(() -> {
 508                 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
 509             });
 510 
 511             checkROBE(() -> {
 512                 boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
 513             });
 514 
 515             checkROBE(() -> {
 516                 double o = (double) vh.getAndSet(array, ci, VALUE_1);
 517             });
 518 
 519             checkROBE(() -> {
 520                 double o = (double) vh.getAndSetAcquire(array, ci, VALUE_1);
 521             });
 522 
 523             checkROBE(() -> {
 524                 double o = (double) vh.getAndSetRelease(array, ci, VALUE_1);
 525             });
 526 
 527 
 528             checkUOE(() -> {
 529                 double o = (double) vh.getAndAdd(array, ci, VALUE_1);
 530             });
 531 
 532             checkUOE(() -> {
 533                 double o = (double) vh.getAndAddAcquire(array, ci, VALUE_1);
 534             });
 535 
 536             checkUOE(() -> {
 537                 double o = (double) vh.getAndAddRelease(array, ci, VALUE_1);
 538             });
 539 
 540             checkUOE(() -> {
 541                 double o = (double) vh.getAndBitwiseOr(array, ci, VALUE_1);
 542             });
 543 
 544             checkUOE(() -> {
 545                 double o = (double) vh.getAndBitwiseOrAcquire(array, ci, VALUE_1);
 546             });
 547 
 548             checkUOE(() -> {
 549                 double o = (double) vh.getAndBitwiseOrRelease(array, ci, VALUE_1);
 550             });
 551 
 552             checkUOE(() -> {
 553                 double o = (double) vh.getAndBitwiseAnd(array, ci, VALUE_1);
 554             });
 555 
 556             checkUOE(() -> {
 557                 double o = (double) vh.getAndBitwiseAndAcquire(array, ci, VALUE_1);
 558             });
 559 
 560             checkUOE(() -> {
 561                 double o = (double) vh.getAndBitwiseAndRelease(array, ci, VALUE_1);
 562             });
 563 
 564             checkUOE(() -> {
 565                 double o = (double) vh.getAndBitwiseXor(array, ci, VALUE_1);
 566             });
 567 
 568             checkUOE(() -> {
 569                 double o = (double) vh.getAndBitwiseXorAcquire(array, ci, VALUE_1);
 570             });
 571 
 572             checkUOE(() -> {
 573                 double o = (double) vh.getAndBitwiseXorRelease(array, ci, VALUE_1);
 574             });
 575         }
 576         else {
 577             checkUOE(() -> {
 578                 double o = (double) vh.getAndAdd(array, ci, VALUE_1);
 579             });
 580 
 581             checkUOE(() -> {
 582                 double o = (double) vh.getAndAddAcquire(array, ci, VALUE_1);
 583             });
 584 
 585             checkUOE(() -> {
 586                 double o = (double) vh.getAndAddRelease(array, ci, VALUE_1);
 587             });
 588             checkUOE(() -> {
 589                 double o = (double) vh.getAndBitwiseOr(array, ci, VALUE_1);
 590             });
 591 
 592             checkUOE(() -> {
 593                 double o = (double) vh.getAndBitwiseOrAcquire(array, ci, VALUE_1);
 594             });
 595 
 596             checkUOE(() -> {
 597                 double o = (double) vh.getAndBitwiseOrRelease(array, ci, VALUE_1);
 598             });
 599 
 600             checkUOE(() -> {
 601                 double o = (double) vh.getAndBitwiseAnd(array, ci, VALUE_1);
 602             });
 603 
 604             checkUOE(() -> {
 605                 double o = (double) vh.getAndBitwiseAndAcquire(array, ci, VALUE_1);
 606             });
 607 
 608             checkUOE(() -> {
 609                 double o = (double) vh.getAndBitwiseAndRelease(array, ci, VALUE_1);
 610             });
 611 
 612             checkUOE(() -> {
 613                 double o = (double) vh.getAndBitwiseXor(array, ci, VALUE_1);
 614             });
 615 
 616             checkUOE(() -> {
 617                 double o = (double) vh.getAndBitwiseXorAcquire(array, ci, VALUE_1);
 618             });
 619 
 620             checkUOE(() -> {
 621                 double o = (double) vh.getAndBitwiseXorRelease(array, ci, VALUE_1);
 622             });
 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                 double x = (double) vh.get(array, ci);
 637             });
 638 
 639             checkIOOBE(() -> {
 640                 vh.set(array, ci, VALUE_1);
 641             });
 642 
 643             checkIOOBE(() -> {
 644                 double x = (double) vh.getVolatile(array, ci);
 645             });
 646 
 647             checkIOOBE(() -> {
 648                 double x = (double) vh.getAcquire(array, ci);
 649             });
 650 
 651             checkIOOBE(() -> {
 652                 double x = (double) 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                 double r = (double) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
 673             });
 674 
 675             checkIOOBE(() -> {
 676                 double r = (double) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
 677             });
 678 
 679             checkIOOBE(() -> {
 680                 double r = (double) 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                 double o = (double) vh.getAndSet(array, ci, VALUE_1);
 701             });
 702 
 703             checkIOOBE(() -> {
 704                 double o = (double) vh.getAndSetAcquire(array, ci, VALUE_1);
 705             });
 706 
 707             checkIOOBE(() -> {
 708                 double o = (double) vh.getAndSetRelease(array, ci, VALUE_1);
 709             });
 710 
 711 
 712 
 713         }
 714     }
 715 
 716     static void testArrayIndexOutOfBounds(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
 717         VarHandle vh = vhs.s;
 718         ByteBuffer array = bs.s;
 719 
 720         boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
 721 
 722         int length = array.limit() - SIZE + 1;
 723         for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
 724             final int ci = i;
 725 
 726             checkIOOBE(() -> {
 727                 double x = (double) vh.get(array, ci);
 728             });
 729 
 730             if (!readOnly) {
 731                 checkIOOBE(() -> {
 732                     vh.set(array, ci, VALUE_1);
 733                 });
 734             }
 735 
 736             checkIOOBE(() -> {
 737                 double x = (double) vh.getVolatile(array, ci);
 738             });
 739 
 740             checkIOOBE(() -> {
 741                 double x = (double) vh.getAcquire(array, ci);
 742             });
 743 
 744             checkIOOBE(() -> {
 745                 double x = (double) vh.getOpaque(array, ci);
 746             });
 747 
 748             if (!readOnly) {
 749                 checkIOOBE(() -> {
 750                     vh.setVolatile(array, ci, VALUE_1);
 751                 });
 752 
 753                 checkIOOBE(() -> {
 754                     vh.setRelease(array, ci, VALUE_1);
 755                 });
 756 
 757                 checkIOOBE(() -> {
 758                     vh.setOpaque(array, ci, VALUE_1);
 759                 });
 760 
 761                 checkIOOBE(() -> {
 762                     boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
 763                 });
 764 
 765                 checkIOOBE(() -> {
 766                     double r = (double) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
 767                 });
 768 
 769                 checkIOOBE(() -> {
 770                     double r = (double) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
 771                 });
 772 
 773                 checkIOOBE(() -> {
 774                     double r = (double) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
 775                 });
 776 
 777                 checkIOOBE(() -> {
 778                     boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
 779                 });
 780 
 781                 checkIOOBE(() -> {
 782                     boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
 783                 });
 784 
 785                 checkIOOBE(() -> {
 786                     boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
 787                 });
 788 
 789                 checkIOOBE(() -> {
 790                     boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
 791                 });
 792 
 793                 checkIOOBE(() -> {
 794                     double o = (double) vh.getAndSet(array, ci, VALUE_1);
 795                 });
 796 
 797                 checkIOOBE(() -> {
 798                     double o = (double) vh.getAndSetAcquire(array, ci, VALUE_1);
 799                 });
 800 
 801                 checkIOOBE(() -> {
 802                     double o = (double) vh.getAndSetRelease(array, ci, VALUE_1);
 803                 });
 804 
 805 
 806             }
 807         }
 808     }
 809 
 810     static void testArrayMisalignedAccess(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
 811         VarHandle vh = vhs.s;
 812         byte[] array = bs.s;
 813 
 814         int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
 815 
 816         int length = array.length - SIZE + 1;
 817         for (int i = 0; i < length; i++) {
 818             boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
 819             final int ci = i;
 820 
 821             if (!iAligned) {
 822                 checkISE(() -> {
 823                     double x = (double) vh.getVolatile(array, ci);
 824                 });
 825 
 826                 checkISE(() -> {
 827                     double x = (double) vh.getAcquire(array, ci);
 828                 });
 829 
 830                 checkISE(() -> {
 831                     double x = (double) vh.getOpaque(array, ci);
 832                 });
 833 
 834                 checkISE(() -> {
 835                     vh.setVolatile(array, ci, VALUE_1);
 836                 });
 837 
 838                 checkISE(() -> {
 839                     vh.setRelease(array, ci, VALUE_1);
 840                 });
 841 
 842                 checkISE(() -> {
 843                     vh.setOpaque(array, ci, VALUE_1);
 844                 });
 845 
 846                 checkISE(() -> {
 847                     boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
 848                 });
 849 
 850                 checkISE(() -> {
 851                     double r = (double) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
 852                 });
 853 
 854                 checkISE(() -> {
 855                     double r = (double) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
 856                 });
 857 
 858                 checkISE(() -> {
 859                     double r = (double) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
 860                 });
 861 
 862                 checkISE(() -> {
 863                     boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
 864                 });
 865 
 866                 checkISE(() -> {
 867                     boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
 868                 });
 869 
 870                 checkISE(() -> {
 871                     boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
 872                 });
 873 
 874                 checkISE(() -> {
 875                     boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
 876                 });
 877 
 878                 checkISE(() -> {
 879                     double o = (double) vh.getAndSet(array, ci, VALUE_1);
 880                 });
 881 
 882                 checkISE(() -> {
 883                     double o = (double) vh.getAndSetAcquire(array, ci, VALUE_1);
 884                 });
 885 
 886                 checkISE(() -> {
 887                     double o = (double) vh.getAndSetRelease(array, ci, VALUE_1);
 888                 });
 889 
 890 
 891             }
 892         }
 893     }
 894 
 895     static void testArrayMisalignedAccess(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
 896         VarHandle vh = vhs.s;
 897         ByteBuffer array = bs.s;
 898 
 899         boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
 900         int misalignmentAtZero = array.alignmentOffset(0, SIZE);
 901 
 902         int length = array.limit() - SIZE + 1;
 903         for (int i = 0; i < length; i++) {
 904             boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
 905             final int ci = i;
 906 
 907             if (!iAligned) {
 908                 checkISE(() -> {
 909                     double x = (double) vh.getVolatile(array, ci);
 910                 });
 911 
 912                 checkISE(() -> {
 913                     double x = (double) vh.getAcquire(array, ci);
 914                 });
 915 
 916                 checkISE(() -> {
 917                     double x = (double) vh.getOpaque(array, ci);
 918                 });
 919 
 920                 if (!readOnly) {
 921                     checkISE(() -> {
 922                         vh.setVolatile(array, ci, VALUE_1);
 923                     });
 924 
 925                     checkISE(() -> {
 926                         vh.setRelease(array, ci, VALUE_1);
 927                     });
 928 
 929                     checkISE(() -> {
 930                         vh.setOpaque(array, ci, VALUE_1);
 931                     });
 932 
 933                     checkISE(() -> {
 934                         boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
 935                     });
 936 
 937                     checkISE(() -> {
 938                         double r = (double) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
 939                     });
 940 
 941                     checkISE(() -> {
 942                         double r = (double) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
 943                     });
 944 
 945                     checkISE(() -> {
 946                         double r = (double) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
 947                     });
 948 
 949                     checkISE(() -> {
 950                         boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
 951                     });
 952 
 953                     checkISE(() -> {
 954                         boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
 955                     });
 956 
 957                     checkISE(() -> {
 958                         boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
 959                     });
 960 
 961                     checkISE(() -> {
 962                         boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
 963                     });
 964 
 965                     checkISE(() -> {
 966                         double o = (double) vh.getAndSet(array, ci, VALUE_1);
 967                     });
 968 
 969                     checkISE(() -> {
 970                         double o = (double) vh.getAndSetAcquire(array, ci, VALUE_1);
 971                     });
 972 
 973                     checkISE(() -> {
 974                         double o = (double) vh.getAndSetRelease(array, ci, VALUE_1);
 975                     });
 976 
 977 
 978                 }
 979             }
 980         }
 981     }
 982 
 983     static void testArrayReadWrite(ByteArraySource bs, VarHandleSource vhs) {
 984         VarHandle vh = vhs.s;
 985         byte[] array = bs.s;
 986 
 987         int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
 988 
 989         bs.fill((byte) 0xff);
 990         int length = array.length - SIZE + 1;
 991         for (int i = 0; i < length; i++) {
 992             boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
 993 
 994             // Plain
 995             {
 996                 vh.set(array, i, VALUE_1);
 997                 double x = (double) vh.get(array, i);
 998                 assertEquals(x, VALUE_1, "get double value");
 999             }
1000 
1001 
1002             if (iAligned) {
1003                 // Volatile
1004                 {
1005                     vh.setVolatile(array, i, VALUE_2);
1006                     double x = (double) vh.getVolatile(array, i);
1007                     assertEquals(x, VALUE_2, "setVolatile double value");
1008                 }
1009 
1010                 // Lazy
1011                 {
1012                     vh.setRelease(array, i, VALUE_1);
1013                     double x = (double) vh.getAcquire(array, i);
1014                     assertEquals(x, VALUE_1, "setRelease double value");
1015                 }
1016 
1017                 // Opaque
1018                 {
1019                     vh.setOpaque(array, i, VALUE_2);
1020                     double x = (double) vh.getOpaque(array, i);
1021                     assertEquals(x, VALUE_2, "setOpaque double value");
1022                 }
1023 
1024                 vh.set(array, i, VALUE_1);
1025 
1026                 // Compare
1027                 {
1028                     boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2);
1029                     assertEquals(r, true, "success compareAndSet double");
1030                     double x = (double) vh.get(array, i);
1031                     assertEquals(x, VALUE_2, "success compareAndSet double value");
1032                 }
1033 
1034                 {
1035                     boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3);
1036                     assertEquals(r, false, "failing compareAndSet double");
1037                     double x = (double) vh.get(array, i);
1038                     assertEquals(x, VALUE_2, "failing compareAndSet double value");
1039                 }
1040 
1041                 {
1042                     double r = (double) vh.compareAndExchange(array, i, VALUE_2, VALUE_1);
1043                     assertEquals(r, VALUE_2, "success compareAndExchange double");
1044                     double x = (double) vh.get(array, i);
1045                     assertEquals(x, VALUE_1, "success compareAndExchange double value");
1046                 }
1047 
1048                 {
1049                     double r = (double) vh.compareAndExchange(array, i, VALUE_2, VALUE_3);
1050                     assertEquals(r, VALUE_1, "failing compareAndExchange double");
1051                     double x = (double) vh.get(array, i);
1052                     assertEquals(x, VALUE_1, "failing compareAndExchange double value");
1053                 }
1054 
1055                 {
1056                     double r = (double) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2);
1057                     assertEquals(r, VALUE_1, "success compareAndExchangeAcquire double");
1058                     double x = (double) vh.get(array, i);
1059                     assertEquals(x, VALUE_2, "success compareAndExchangeAcquire double value");
1060                 }
1061 
1062                 {
1063                     double r = (double) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3);
1064                     assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire double");
1065                     double x = (double) vh.get(array, i);
1066                     assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire double value");
1067                 }
1068 
1069                 {
1070                     double r = (double) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1);
1071                     assertEquals(r, VALUE_2, "success compareAndExchangeRelease double");
1072                     double x = (double) vh.get(array, i);
1073                     assertEquals(x, VALUE_1, "success compareAndExchangeRelease double value");
1074                 }
1075 
1076                 {
1077                     double r = (double) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3);
1078                     assertEquals(r, VALUE_1, "failing compareAndExchangeRelease double");
1079                     double x = (double) vh.get(array, i);
1080                     assertEquals(x, VALUE_1, "failing compareAndExchangeRelease double value");
1081                 }
1082 
1083                 {
1084                     boolean success = false;
1085                     for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
1086                         success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_2);
1087                     }
1088                     assertEquals(success, true, "weakCompareAndSetPlain double");
1089                     double x = (double) vh.get(array, i);
1090                     assertEquals(x, VALUE_2, "weakCompareAndSetPlain double value");
1091                 }
1092 
1093                 {
1094                     boolean success = false;
1095                     for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
1096                         success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1);
1097                     }
1098                     assertEquals(success, true, "weakCompareAndSetAcquire double");
1099                     double x = (double) vh.get(array, i);
1100                     assertEquals(x, VALUE_1, "weakCompareAndSetAcquire double");
1101                 }
1102 
1103                 {
1104                     boolean success = false;
1105                     for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
1106                         success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2);
1107                     }
1108                     assertEquals(success, true, "weakCompareAndSetRelease double");
1109                     double x = (double) vh.get(array, i);
1110                     assertEquals(x, VALUE_2, "weakCompareAndSetRelease double");
1111                 }
1112 
1113                 {
1114                     boolean success = false;
1115                     for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
1116                         success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_1);
1117                     }
1118                     assertEquals(success, true, "weakCompareAndSet double");
1119                     double x = (double) vh.get(array, i);
1120                     assertEquals(x, VALUE_1, "weakCompareAndSet double");
1121                 }
1122 
1123                 // Compare set and get
1124                 {
1125                     vh.set(array, i, VALUE_1);
1126 
1127                     double o = (double) vh.getAndSet(array, i, VALUE_2);
1128                     assertEquals(o, VALUE_1, "getAndSet double");
1129                     double x = (double) vh.get(array, i);
1130                     assertEquals(x, VALUE_2, "getAndSet double value");
1131                 }
1132 
1133                 {
1134                     vh.set(array, i, VALUE_1);
1135 
1136                     double o = (double) vh.getAndSetAcquire(array, i, VALUE_2);
1137                     assertEquals(o, VALUE_1, "getAndSetAcquire double");
1138                     double x = (double) vh.get(array, i);
1139                     assertEquals(x, VALUE_2, "getAndSetAcquire double value");
1140                 }
1141 
1142                 {
1143                     vh.set(array, i, VALUE_1);
1144 
1145                     double o = (double) vh.getAndSetRelease(array, i, VALUE_2);
1146                     assertEquals(o, VALUE_1, "getAndSetRelease double");
1147                     double x = (double) vh.get(array, i);
1148                     assertEquals(x, VALUE_2, "getAndSetRelease double value");
1149                 }
1150 
1151 
1152             }
1153         }
1154     }
1155 
1156 
1157     static void testArrayReadWrite(ByteBufferSource bs, VarHandleSource vhs) {
1158         VarHandle vh = vhs.s;
1159         ByteBuffer array = bs.s;
1160 
1161         int misalignmentAtZero = array.alignmentOffset(0, SIZE);
1162 
1163         bs.fill((byte) 0xff);
1164         int length = array.limit() - SIZE + 1;
1165         for (int i = 0; i < length; i++) {
1166             boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
1167 
1168             // Plain
1169             {
1170                 vh.set(array, i, VALUE_1);
1171                 double x = (double) vh.get(array, i);
1172                 assertEquals(x, VALUE_1, "get double value");
1173             }
1174 
1175             if (iAligned) {
1176                 // Volatile
1177                 {
1178                     vh.setVolatile(array, i, VALUE_2);
1179                     double x = (double) vh.getVolatile(array, i);
1180                     assertEquals(x, VALUE_2, "setVolatile double value");
1181                 }
1182 
1183                 // Lazy
1184                 {
1185                     vh.setRelease(array, i, VALUE_1);
1186                     double x = (double) vh.getAcquire(array, i);
1187                     assertEquals(x, VALUE_1, "setRelease double value");
1188                 }
1189 
1190                 // Opaque
1191                 {
1192                     vh.setOpaque(array, i, VALUE_2);
1193                     double x = (double) vh.getOpaque(array, i);
1194                     assertEquals(x, VALUE_2, "setOpaque double value");
1195                 }
1196 
1197                 vh.set(array, i, VALUE_1);
1198 
1199                 // Compare
1200                 {
1201                     boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2);
1202                     assertEquals(r, true, "success compareAndSet double");
1203                     double x = (double) vh.get(array, i);
1204                     assertEquals(x, VALUE_2, "success compareAndSet double value");
1205                 }
1206 
1207                 {
1208                     boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3);
1209                     assertEquals(r, false, "failing compareAndSet double");
1210                     double x = (double) vh.get(array, i);
1211                     assertEquals(x, VALUE_2, "failing compareAndSet double value");
1212                 }
1213 
1214                 {
1215                     double r = (double) vh.compareAndExchange(array, i, VALUE_2, VALUE_1);
1216                     assertEquals(r, VALUE_2, "success compareAndExchange double");
1217                     double x = (double) vh.get(array, i);
1218                     assertEquals(x, VALUE_1, "success compareAndExchange double value");
1219                 }
1220 
1221                 {
1222                     double r = (double) vh.compareAndExchange(array, i, VALUE_2, VALUE_3);
1223                     assertEquals(r, VALUE_1, "failing compareAndExchange double");
1224                     double x = (double) vh.get(array, i);
1225                     assertEquals(x, VALUE_1, "failing compareAndExchange double value");
1226                 }
1227 
1228                 {
1229                     double r = (double) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2);
1230                     assertEquals(r, VALUE_1, "success compareAndExchangeAcquire double");
1231                     double x = (double) vh.get(array, i);
1232                     assertEquals(x, VALUE_2, "success compareAndExchangeAcquire double value");
1233                 }
1234 
1235                 {
1236                     double r = (double) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3);
1237                     assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire double");
1238                     double x = (double) vh.get(array, i);
1239                     assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire double value");
1240                 }
1241 
1242                 {
1243                     double r = (double) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1);
1244                     assertEquals(r, VALUE_2, "success compareAndExchangeRelease double");
1245                     double x = (double) vh.get(array, i);
1246                     assertEquals(x, VALUE_1, "success compareAndExchangeRelease double value");
1247                 }
1248 
1249                 {
1250                     double r = (double) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3);
1251                     assertEquals(r, VALUE_1, "failing compareAndExchangeRelease double");
1252                     double x = (double) vh.get(array, i);
1253                     assertEquals(x, VALUE_1, "failing compareAndExchangeRelease double value");
1254                 }
1255 
1256                 {
1257                     boolean success = false;
1258                     for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
1259                         success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_2);
1260                     }
1261                     assertEquals(success, true, "weakCompareAndSetPlain double");
1262                     double x = (double) vh.get(array, i);
1263                     assertEquals(x, VALUE_2, "weakCompareAndSetPlain double value");
1264                 }
1265 
1266                 {
1267                     boolean success = false;
1268                     for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
1269                         success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1);
1270                     }
1271                     assertEquals(success, true, "weakCompareAndSetAcquire double");
1272                     double x = (double) vh.get(array, i);
1273                     assertEquals(x, VALUE_1, "weakCompareAndSetAcquire double");
1274                 }
1275 
1276                 {
1277                     boolean success = false;
1278                     for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
1279                         success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2);
1280                     }
1281                     assertEquals(success, true, "weakCompareAndSetRelease double");
1282                     double x = (double) vh.get(array, i);
1283                     assertEquals(x, VALUE_2, "weakCompareAndSetRelease double");
1284                 }
1285 
1286                 {
1287                     boolean success = false;
1288                     for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
1289                         success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_1);
1290                     }
1291                     assertEquals(success, true, "weakCompareAndSet double");
1292                     double x = (double) vh.get(array, i);
1293                     assertEquals(x, VALUE_1, "weakCompareAndSet double");
1294                 }
1295 
1296                 // Compare set and get
1297                 {
1298                     vh.set(array, i, VALUE_1);
1299 
1300                     double o = (double) vh.getAndSet(array, i, VALUE_2);
1301                     assertEquals(o, VALUE_1, "getAndSet double");
1302                     double x = (double) vh.get(array, i);
1303                     assertEquals(x, VALUE_2, "getAndSet double value");
1304                 }
1305 
1306                 {
1307                     vh.set(array, i, VALUE_1);
1308 
1309                     double o = (double) vh.getAndSetAcquire(array, i, VALUE_2);
1310                     assertEquals(o, VALUE_1, "getAndSetAcquire double");
1311                     double x = (double) vh.get(array, i);
1312                     assertEquals(x, VALUE_2, "getAndSetAcquire double value");
1313                 }
1314 
1315                 {
1316                     vh.set(array, i, VALUE_1);
1317 
1318                     double o = (double) vh.getAndSetRelease(array, i, VALUE_2);
1319                     assertEquals(o, VALUE_1, "getAndSetRelease double");
1320                     double x = (double) vh.get(array, i);
1321                     assertEquals(x, VALUE_2, "getAndSetRelease double value");
1322                 }
1323 
1324 
1325             }
1326         }
1327     }
1328 
1329     static void testArrayReadOnly(ByteBufferSource bs, VarHandleSource vhs) {
1330         VarHandle vh = vhs.s;
1331         ByteBuffer array = bs.s;
1332 
1333         int misalignmentAtZero = array.alignmentOffset(0, SIZE);
1334 
1335         ByteBuffer bb = ByteBuffer.allocate(SIZE);
1336         bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN);
1337         bs.fill(bb.putDouble(0, VALUE_2).array());
1338 
1339         int length = array.limit() - SIZE + 1;
1340         for (int i = 0; i < length; i++) {
1341             boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
1342 
1343             double v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes)
1344                     ? rotateLeft(VALUE_2, (i % SIZE) << 3)
1345                     : rotateRight(VALUE_2, (i % SIZE) << 3);
1346             // Plain
1347             {
1348                 double x = (double) vh.get(array, i);
1349                 assertEquals(x, v, "get double value");
1350             }
1351 
1352             if (iAligned) {
1353                 // Volatile
1354                 {
1355                     double x = (double) vh.getVolatile(array, i);
1356                     assertEquals(x, v, "getVolatile double value");
1357                 }
1358 
1359                 // Lazy
1360                 {
1361                     double x = (double) vh.getAcquire(array, i);
1362                     assertEquals(x, v, "getRelease double value");
1363                 }
1364 
1365                 // Opaque
1366                 {
1367                     double x = (double) vh.getOpaque(array, i);
1368                     assertEquals(x, v, "getOpaque double value");
1369                 }
1370             }
1371         }
1372     }
1373 
1374 }
1375