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 void setupVarHandleSources() {
  58         // Combinations of VarHandle byte[] or ByteBuffer
  59         vhss = new ArrayList<>();
  60         for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) {
  61 
  62             ByteOrder bo = endianess == MemoryMode.BIG_ENDIAN
  63                     ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
  64             VarHandleSource aeh = new VarHandleSource(
  65                     MethodHandles.byteArrayViewVarHandle(double[].class, bo),
  66                     endianess, MemoryMode.READ_WRITE);
  67             vhss.add(aeh);
  68 
  69             VarHandleSource bbh = new VarHandleSource(
  70                     MethodHandles.byteBufferViewVarHandle(double[].class, bo),
  71                     endianess, MemoryMode.READ_WRITE);
  72             vhss.add(bbh);
  73         }
  74     }
  75 
  76 
  77     @Test(dataProvider = "varHandlesProvider")
  78     public void testIsAccessModeSupported(VarHandleSource vhs) {
  79         VarHandle vh = vhs.s;
  80 
  81         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET));
  82         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET));
  83 
  84         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_VOLATILE));
  85         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_VOLATILE));
  86         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_ACQUIRE));
  87         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_RELEASE));
  88         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_OPAQUE));
  89         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_OPAQUE));
  90 
  91         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_SET));
  92         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE));
  93         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
  94         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
  95         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_PLAIN));
  96         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
  97         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
  98         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
  99         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
 100         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET_ACQUIRE));
 101         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET_RELEASE));
 102 
 103         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
 104         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD_ACQUIRE));
 105         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD_RELEASE));
 106 
 107         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR));
 108         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR_ACQUIRE));
 109         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR_RELEASE));
 110         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND));
 111         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND_ACQUIRE));
 112         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND_RELEASE));
 113         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR));
 114         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_ACQUIRE));
 115         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_RELEASE));
 116     }
 117 
 118     @Test(dataProvider = "typesProvider")
 119     public void testTypes(VarHandle vh, List<java.lang.Class<?>> pts) {
 120         assertEquals(vh.varType(), double.class);
 121 
 122         assertEquals(vh.coordinateTypes(), pts);
 123 
 124         testTypes(vh);
 125     }
 126 
 127 
 128     @DataProvider
 129     public Object[][] accessTestCaseProvider() throws Exception {
 130         List<AccessTestCase<?>> cases = new ArrayList<>();
 131 
 132         for (ByteArrayViewSource<?> bav : bavss) {
 133             for (VarHandleSource vh : vhss) {
 134                 if (vh.matches(bav)) {
 135                     if (bav instanceof ByteArraySource) {
 136                         ByteArraySource bas = (ByteArraySource) bav;
 137 
 138                         cases.add(new VarHandleSourceAccessTestCase(
 139                                 "read write", bav, vh, h -> testArrayReadWrite(bas, h),
 140                                 true));
 141                         cases.add(new VarHandleSourceAccessTestCase(
 142                                 "null array", bav, vh, h -> testArrayNPE(bas, h),
 143                                 false));
 144                         cases.add(new VarHandleSourceAccessTestCase(
 145                                 "unsupported", bav, vh, h -> testArrayUnsupported(bas, h),
 146                                 false));
 147                         cases.add(new VarHandleSourceAccessTestCase(
 148                                 "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bas, h),
 149                                 false));
 150                         cases.add(new VarHandleSourceAccessTestCase(
 151                                 "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bas, h),
 152                                 false));
 153                     }
 154                     else {
 155                         ByteBufferSource bbs = (ByteBufferSource) bav;
 156 
 157                         if (MemoryMode.READ_WRITE.isSet(bav.memoryModes)) {
 158                             cases.add(new VarHandleSourceAccessTestCase(
 159                                     "read write", bav, vh, h -> testArrayReadWrite(bbs, h),
 160                                     true));
 161                         }
 162                         else {
 163                             cases.add(new VarHandleSourceAccessTestCase(
 164                                     "read only", bav, vh, h -> testArrayReadOnly(bbs, h),
 165                                     true));
 166                         }
 167 
 168                         cases.add(new VarHandleSourceAccessTestCase(
 169                                 "null buffer", bav, vh, h -> testArrayNPE(bbs, h),
 170                                 false));
 171                         cases.add(new VarHandleSourceAccessTestCase(
 172                                 "unsupported", bav, vh, h -> testArrayUnsupported(bbs, h),
 173                                 false));
 174                         cases.add(new VarHandleSourceAccessTestCase(
 175                                 "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bbs, h),
 176                                 false));
 177                         cases.add(new VarHandleSourceAccessTestCase(
 178                                 "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bbs, h),
 179                                 false));
 180                     }
 181                 }
 182             }
 183         }
 184 
 185         // Work around issue with jtreg summary reporting which truncates
 186         // the String result of Object.toString to 30 characters, hence
 187         // the first dummy argument
 188         return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
 189     }
 190 
 191     @Test(dataProvider = "accessTestCaseProvider")
 192     public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
 193         T t = atc.get();
 194         int iters = atc.requiresLoop() ? ITERS : 1;
 195         for (int c = 0; c < iters; c++) {
 196             atc.testAccess(t);
 197         }
 198     }
 199 
 200 
 201     static void testArrayNPE(ByteArraySource bs, VarHandleSource vhs) {
 202         VarHandle vh = vhs.s;
 203         byte[] array = null;
 204         int ci = 1;
 205 
 206         checkNPE(() -> {
 207             double x = (double) vh.get(array, ci);
 208         });
 209 
 210         checkNPE(() -> {
 211             vh.set(array, ci, VALUE_1);
 212         });
 213 
 214         checkNPE(() -> {
 215             double x = (double) vh.getVolatile(array, ci);
 216         });
 217 
 218         checkNPE(() -> {
 219             double x = (double) vh.getAcquire(array, ci);
 220         });
 221 
 222         checkNPE(() -> {
 223             double x = (double) vh.getOpaque(array, ci);
 224         });
 225 
 226         checkNPE(() -> {
 227             vh.setVolatile(array, ci, VALUE_1);
 228         });
 229 
 230         checkNPE(() -> {
 231             vh.setRelease(array, ci, VALUE_1);
 232         });
 233 
 234         checkNPE(() -> {
 235             vh.setOpaque(array, ci, VALUE_1);
 236         });
 237 
 238         checkNPE(() -> {
 239             boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
 240         });
 241 
 242         checkNPE(() -> {
 243             double r = (double) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
 244         });
 245 
 246         checkNPE(() -> {
 247             double r = (double) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
 248         });
 249 
 250         checkNPE(() -> {
 251             double r = (double) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
 252         });
 253 
 254         checkNPE(() -> {
 255             boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
 256         });
 257 
 258         checkNPE(() -> {
 259             boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
 260         });
 261 
 262         checkNPE(() -> {
 263             boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
 264         });
 265 
 266         checkNPE(() -> {
 267             boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
 268         });
 269 
 270         checkNPE(() -> {
 271             double o = (double) vh.getAndSet(array, ci, VALUE_1);
 272         });
 273 
 274         checkNPE(() -> {
 275             double o = (double) vh.getAndSetAcquire(array, ci, VALUE_1);
 276         });
 277 
 278         checkNPE(() -> {
 279             double o = (double) vh.getAndSetRelease(array, ci, VALUE_1);
 280         });
 281 
 282 
 283     }
 284 
 285     static void testArrayNPE(ByteBufferSource bs, VarHandleSource vhs) {
 286         VarHandle vh = vhs.s;
 287         ByteBuffer array = null;
 288         int ci = 1;
 289 
 290         checkNPE(() -> {
 291             double x = (double) vh.get(array, ci);
 292         });
 293 
 294         checkNPE(() -> {
 295             vh.set(array, ci, VALUE_1);
 296         });
 297 
 298         checkNPE(() -> {
 299             double x = (double) vh.getVolatile(array, ci);
 300         });
 301 
 302         checkNPE(() -> {
 303             double x = (double) vh.getAcquire(array, ci);
 304         });
 305 
 306         checkNPE(() -> {
 307             double x = (double) vh.getOpaque(array, ci);
 308         });
 309 
 310         checkNPE(() -> {
 311             vh.setVolatile(array, ci, VALUE_1);
 312         });
 313 
 314         checkNPE(() -> {
 315             vh.setRelease(array, ci, VALUE_1);
 316         });
 317 
 318         checkNPE(() -> {
 319             vh.setOpaque(array, ci, VALUE_1);
 320         });
 321 
 322         checkNPE(() -> {
 323             boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
 324         });
 325 
 326         checkNPE(() -> {
 327             double r = (double) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
 328         });
 329 
 330         checkNPE(() -> {
 331             double r = (double) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
 332         });
 333 
 334         checkNPE(() -> {
 335             double r = (double) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
 336         });
 337 
 338         checkNPE(() -> {
 339             boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
 340         });
 341 
 342         checkNPE(() -> {
 343             boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
 344         });
 345 
 346         checkNPE(() -> {
 347             boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
 348         });
 349 
 350         checkNPE(() -> {
 351             boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
 352         });
 353 
 354         checkNPE(() -> {
 355             double o = (double) vh.getAndSet(array, ci, VALUE_1);
 356         });
 357 
 358         checkNPE(() -> {
 359             double o = (double) vh.getAndSetAcquire(array, ci, VALUE_1);
 360         });
 361 
 362         checkNPE(() -> {
 363             double o = (double) vh.getAndSetRelease(array, ci, VALUE_1);
 364         });
 365 
 366 
 367     }
 368 
 369     static void testArrayUnsupported(ByteArraySource bs, VarHandleSource vhs) {
 370         VarHandle vh = vhs.s;
 371         byte[] array = bs.s;
 372         int ci = 1;
 373 
 374 
 375         checkUOE(() -> {
 376             double o = (double) vh.getAndAdd(array, ci, VALUE_1);
 377         });
 378 
 379         checkUOE(() -> {
 380             double o = (double) vh.getAndAddAcquire(array, ci, VALUE_1);
 381         });
 382 
 383         checkUOE(() -> {
 384             double o = (double) vh.getAndAddRelease(array, ci, VALUE_1);
 385         });
 386 
 387         checkUOE(() -> {
 388             double o = (double) vh.getAndBitwiseOr(array, ci, VALUE_1);
 389         });
 390 
 391         checkUOE(() -> {
 392             double o = (double) vh.getAndBitwiseOrAcquire(array, ci, VALUE_1);
 393         });
 394 
 395         checkUOE(() -> {
 396             double o = (double) vh.getAndBitwiseOrRelease(array, ci, VALUE_1);
 397         });
 398 
 399         checkUOE(() -> {
 400             double o = (double) vh.getAndBitwiseAnd(array, ci, VALUE_1);
 401         });
 402 
 403         checkUOE(() -> {
 404             double o = (double) vh.getAndBitwiseAndAcquire(array, ci, VALUE_1);
 405         });
 406 
 407         checkUOE(() -> {
 408             double o = (double) vh.getAndBitwiseAndRelease(array, ci, VALUE_1);
 409         });
 410 
 411         checkUOE(() -> {
 412             double o = (double) vh.getAndBitwiseXor(array, ci, VALUE_1);
 413         });
 414 
 415         checkUOE(() -> {
 416             double o = (double) vh.getAndBitwiseXorAcquire(array, ci, VALUE_1);
 417         });
 418 
 419         checkUOE(() -> {
 420             double o = (double) vh.getAndBitwiseXorRelease(array, ci, VALUE_1);
 421         });
 422     }
 423 
 424     static void testArrayUnsupported(ByteBufferSource bs, VarHandleSource vhs) {
 425         VarHandle vh = vhs.s;
 426         ByteBuffer array = bs.s;
 427         int ci = 0;
 428         boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
 429 
 430         if (readOnly) {
 431             checkROBE(() -> {
 432                 vh.set(array, ci, VALUE_1);
 433             });
 434         }
 435 
 436         if (readOnly) {
 437             checkROBE(() -> {
 438                 vh.setVolatile(array, ci, VALUE_1);
 439             });
 440 
 441             checkROBE(() -> {
 442                 vh.setRelease(array, ci, VALUE_1);
 443             });
 444 
 445             checkROBE(() -> {
 446                 vh.setOpaque(array, ci, VALUE_1);
 447             });
 448 
 449             checkROBE(() -> {
 450                 boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
 451             });
 452 
 453             checkROBE(() -> {
 454                 double r = (double) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
 455             });
 456 
 457             checkROBE(() -> {
 458                 double r = (double) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
 459             });
 460 
 461             checkROBE(() -> {
 462                 double r = (double) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
 463             });
 464 
 465             checkROBE(() -> {
 466                 boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
 467             });
 468 
 469             checkROBE(() -> {
 470                 boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
 471             });
 472 
 473             checkROBE(() -> {
 474                 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
 475             });
 476 
 477             checkROBE(() -> {
 478                 boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
 479             });
 480 
 481             checkROBE(() -> {
 482                 double o = (double) vh.getAndSet(array, ci, VALUE_1);
 483             });
 484 
 485             checkROBE(() -> {
 486                 double o = (double) vh.getAndSetAcquire(array, ci, VALUE_1);
 487             });
 488 
 489             checkROBE(() -> {
 490                 double o = (double) vh.getAndSetRelease(array, ci, VALUE_1);
 491             });
 492 
 493 
 494             checkUOE(() -> {
 495                 double o = (double) vh.getAndAdd(array, ci, VALUE_1);
 496             });
 497 
 498             checkUOE(() -> {
 499                 double o = (double) vh.getAndAddAcquire(array, ci, VALUE_1);
 500             });
 501 
 502             checkUOE(() -> {
 503                 double o = (double) vh.getAndAddRelease(array, ci, VALUE_1);
 504             });
 505 
 506             checkUOE(() -> {
 507                 double o = (double) vh.getAndBitwiseOr(array, ci, VALUE_1);
 508             });
 509 
 510             checkUOE(() -> {
 511                 double o = (double) vh.getAndBitwiseOrAcquire(array, ci, VALUE_1);
 512             });
 513 
 514             checkUOE(() -> {
 515                 double o = (double) vh.getAndBitwiseOrRelease(array, ci, VALUE_1);
 516             });
 517 
 518             checkUOE(() -> {
 519                 double o = (double) vh.getAndBitwiseAnd(array, ci, VALUE_1);
 520             });
 521 
 522             checkUOE(() -> {
 523                 double o = (double) vh.getAndBitwiseAndAcquire(array, ci, VALUE_1);
 524             });
 525 
 526             checkUOE(() -> {
 527                 double o = (double) vh.getAndBitwiseAndRelease(array, ci, VALUE_1);
 528             });
 529 
 530             checkUOE(() -> {
 531                 double o = (double) vh.getAndBitwiseXor(array, ci, VALUE_1);
 532             });
 533 
 534             checkUOE(() -> {
 535                 double o = (double) vh.getAndBitwiseXorAcquire(array, ci, VALUE_1);
 536             });
 537 
 538             checkUOE(() -> {
 539                 double o = (double) vh.getAndBitwiseXorRelease(array, ci, VALUE_1);
 540             });
 541         }
 542         else {
 543             checkUOE(() -> {
 544                 double o = (double) vh.getAndAdd(array, ci, VALUE_1);
 545             });
 546 
 547             checkUOE(() -> {
 548                 double o = (double) vh.getAndAddAcquire(array, ci, VALUE_1);
 549             });
 550 
 551             checkUOE(() -> {
 552                 double o = (double) vh.getAndAddRelease(array, ci, VALUE_1);
 553             });
 554             checkUOE(() -> {
 555                 double o = (double) vh.getAndBitwiseOr(array, ci, VALUE_1);
 556             });
 557 
 558             checkUOE(() -> {
 559                 double o = (double) vh.getAndBitwiseOrAcquire(array, ci, VALUE_1);
 560             });
 561 
 562             checkUOE(() -> {
 563                 double o = (double) vh.getAndBitwiseOrRelease(array, ci, VALUE_1);
 564             });
 565 
 566             checkUOE(() -> {
 567                 double o = (double) vh.getAndBitwiseAnd(array, ci, VALUE_1);
 568             });
 569 
 570             checkUOE(() -> {
 571                 double o = (double) vh.getAndBitwiseAndAcquire(array, ci, VALUE_1);
 572             });
 573 
 574             checkUOE(() -> {
 575                 double o = (double) vh.getAndBitwiseAndRelease(array, ci, VALUE_1);
 576             });
 577 
 578             checkUOE(() -> {
 579                 double o = (double) vh.getAndBitwiseXor(array, ci, VALUE_1);
 580             });
 581 
 582             checkUOE(() -> {
 583                 double o = (double) vh.getAndBitwiseXorAcquire(array, ci, VALUE_1);
 584             });
 585 
 586             checkUOE(() -> {
 587                 double o = (double) vh.getAndBitwiseXorRelease(array, ci, VALUE_1);
 588             });
 589         }
 590     }
 591 
 592 
 593     static void testArrayIndexOutOfBounds(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
 594         VarHandle vh = vhs.s;
 595         byte[] array = bs.s;
 596 
 597         int length = array.length - SIZE + 1;
 598         for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
 599             final int ci = i;
 600 
 601             checkIOOBE(() -> {
 602                 double x = (double) vh.get(array, ci);
 603             });
 604 
 605             checkIOOBE(() -> {
 606                 vh.set(array, ci, VALUE_1);
 607             });
 608 
 609             checkIOOBE(() -> {
 610                 double x = (double) vh.getVolatile(array, ci);
 611             });
 612 
 613             checkIOOBE(() -> {
 614                 double x = (double) vh.getAcquire(array, ci);
 615             });
 616 
 617             checkIOOBE(() -> {
 618                 double x = (double) vh.getOpaque(array, ci);
 619             });
 620 
 621             checkIOOBE(() -> {
 622                 vh.setVolatile(array, ci, VALUE_1);
 623             });
 624 
 625             checkIOOBE(() -> {
 626                 vh.setRelease(array, ci, VALUE_1);
 627             });
 628 
 629             checkIOOBE(() -> {
 630                 vh.setOpaque(array, ci, VALUE_1);
 631             });
 632 
 633             checkIOOBE(() -> {
 634                 boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
 635             });
 636 
 637             checkIOOBE(() -> {
 638                 double r = (double) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
 639             });
 640 
 641             checkIOOBE(() -> {
 642                 double r = (double) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
 643             });
 644 
 645             checkIOOBE(() -> {
 646                 double r = (double) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
 647             });
 648 
 649             checkIOOBE(() -> {
 650                 boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
 651             });
 652 
 653             checkIOOBE(() -> {
 654                 boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
 655             });
 656 
 657             checkIOOBE(() -> {
 658                 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
 659             });
 660 
 661             checkIOOBE(() -> {
 662                 boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
 663             });
 664 
 665             checkIOOBE(() -> {
 666                 double o = (double) vh.getAndSet(array, ci, VALUE_1);
 667             });
 668 
 669             checkIOOBE(() -> {
 670                 double o = (double) vh.getAndSetAcquire(array, ci, VALUE_1);
 671             });
 672 
 673             checkIOOBE(() -> {
 674                 double o = (double) vh.getAndSetRelease(array, ci, VALUE_1);
 675             });
 676 
 677 
 678 
 679         }
 680     }
 681 
 682     static void testArrayIndexOutOfBounds(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
 683         VarHandle vh = vhs.s;
 684         ByteBuffer array = bs.s;
 685 
 686         boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
 687 
 688         int length = array.limit() - SIZE + 1;
 689         for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
 690             final int ci = i;
 691 
 692             checkIOOBE(() -> {
 693                 double x = (double) vh.get(array, ci);
 694             });
 695 
 696             if (!readOnly) {
 697                 checkIOOBE(() -> {
 698                     vh.set(array, ci, VALUE_1);
 699                 });
 700             }
 701 
 702             checkIOOBE(() -> {
 703                 double x = (double) vh.getVolatile(array, ci);
 704             });
 705 
 706             checkIOOBE(() -> {
 707                 double x = (double) vh.getAcquire(array, ci);
 708             });
 709 
 710             checkIOOBE(() -> {
 711                 double x = (double) vh.getOpaque(array, ci);
 712             });
 713 
 714             if (!readOnly) {
 715                 checkIOOBE(() -> {
 716                     vh.setVolatile(array, ci, VALUE_1);
 717                 });
 718 
 719                 checkIOOBE(() -> {
 720                     vh.setRelease(array, ci, VALUE_1);
 721                 });
 722 
 723                 checkIOOBE(() -> {
 724                     vh.setOpaque(array, ci, VALUE_1);
 725                 });
 726 
 727                 checkIOOBE(() -> {
 728                     boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
 729                 });
 730 
 731                 checkIOOBE(() -> {
 732                     double r = (double) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
 733                 });
 734 
 735                 checkIOOBE(() -> {
 736                     double r = (double) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
 737                 });
 738 
 739                 checkIOOBE(() -> {
 740                     double r = (double) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
 741                 });
 742 
 743                 checkIOOBE(() -> {
 744                     boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
 745                 });
 746 
 747                 checkIOOBE(() -> {
 748                     boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
 749                 });
 750 
 751                 checkIOOBE(() -> {
 752                     boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
 753                 });
 754 
 755                 checkIOOBE(() -> {
 756                     boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
 757                 });
 758 
 759                 checkIOOBE(() -> {
 760                     double o = (double) vh.getAndSet(array, ci, VALUE_1);
 761                 });
 762 
 763                 checkIOOBE(() -> {
 764                     double o = (double) vh.getAndSetAcquire(array, ci, VALUE_1);
 765                 });
 766 
 767                 checkIOOBE(() -> {
 768                     double o = (double) vh.getAndSetRelease(array, ci, VALUE_1);
 769                 });
 770 
 771 
 772             }
 773         }
 774     }
 775 
 776     static void testArrayMisalignedAccess(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
 777         VarHandle vh = vhs.s;
 778         byte[] array = bs.s;
 779 
 780         int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
 781 
 782         int length = array.length - SIZE + 1;
 783         for (int i = 0; i < length; i++) {
 784             boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
 785             final int ci = i;
 786 
 787             if (!iAligned) {
 788                 checkISE(() -> {
 789                     double x = (double) vh.getVolatile(array, ci);
 790                 });
 791 
 792                 checkISE(() -> {
 793                     double x = (double) vh.getAcquire(array, ci);
 794                 });
 795 
 796                 checkISE(() -> {
 797                     double x = (double) vh.getOpaque(array, ci);
 798                 });
 799 
 800                 checkISE(() -> {
 801                     vh.setVolatile(array, ci, VALUE_1);
 802                 });
 803 
 804                 checkISE(() -> {
 805                     vh.setRelease(array, ci, VALUE_1);
 806                 });
 807 
 808                 checkISE(() -> {
 809                     vh.setOpaque(array, ci, VALUE_1);
 810                 });
 811 
 812                 checkISE(() -> {
 813                     boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
 814                 });
 815 
 816                 checkISE(() -> {
 817                     double r = (double) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
 818                 });
 819 
 820                 checkISE(() -> {
 821                     double r = (double) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
 822                 });
 823 
 824                 checkISE(() -> {
 825                     double r = (double) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
 826                 });
 827 
 828                 checkISE(() -> {
 829                     boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
 830                 });
 831 
 832                 checkISE(() -> {
 833                     boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
 834                 });
 835 
 836                 checkISE(() -> {
 837                     boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
 838                 });
 839 
 840                 checkISE(() -> {
 841                     boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
 842                 });
 843 
 844                 checkISE(() -> {
 845                     double o = (double) vh.getAndSet(array, ci, VALUE_1);
 846                 });
 847 
 848                 checkISE(() -> {
 849                     double o = (double) vh.getAndSetAcquire(array, ci, VALUE_1);
 850                 });
 851 
 852                 checkISE(() -> {
 853                     double o = (double) vh.getAndSetRelease(array, ci, VALUE_1);
 854                 });
 855 
 856 
 857             }
 858         }
 859     }
 860 
 861     static void testArrayMisalignedAccess(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
 862         VarHandle vh = vhs.s;
 863         ByteBuffer array = bs.s;
 864 
 865         boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
 866         int misalignmentAtZero = array.alignmentOffset(0, SIZE);
 867 
 868         int length = array.limit() - SIZE + 1;
 869         for (int i = 0; i < length; i++) {
 870             boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
 871             final int ci = i;
 872 
 873             if (!iAligned) {
 874                 checkISE(() -> {
 875                     double x = (double) vh.getVolatile(array, ci);
 876                 });
 877 
 878                 checkISE(() -> {
 879                     double x = (double) vh.getAcquire(array, ci);
 880                 });
 881 
 882                 checkISE(() -> {
 883                     double x = (double) vh.getOpaque(array, ci);
 884                 });
 885 
 886                 if (!readOnly) {
 887                     checkISE(() -> {
 888                         vh.setVolatile(array, ci, VALUE_1);
 889                     });
 890 
 891                     checkISE(() -> {
 892                         vh.setRelease(array, ci, VALUE_1);
 893                     });
 894 
 895                     checkISE(() -> {
 896                         vh.setOpaque(array, ci, VALUE_1);
 897                     });
 898 
 899                     checkISE(() -> {
 900                         boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
 901                     });
 902 
 903                     checkISE(() -> {
 904                         double r = (double) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
 905                     });
 906 
 907                     checkISE(() -> {
 908                         double r = (double) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
 909                     });
 910 
 911                     checkISE(() -> {
 912                         double r = (double) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
 913                     });
 914 
 915                     checkISE(() -> {
 916                         boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
 917                     });
 918 
 919                     checkISE(() -> {
 920                         boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
 921                     });
 922 
 923                     checkISE(() -> {
 924                         boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
 925                     });
 926 
 927                     checkISE(() -> {
 928                         boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
 929                     });
 930 
 931                     checkISE(() -> {
 932                         double o = (double) vh.getAndSet(array, ci, VALUE_1);
 933                     });
 934 
 935                     checkISE(() -> {
 936                         double o = (double) vh.getAndSetAcquire(array, ci, VALUE_1);
 937                     });
 938 
 939                     checkISE(() -> {
 940                         double o = (double) vh.getAndSetRelease(array, ci, VALUE_1);
 941                     });
 942 
 943 
 944                 }
 945             }
 946         }
 947     }
 948 
 949     static void testArrayReadWrite(ByteArraySource bs, VarHandleSource vhs) {
 950         VarHandle vh = vhs.s;
 951         byte[] array = bs.s;
 952 
 953         int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
 954 
 955         bs.fill((byte) 0xff);
 956         int length = array.length - SIZE + 1;
 957         for (int i = 0; i < length; i++) {
 958             boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
 959 
 960             // Plain
 961             {
 962                 vh.set(array, i, VALUE_1);
 963                 double x = (double) vh.get(array, i);
 964                 assertEquals(x, VALUE_1, "get double value");
 965             }
 966 
 967 
 968             if (iAligned) {
 969                 // Volatile
 970                 {
 971                     vh.setVolatile(array, i, VALUE_2);
 972                     double x = (double) vh.getVolatile(array, i);
 973                     assertEquals(x, VALUE_2, "setVolatile double value");
 974                 }
 975 
 976                 // Lazy
 977                 {
 978                     vh.setRelease(array, i, VALUE_1);
 979                     double x = (double) vh.getAcquire(array, i);
 980                     assertEquals(x, VALUE_1, "setRelease double value");
 981                 }
 982 
 983                 // Opaque
 984                 {
 985                     vh.setOpaque(array, i, VALUE_2);
 986                     double x = (double) vh.getOpaque(array, i);
 987                     assertEquals(x, VALUE_2, "setOpaque double value");
 988                 }
 989 
 990                 vh.set(array, i, VALUE_1);
 991 
 992                 // Compare
 993                 {
 994                     boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2);
 995                     assertEquals(r, true, "success compareAndSet double");
 996                     double x = (double) vh.get(array, i);
 997                     assertEquals(x, VALUE_2, "success compareAndSet double value");
 998                 }
 999 
1000                 {
1001                     boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3);
1002                     assertEquals(r, false, "failing compareAndSet double");
1003                     double x = (double) vh.get(array, i);
1004                     assertEquals(x, VALUE_2, "failing compareAndSet double value");
1005                 }
1006 
1007                 {
1008                     double r = (double) vh.compareAndExchange(array, i, VALUE_2, VALUE_1);
1009                     assertEquals(r, VALUE_2, "success compareAndExchange double");
1010                     double x = (double) vh.get(array, i);
1011                     assertEquals(x, VALUE_1, "success compareAndExchange double value");
1012                 }
1013 
1014                 {
1015                     double r = (double) vh.compareAndExchange(array, i, VALUE_2, VALUE_3);
1016                     assertEquals(r, VALUE_1, "failing compareAndExchange double");
1017                     double x = (double) vh.get(array, i);
1018                     assertEquals(x, VALUE_1, "failing compareAndExchange double value");
1019                 }
1020 
1021                 {
1022                     double r = (double) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2);
1023                     assertEquals(r, VALUE_1, "success compareAndExchangeAcquire double");
1024                     double x = (double) vh.get(array, i);
1025                     assertEquals(x, VALUE_2, "success compareAndExchangeAcquire double value");
1026                 }
1027 
1028                 {
1029                     double r = (double) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3);
1030                     assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire double");
1031                     double x = (double) vh.get(array, i);
1032                     assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire double value");
1033                 }
1034 
1035                 {
1036                     double r = (double) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1);
1037                     assertEquals(r, VALUE_2, "success compareAndExchangeRelease double");
1038                     double x = (double) vh.get(array, i);
1039                     assertEquals(x, VALUE_1, "success compareAndExchangeRelease double value");
1040                 }
1041 
1042                 {
1043                     double r = (double) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3);
1044                     assertEquals(r, VALUE_1, "failing compareAndExchangeRelease double");
1045                     double x = (double) vh.get(array, i);
1046                     assertEquals(x, VALUE_1, "failing compareAndExchangeRelease double value");
1047                 }
1048 
1049                 {
1050                     boolean success = false;
1051                     for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
1052                         success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_2);
1053                     }
1054                     assertEquals(success, true, "weakCompareAndSetPlain double");
1055                     double x = (double) vh.get(array, i);
1056                     assertEquals(x, VALUE_2, "weakCompareAndSetPlain double value");
1057                 }
1058 
1059                 {
1060                     boolean success = false;
1061                     for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
1062                         success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1);
1063                     }
1064                     assertEquals(success, true, "weakCompareAndSetAcquire double");
1065                     double x = (double) vh.get(array, i);
1066                     assertEquals(x, VALUE_1, "weakCompareAndSetAcquire double");
1067                 }
1068 
1069                 {
1070                     boolean success = false;
1071                     for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
1072                         success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2);
1073                     }
1074                     assertEquals(success, true, "weakCompareAndSetRelease double");
1075                     double x = (double) vh.get(array, i);
1076                     assertEquals(x, VALUE_2, "weakCompareAndSetRelease double");
1077                 }
1078 
1079                 {
1080                     boolean success = false;
1081                     for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
1082                         success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_1);
1083                     }
1084                     assertEquals(success, true, "weakCompareAndSet double");
1085                     double x = (double) vh.get(array, i);
1086                     assertEquals(x, VALUE_1, "weakCompareAndSet double");
1087                 }
1088 
1089                 // Compare set and get
1090                 {
1091                     vh.set(array, i, VALUE_1);
1092 
1093                     double o = (double) vh.getAndSet(array, i, VALUE_2);
1094                     assertEquals(o, VALUE_1, "getAndSet double");
1095                     double x = (double) vh.get(array, i);
1096                     assertEquals(x, VALUE_2, "getAndSet double value");
1097                 }
1098 
1099                 {
1100                     vh.set(array, i, VALUE_1);
1101 
1102                     double o = (double) vh.getAndSetAcquire(array, i, VALUE_2);
1103                     assertEquals(o, VALUE_1, "getAndSetAcquire double");
1104                     double x = (double) vh.get(array, i);
1105                     assertEquals(x, VALUE_2, "getAndSetAcquire double value");
1106                 }
1107 
1108                 {
1109                     vh.set(array, i, VALUE_1);
1110 
1111                     double o = (double) vh.getAndSetRelease(array, i, VALUE_2);
1112                     assertEquals(o, VALUE_1, "getAndSetRelease double");
1113                     double x = (double) vh.get(array, i);
1114                     assertEquals(x, VALUE_2, "getAndSetRelease double value");
1115                 }
1116 
1117 
1118             }
1119         }
1120     }
1121 
1122 
1123     static void testArrayReadWrite(ByteBufferSource bs, VarHandleSource vhs) {
1124         VarHandle vh = vhs.s;
1125         ByteBuffer array = bs.s;
1126 
1127         int misalignmentAtZero = array.alignmentOffset(0, SIZE);
1128 
1129         bs.fill((byte) 0xff);
1130         int length = array.limit() - SIZE + 1;
1131         for (int i = 0; i < length; i++) {
1132             boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
1133 
1134             // Plain
1135             {
1136                 vh.set(array, i, VALUE_1);
1137                 double x = (double) vh.get(array, i);
1138                 assertEquals(x, VALUE_1, "get double value");
1139             }
1140 
1141             if (iAligned) {
1142                 // Volatile
1143                 {
1144                     vh.setVolatile(array, i, VALUE_2);
1145                     double x = (double) vh.getVolatile(array, i);
1146                     assertEquals(x, VALUE_2, "setVolatile double value");
1147                 }
1148 
1149                 // Lazy
1150                 {
1151                     vh.setRelease(array, i, VALUE_1);
1152                     double x = (double) vh.getAcquire(array, i);
1153                     assertEquals(x, VALUE_1, "setRelease double value");
1154                 }
1155 
1156                 // Opaque
1157                 {
1158                     vh.setOpaque(array, i, VALUE_2);
1159                     double x = (double) vh.getOpaque(array, i);
1160                     assertEquals(x, VALUE_2, "setOpaque double value");
1161                 }
1162 
1163                 vh.set(array, i, VALUE_1);
1164 
1165                 // Compare
1166                 {
1167                     boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2);
1168                     assertEquals(r, true, "success compareAndSet double");
1169                     double x = (double) vh.get(array, i);
1170                     assertEquals(x, VALUE_2, "success compareAndSet double value");
1171                 }
1172 
1173                 {
1174                     boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3);
1175                     assertEquals(r, false, "failing compareAndSet double");
1176                     double x = (double) vh.get(array, i);
1177                     assertEquals(x, VALUE_2, "failing compareAndSet double value");
1178                 }
1179 
1180                 {
1181                     double r = (double) vh.compareAndExchange(array, i, VALUE_2, VALUE_1);
1182                     assertEquals(r, VALUE_2, "success compareAndExchange double");
1183                     double x = (double) vh.get(array, i);
1184                     assertEquals(x, VALUE_1, "success compareAndExchange double value");
1185                 }
1186 
1187                 {
1188                     double r = (double) vh.compareAndExchange(array, i, VALUE_2, VALUE_3);
1189                     assertEquals(r, VALUE_1, "failing compareAndExchange double");
1190                     double x = (double) vh.get(array, i);
1191                     assertEquals(x, VALUE_1, "failing compareAndExchange double value");
1192                 }
1193 
1194                 {
1195                     double r = (double) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2);
1196                     assertEquals(r, VALUE_1, "success compareAndExchangeAcquire double");
1197                     double x = (double) vh.get(array, i);
1198                     assertEquals(x, VALUE_2, "success compareAndExchangeAcquire double value");
1199                 }
1200 
1201                 {
1202                     double r = (double) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3);
1203                     assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire double");
1204                     double x = (double) vh.get(array, i);
1205                     assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire double value");
1206                 }
1207 
1208                 {
1209                     double r = (double) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1);
1210                     assertEquals(r, VALUE_2, "success compareAndExchangeRelease double");
1211                     double x = (double) vh.get(array, i);
1212                     assertEquals(x, VALUE_1, "success compareAndExchangeRelease double value");
1213                 }
1214 
1215                 {
1216                     double r = (double) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3);
1217                     assertEquals(r, VALUE_1, "failing compareAndExchangeRelease double");
1218                     double x = (double) vh.get(array, i);
1219                     assertEquals(x, VALUE_1, "failing compareAndExchangeRelease double value");
1220                 }
1221 
1222                 {
1223                     boolean success = false;
1224                     for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
1225                         success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_2);
1226                     }
1227                     assertEquals(success, true, "weakCompareAndSetPlain double");
1228                     double x = (double) vh.get(array, i);
1229                     assertEquals(x, VALUE_2, "weakCompareAndSetPlain double value");
1230                 }
1231 
1232                 {
1233                     boolean success = false;
1234                     for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
1235                         success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1);
1236                     }
1237                     assertEquals(success, true, "weakCompareAndSetAcquire double");
1238                     double x = (double) vh.get(array, i);
1239                     assertEquals(x, VALUE_1, "weakCompareAndSetAcquire double");
1240                 }
1241 
1242                 {
1243                     boolean success = false;
1244                     for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
1245                         success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2);
1246                     }
1247                     assertEquals(success, true, "weakCompareAndSetRelease double");
1248                     double x = (double) vh.get(array, i);
1249                     assertEquals(x, VALUE_2, "weakCompareAndSetRelease double");
1250                 }
1251 
1252                 {
1253                     boolean success = false;
1254                     for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
1255                         success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_1);
1256                     }
1257                     assertEquals(success, true, "weakCompareAndSet double");
1258                     double x = (double) vh.get(array, i);
1259                     assertEquals(x, VALUE_1, "weakCompareAndSet double");
1260                 }
1261 
1262                 // Compare set and get
1263                 {
1264                     vh.set(array, i, VALUE_1);
1265 
1266                     double o = (double) vh.getAndSet(array, i, VALUE_2);
1267                     assertEquals(o, VALUE_1, "getAndSet double");
1268                     double x = (double) vh.get(array, i);
1269                     assertEquals(x, VALUE_2, "getAndSet double value");
1270                 }
1271 
1272                 {
1273                     vh.set(array, i, VALUE_1);
1274 
1275                     double o = (double) vh.getAndSetAcquire(array, i, VALUE_2);
1276                     assertEquals(o, VALUE_1, "getAndSetAcquire double");
1277                     double x = (double) vh.get(array, i);
1278                     assertEquals(x, VALUE_2, "getAndSetAcquire double value");
1279                 }
1280 
1281                 {
1282                     vh.set(array, i, VALUE_1);
1283 
1284                     double o = (double) vh.getAndSetRelease(array, i, VALUE_2);
1285                     assertEquals(o, VALUE_1, "getAndSetRelease double");
1286                     double x = (double) vh.get(array, i);
1287                     assertEquals(x, VALUE_2, "getAndSetRelease double value");
1288                 }
1289 
1290 
1291             }
1292         }
1293     }
1294 
1295     static void testArrayReadOnly(ByteBufferSource bs, VarHandleSource vhs) {
1296         VarHandle vh = vhs.s;
1297         ByteBuffer array = bs.s;
1298 
1299         int misalignmentAtZero = array.alignmentOffset(0, SIZE);
1300 
1301         ByteBuffer bb = ByteBuffer.allocate(SIZE);
1302         bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN);
1303         bs.fill(bb.putDouble(0, VALUE_2).array());
1304 
1305         int length = array.limit() - SIZE + 1;
1306         for (int i = 0; i < length; i++) {
1307             boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
1308 
1309             double v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes)
1310                     ? rotateLeft(VALUE_2, (i % SIZE) << 3)
1311                     : rotateRight(VALUE_2, (i % SIZE) << 3);
1312             // Plain
1313             {
1314                 double x = (double) vh.get(array, i);
1315                 assertEquals(x, v, "get double value");
1316             }
1317 
1318             if (iAligned) {
1319                 // Volatile
1320                 {
1321                     double x = (double) vh.getVolatile(array, i);
1322                     assertEquals(x, v, "getVolatile double value");
1323                 }
1324 
1325                 // Lazy
1326                 {
1327                     double x = (double) vh.getAcquire(array, i);
1328                     assertEquals(x, v, "getRelease double value");
1329                 }
1330 
1331                 // Opaque
1332                 {
1333                     double x = (double) vh.getOpaque(array, i);
1334                     assertEquals(x, v, "getOpaque double value");
1335                 }
1336             }
1337         }
1338     }
1339 
1340 }
1341