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