1 /*
   2  * Copyright (c) 2015, 2016, 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  * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsLong
  27  * @run testng/othervm -Diters=20000                         VarHandleTestByteArrayAsLong
  28  * @run testng/othervm -Diters=20000 -XX:-TieredCompilation  VarHandleTestByteArrayAsLong
  29  */
  30 
  31 import org.testng.annotations.DataProvider;
  32 import org.testng.annotations.Test;
  33 
  34 import java.lang.invoke.MethodHandles;
  35 import java.lang.invoke.VarHandle;
  36 import java.nio.ByteBuffer;
  37 import java.nio.ByteOrder;
  38 import java.util.ArrayList;
  39 import java.util.Arrays;
  40 import java.util.EnumSet;
  41 import java.util.List;
  42 
  43 import static org.testng.Assert.*;
  44 
  45 public class VarHandleTestByteArrayAsLong extends VarHandleBaseByteArrayTest {
  46     static final int SIZE = Long.BYTES;
  47 
  48     static final long VALUE_1 = 0x0102030405060708L;
  49 
  50     static final long VALUE_2 = 0x1112131415161718L;
  51 
  52     static final long VALUE_3 = 0x2122232425262728L;
  53 
  54 
  55     @Override
  56     public void setupVarHandleSources() {
  57         // Combinations of VarHandle byte[] or ByteBuffer
  58         vhss = new ArrayList<>();
  59         for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) {
  60             VarHandleSource aeh = new VarHandleSource(
  61                     MethodHandles.byteArrayViewVarHandle(long[].class,
  62                                                          endianess == MemoryMode.BIG_ENDIAN),
  63                     endianess, MemoryMode.READ_WRITE);
  64             vhss.add(aeh);
  65 
  66             VarHandleSource bbh = new VarHandleSource(
  67                     MethodHandles.byteBufferViewVarHandle(long[].class,
  68                                                           endianess == MemoryMode.BIG_ENDIAN),
  69                     endianess, MemoryMode.READ_WRITE);
  70             vhss.add(bbh);
  71         }
  72     }
  73 
  74 
  75     @Test(dataProvider = "varHandlesProvider")
  76     public void testIsAccessModeSupported(VarHandleSource vhs) {
  77         VarHandle vh = vhs.s;
  78 
  79         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET));
  80         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET));
  81 
  82         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_VOLATILE));
  83         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_VOLATILE));
  84         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_ACQUIRE));
  85         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_RELEASE));
  86         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_OPAQUE));
  87         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_OPAQUE));
  88 
  89         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_SET));
  90         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_VOLATILE));
  91         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
  92         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
  93         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
  94         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
  95         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
  96         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
  97 
  98         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
  99         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.ADD_AND_GET));
 100     }
 101 
 102     @Test(dataProvider = "typesProvider")
 103     public void testTypes(VarHandle vh, List<java.lang.Class<?>> pts) {
 104         assertEquals(vh.varType(), long.class);
 105 
 106         assertEquals(vh.coordinateTypes(), pts);
 107 
 108         testTypes(vh);
 109     }
 110 
 111 
 112     @DataProvider
 113     public Object[][] accessTestCaseProvider() throws Exception {
 114         List<AccessTestCase<?>> cases = new ArrayList<>();
 115 
 116         for (ByteArrayViewSource<?> bav : bavss) {
 117             for (VarHandleSource vh : vhss) {
 118                 if (vh.matches(bav)) {
 119                     if (bav instanceof ByteArraySource) {
 120                         ByteArraySource bas = (ByteArraySource) bav;
 121 
 122                         cases.add(new VarHandleSourceAccessTestCase(
 123                                 "read write", bav, vh, h -> testArrayReadWrite(bas, h),
 124                                 true));
 125                         cases.add(new VarHandleSourceAccessTestCase(
 126                                 "unsupported", bav, vh, h -> testArrayUnsupported(bas, h),
 127                                 false));
 128                         cases.add(new VarHandleSourceAccessTestCase(
 129                                 "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bas, h),
 130                                 false));
 131                         cases.add(new VarHandleSourceAccessTestCase(
 132                                 "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bas, h),
 133                                 false));
 134                     }
 135                     else {
 136                         ByteBufferSource bbs = (ByteBufferSource) bav;
 137 
 138                         if (MemoryMode.READ_WRITE.isSet(bav.memoryModes)) {
 139                             cases.add(new VarHandleSourceAccessTestCase(
 140                                     "read write", bav, vh, h -> testArrayReadWrite(bbs, h),
 141                                     true));
 142                         }
 143                         else {
 144                             cases.add(new VarHandleSourceAccessTestCase(
 145                                     "read only", bav, vh, h -> testArrayReadOnly(bbs, h),
 146                                     true));
 147                         }
 148 
 149                         cases.add(new VarHandleSourceAccessTestCase(
 150                                 "unsupported", bav, vh, h -> testArrayUnsupported(bbs, h),
 151                                 false));
 152                         cases.add(new VarHandleSourceAccessTestCase(
 153                                 "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bbs, h),
 154                                 false));
 155                         cases.add(new VarHandleSourceAccessTestCase(
 156                                 "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bbs, h),
 157                                 false));
 158                     }
 159                 }
 160             }
 161         }
 162 
 163         // Work around issue with jtreg summary reporting which truncates
 164         // the String result of Object.toString to 30 characters, hence
 165         // the first dummy argument
 166         return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
 167     }
 168 
 169     @Test(dataProvider = "accessTestCaseProvider")
 170     public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
 171         T t = atc.get();
 172         int iters = atc.requiresLoop() ? ITERS : 1;
 173         for (int c = 0; c < iters; c++) {
 174             atc.testAccess(t);
 175         }
 176     }
 177 
 178 
 179     static void testArrayUnsupported(ByteArraySource bs, VarHandleSource vhs) {
 180         VarHandle vh = vhs.s;
 181         byte[] array = bs.s;
 182         int ci = 1;
 183 
 184 
 185     }
 186 
 187     static void testArrayUnsupported(ByteBufferSource bs, VarHandleSource vhs) {
 188         VarHandle vh = vhs.s;
 189         ByteBuffer array = bs.s;
 190         int ci = 0;
 191         boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
 192 
 193         if (readOnly) {
 194             checkROBE(() -> {
 195                 vh.set(array, ci, VALUE_1);
 196             });
 197         }
 198 
 199         if (readOnly) {
 200             checkROBE(() -> {
 201                 vh.setVolatile(array, ci, VALUE_1);
 202             });
 203 
 204             checkROBE(() -> {
 205                 vh.setRelease(array, ci, VALUE_1);
 206             });
 207 
 208             checkROBE(() -> {
 209                 vh.setOpaque(array, ci, VALUE_1);
 210             });
 211 
 212             checkROBE(() -> {
 213                 boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
 214             });
 215 
 216             checkROBE(() -> {
 217                 long r = (long) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
 218             });
 219 
 220             checkROBE(() -> {
 221                 long r = (long) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
 222             });
 223 
 224             checkROBE(() -> {
 225                 long r = (long) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
 226             });
 227 
 228             checkROBE(() -> {
 229                 boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
 230             });
 231 
 232             checkROBE(() -> {
 233                 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
 234             });
 235 
 236             checkROBE(() -> {
 237                 boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
 238             });
 239 
 240             checkROBE(() -> {
 241                 long o = (long) vh.getAndSet(array, ci, VALUE_1);
 242             });
 243             checkUOE(() -> {
 244                 boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
 245             });
 246 
 247             checkROBE(() -> {
 248                 long o = (long) vh.getAndAdd(array, ci, VALUE_1);
 249             });
 250 
 251             checkROBE(() -> {
 252                 long o = (long) vh.addAndGet(array, ci, VALUE_1);
 253             });
 254         }
 255         else {
 256         }
 257     }
 258 
 259 
 260     static void testArrayIndexOutOfBounds(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
 261         VarHandle vh = vhs.s;
 262         byte[] array = bs.s;
 263 
 264         int length = array.length - SIZE + 1;
 265         for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
 266             final int ci = i;
 267 
 268             checkIOOBE(() -> {
 269                 long x = (long) vh.get(array, ci);
 270             });
 271 
 272             checkIOOBE(() -> {
 273                 vh.set(array, ci, VALUE_1);
 274             });
 275 
 276             checkIOOBE(() -> {
 277                 long x = (long) vh.getVolatile(array, ci);
 278             });
 279 
 280             checkIOOBE(() -> {
 281                 long x = (long) vh.getAcquire(array, ci);
 282             });
 283 
 284             checkIOOBE(() -> {
 285                 long x = (long) vh.getOpaque(array, ci);
 286             });
 287 
 288             checkIOOBE(() -> {
 289                 vh.setVolatile(array, ci, VALUE_1);
 290             });
 291 
 292             checkIOOBE(() -> {
 293                 vh.setRelease(array, ci, VALUE_1);
 294             });
 295 
 296             checkIOOBE(() -> {
 297                 vh.setOpaque(array, ci, VALUE_1);
 298             });
 299 
 300             checkIOOBE(() -> {
 301                 boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
 302             });
 303 
 304             checkIOOBE(() -> {
 305                 long r = (long) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
 306             });
 307 
 308             checkIOOBE(() -> {
 309                 long r = (long) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
 310             });
 311 
 312             checkIOOBE(() -> {
 313                 long r = (long) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
 314             });
 315 
 316             checkIOOBE(() -> {
 317                 boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
 318             });
 319 
 320             checkIOOBE(() -> {
 321                 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
 322             });
 323 
 324             checkIOOBE(() -> {
 325                 boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
 326             });
 327 
 328             checkIOOBE(() -> {
 329                 long o = (long) vh.getAndSet(array, ci, VALUE_1);
 330             });
 331 
 332             checkIOOBE(() -> {
 333                 long o = (long) vh.getAndAdd(array, ci, VALUE_1);
 334             });
 335 
 336             checkIOOBE(() -> {
 337                 long o = (long) vh.addAndGet(array, ci, VALUE_1);
 338             });
 339 
 340         }
 341     }
 342 
 343     static void testArrayIndexOutOfBounds(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
 344         VarHandle vh = vhs.s;
 345         ByteBuffer array = bs.s;
 346 
 347         boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
 348 
 349         int length = array.limit() - SIZE + 1;
 350         for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
 351             final int ci = i;
 352 
 353             checkIOOBE(() -> {
 354                 long x = (long) vh.get(array, ci);
 355             });
 356 
 357             if (!readOnly) {
 358                 checkIOOBE(() -> {
 359                     vh.set(array, ci, VALUE_1);
 360                 });
 361             }
 362 
 363             checkIOOBE(() -> {
 364                 long x = (long) vh.getVolatile(array, ci);
 365             });
 366 
 367             checkIOOBE(() -> {
 368                 long x = (long) vh.getAcquire(array, ci);
 369             });
 370 
 371             checkIOOBE(() -> {
 372                 long x = (long) vh.getOpaque(array, ci);
 373             });
 374 
 375             if (!readOnly) {
 376                 checkIOOBE(() -> {
 377                     vh.setVolatile(array, ci, VALUE_1);
 378                 });
 379 
 380                 checkIOOBE(() -> {
 381                     vh.setRelease(array, ci, VALUE_1);
 382                 });
 383 
 384                 checkIOOBE(() -> {
 385                     vh.setOpaque(array, ci, VALUE_1);
 386                 });
 387 
 388                 checkIOOBE(() -> {
 389                     boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
 390                 });
 391 
 392                 checkIOOBE(() -> {
 393                     long r = (long) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
 394                 });
 395 
 396                 checkIOOBE(() -> {
 397                     long r = (long) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
 398                 });
 399 
 400                 checkIOOBE(() -> {
 401                     long r = (long) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
 402                 });
 403 
 404                 checkIOOBE(() -> {
 405                     boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
 406                 });
 407 
 408                 checkIOOBE(() -> {
 409                     boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
 410                 });
 411 
 412                 checkIOOBE(() -> {
 413                     boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
 414                 });
 415 
 416                 checkIOOBE(() -> {
 417                     long o = (long) vh.getAndSet(array, ci, VALUE_1);
 418                 });
 419 
 420                 checkIOOBE(() -> {
 421                     long o = (long) vh.getAndAdd(array, ci, VALUE_1);
 422                 });
 423 
 424                 checkIOOBE(() -> {
 425                     long o = (long) vh.addAndGet(array, ci, VALUE_1);
 426                 });
 427             }
 428         }
 429     }
 430 
 431     static void testArrayMisalignedAccess(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
 432         VarHandle vh = vhs.s;
 433         byte[] array = bs.s;
 434 
 435         int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
 436 
 437         int length = array.length - SIZE + 1;
 438         for (int i = 0; i < length; i++) {
 439             boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
 440             final int ci = i;
 441 
 442             if (!iAligned) {
 443                 checkISE(() -> {
 444                     long x = (long) vh.getVolatile(array, ci);
 445                 });
 446 
 447                 checkISE(() -> {
 448                     long x = (long) vh.getAcquire(array, ci);
 449                 });
 450 
 451                 checkISE(() -> {
 452                     long x = (long) vh.getOpaque(array, ci);
 453                 });
 454 
 455                 checkISE(() -> {
 456                     vh.setVolatile(array, ci, VALUE_1);
 457                 });
 458 
 459                 checkISE(() -> {
 460                     vh.setRelease(array, ci, VALUE_1);
 461                 });
 462 
 463                 checkISE(() -> {
 464                     vh.setOpaque(array, ci, VALUE_1);
 465                 });
 466 
 467                 checkISE(() -> {
 468                     boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
 469                 });
 470 
 471                 checkISE(() -> {
 472                     long r = (long) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
 473                 });
 474 
 475                 checkISE(() -> {
 476                     long r = (long) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
 477                 });
 478 
 479                 checkISE(() -> {
 480                     long r = (long) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
 481                 });
 482 
 483                 checkISE(() -> {
 484                     boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
 485                 });
 486 
 487                 checkISE(() -> {
 488                     boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
 489                 });
 490 
 491                 checkISE(() -> {
 492                     boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
 493                 });
 494 
 495                 checkISE(() -> {
 496                     long o = (long) vh.getAndSet(array, ci, VALUE_1);
 497                 });
 498 
 499                 checkISE(() -> {
 500                     long o = (long) vh.getAndAdd(array, ci, VALUE_1);
 501                 });
 502 
 503                 checkISE(() -> {
 504                     long o = (long) vh.addAndGet(array, ci, VALUE_1);
 505                 });
 506 
 507             }
 508         }
 509     }
 510 
 511     static void testArrayMisalignedAccess(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
 512         VarHandle vh = vhs.s;
 513         ByteBuffer array = bs.s;
 514 
 515         boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
 516         int misalignmentAtZero = array.alignmentOffset(0, SIZE);
 517 
 518         int length = array.limit() - SIZE + 1;
 519         for (int i = 0; i < length; i++) {
 520             boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
 521             final int ci = i;
 522 
 523             if (!iAligned) {
 524                 checkISE(() -> {
 525                     long x = (long) vh.getVolatile(array, ci);
 526                 });
 527 
 528                 checkISE(() -> {
 529                     long x = (long) vh.getAcquire(array, ci);
 530                 });
 531 
 532                 checkISE(() -> {
 533                     long x = (long) vh.getOpaque(array, ci);
 534                 });
 535 
 536                 if (!readOnly) {
 537                     checkISE(() -> {
 538                         vh.setVolatile(array, ci, VALUE_1);
 539                     });
 540 
 541                     checkISE(() -> {
 542                         vh.setRelease(array, ci, VALUE_1);
 543                     });
 544 
 545                     checkISE(() -> {
 546                         vh.setOpaque(array, ci, VALUE_1);
 547                     });
 548 
 549                     checkISE(() -> {
 550                         boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
 551                     });
 552 
 553                     checkISE(() -> {
 554                         long r = (long) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
 555                     });
 556 
 557                     checkISE(() -> {
 558                         long r = (long) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
 559                     });
 560 
 561                     checkISE(() -> {
 562                         long r = (long) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
 563                     });
 564 
 565                     checkISE(() -> {
 566                         boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
 567                     });
 568 
 569                     checkISE(() -> {
 570                         boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
 571                     });
 572 
 573                     checkISE(() -> {
 574                         boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
 575                     });
 576 
 577                     checkISE(() -> {
 578                         long o = (long) vh.getAndSet(array, ci, VALUE_1);
 579                     });
 580 
 581                     checkISE(() -> {
 582                         long o = (long) vh.getAndAdd(array, ci, VALUE_1);
 583                     });
 584 
 585                     checkISE(() -> {
 586                         long o = (long) vh.addAndGet(array, ci, VALUE_1);
 587                     });
 588                 }
 589             }
 590         }
 591     }
 592 
 593     static void testArrayReadWrite(ByteArraySource bs, VarHandleSource vhs) {
 594         VarHandle vh = vhs.s;
 595         byte[] array = bs.s;
 596 
 597         int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
 598 
 599         bs.fill((byte) 0xff);
 600         int length = array.length - SIZE + 1;
 601         for (int i = 0; i < length; i++) {
 602             boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
 603 
 604             // Plain
 605             {
 606                 vh.set(array, i, VALUE_1);
 607                 long x = (long) vh.get(array, i);
 608                 assertEquals(x, VALUE_1, "get long value");
 609             }
 610 
 611 
 612             if (iAligned) {
 613                 // Volatile
 614                 {
 615                     vh.setVolatile(array, i, VALUE_2);
 616                     long x = (long) vh.getVolatile(array, i);
 617                     assertEquals(x, VALUE_2, "setVolatile long value");
 618                 }
 619 
 620                 // Lazy
 621                 {
 622                     vh.setRelease(array, i, VALUE_1);
 623                     long x = (long) vh.getAcquire(array, i);
 624                     assertEquals(x, VALUE_1, "setRelease long value");
 625                 }
 626 
 627                 // Opaque
 628                 {
 629                     vh.setOpaque(array, i, VALUE_2);
 630                     long x = (long) vh.getOpaque(array, i);
 631                     assertEquals(x, VALUE_2, "setOpaque long value");
 632                 }
 633 
 634                 vh.set(array, i, VALUE_1);
 635 
 636                 // Compare
 637                 {
 638                     boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2);
 639                     assertEquals(r, true, "success compareAndSet long");
 640                     long x = (long) vh.get(array, i);
 641                     assertEquals(x, VALUE_2, "success compareAndSet long value");
 642                 }
 643 
 644                 {
 645                     boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3);
 646                     assertEquals(r, false, "failing compareAndSet long");
 647                     long x = (long) vh.get(array, i);
 648                     assertEquals(x, VALUE_2, "failing compareAndSet long value");
 649                 }
 650 
 651                 {
 652                     long r = (long) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1);
 653                     assertEquals(r, VALUE_2, "success compareAndExchangeVolatile long");
 654                     long x = (long) vh.get(array, i);
 655                     assertEquals(x, VALUE_1, "success compareAndExchangeVolatile long value");
 656                 }
 657 
 658                 {
 659                     long r = (long) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3);
 660                     assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile long");
 661                     long x = (long) vh.get(array, i);
 662                     assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile long value");
 663                 }
 664 
 665                 {
 666                     long r = (long) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2);
 667                     assertEquals(r, VALUE_1, "success compareAndExchangeAcquire long");
 668                     long x = (long) vh.get(array, i);
 669                     assertEquals(x, VALUE_2, "success compareAndExchangeAcquire long value");
 670                 }
 671 
 672                 {
 673                     long r = (long) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3);
 674                     assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire long");
 675                     long x = (long) vh.get(array, i);
 676                     assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire long value");
 677                 }
 678 
 679                 {
 680                     long r = (long) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1);
 681                     assertEquals(r, VALUE_2, "success compareAndExchangeRelease long");
 682                     long x = (long) vh.get(array, i);
 683                     assertEquals(x, VALUE_1, "success compareAndExchangeRelease long value");
 684                 }
 685 
 686                 {
 687                     long r = (long) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3);
 688                     assertEquals(r, VALUE_1, "failing compareAndExchangeRelease long");
 689                     long x = (long) vh.get(array, i);
 690                     assertEquals(x, VALUE_1, "failing compareAndExchangeRelease long value");
 691                 }
 692 
 693                 {
 694                     boolean success = false;
 695                     for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 696                         success = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2);
 697                     }
 698                     assertEquals(success, true, "weakCompareAndSet long");
 699                     long x = (long) vh.get(array, i);
 700                     assertEquals(x, VALUE_2, "weakCompareAndSet long value");
 701                 }
 702 
 703                 {
 704                     boolean success = false;
 705                     for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 706                         success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1);
 707                     }
 708                     assertEquals(success, true, "weakCompareAndSetAcquire long");
 709                     long x = (long) vh.get(array, i);
 710                     assertEquals(x, VALUE_1, "weakCompareAndSetAcquire long");
 711                 }
 712 
 713                 {
 714                     boolean success = false;
 715                     for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 716                         success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2);
 717                     }
 718                     assertEquals(success, true, "weakCompareAndSetRelease long");
 719                     long x = (long) vh.get(array, i);
 720                     assertEquals(x, VALUE_2, "weakCompareAndSetRelease long");
 721                 }
 722 
 723                 // Compare set and get
 724                 {
 725                     long o = (long) vh.getAndSet(array, i, VALUE_1);
 726                     assertEquals(o, VALUE_2, "getAndSet long");
 727                     long x = (long) vh.get(array, i);
 728                     assertEquals(x, VALUE_1, "getAndSet long value");
 729                 }
 730 
 731                 vh.set(array, i, VALUE_1);
 732 
 733                 // get and add, add and get
 734                 {
 735                     long o = (long) vh.getAndAdd(array, i, VALUE_3);
 736                     assertEquals(o, VALUE_1, "getAndAdd long");
 737                     long c = (long) vh.addAndGet(array, i, VALUE_3);
 738                     assertEquals(c, VALUE_1 + VALUE_3 + VALUE_3, "getAndAdd long value");
 739                 }
 740             }
 741         }
 742     }
 743 
 744 
 745     static void testArrayReadWrite(ByteBufferSource bs, VarHandleSource vhs) {
 746         VarHandle vh = vhs.s;
 747         ByteBuffer array = bs.s;
 748 
 749         int misalignmentAtZero = array.alignmentOffset(0, SIZE);
 750 
 751         bs.fill((byte) 0xff);
 752         int length = array.limit() - SIZE + 1;
 753         for (int i = 0; i < length; i++) {
 754             boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
 755 
 756             // Plain
 757             {
 758                 vh.set(array, i, VALUE_1);
 759                 long x = (long) vh.get(array, i);
 760                 assertEquals(x, VALUE_1, "get long value");
 761             }
 762 
 763             if (iAligned) {
 764                 // Volatile
 765                 {
 766                     vh.setVolatile(array, i, VALUE_2);
 767                     long x = (long) vh.getVolatile(array, i);
 768                     assertEquals(x, VALUE_2, "setVolatile long value");
 769                 }
 770 
 771                 // Lazy
 772                 {
 773                     vh.setRelease(array, i, VALUE_1);
 774                     long x = (long) vh.getAcquire(array, i);
 775                     assertEquals(x, VALUE_1, "setRelease long value");
 776                 }
 777 
 778                 // Opaque
 779                 {
 780                     vh.setOpaque(array, i, VALUE_2);
 781                     long x = (long) vh.getOpaque(array, i);
 782                     assertEquals(x, VALUE_2, "setOpaque long value");
 783                 }
 784 
 785                 vh.set(array, i, VALUE_1);
 786 
 787                 // Compare
 788                 {
 789                     boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2);
 790                     assertEquals(r, true, "success compareAndSet long");
 791                     long x = (long) vh.get(array, i);
 792                     assertEquals(x, VALUE_2, "success compareAndSet long value");
 793                 }
 794 
 795                 {
 796                     boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3);
 797                     assertEquals(r, false, "failing compareAndSet long");
 798                     long x = (long) vh.get(array, i);
 799                     assertEquals(x, VALUE_2, "failing compareAndSet long value");
 800                 }
 801 
 802                 {
 803                     long r = (long) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1);
 804                     assertEquals(r, VALUE_2, "success compareAndExchangeVolatile long");
 805                     long x = (long) vh.get(array, i);
 806                     assertEquals(x, VALUE_1, "success compareAndExchangeVolatile long value");
 807                 }
 808 
 809                 {
 810                     long r = (long) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3);
 811                     assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile long");
 812                     long x = (long) vh.get(array, i);
 813                     assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile long value");
 814                 }
 815 
 816                 {
 817                     long r = (long) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2);
 818                     assertEquals(r, VALUE_1, "success compareAndExchangeAcquire long");
 819                     long x = (long) vh.get(array, i);
 820                     assertEquals(x, VALUE_2, "success compareAndExchangeAcquire long value");
 821                 }
 822 
 823                 {
 824                     long r = (long) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3);
 825                     assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire long");
 826                     long x = (long) vh.get(array, i);
 827                     assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire long value");
 828                 }
 829 
 830                 {
 831                     long r = (long) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1);
 832                     assertEquals(r, VALUE_2, "success compareAndExchangeRelease long");
 833                     long x = (long) vh.get(array, i);
 834                     assertEquals(x, VALUE_1, "success compareAndExchangeRelease long value");
 835                 }
 836 
 837                 {
 838                     long r = (long) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3);
 839                     assertEquals(r, VALUE_1, "failing compareAndExchangeRelease long");
 840                     long x = (long) vh.get(array, i);
 841                     assertEquals(x, VALUE_1, "failing compareAndExchangeRelease long value");
 842                 }
 843 
 844                 {
 845                     boolean success = false;
 846                     for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 847                         success = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2);
 848                     }
 849                     assertEquals(success, true, "weakCompareAndSet long");
 850                     long x = (long) vh.get(array, i);
 851                     assertEquals(x, VALUE_2, "weakCompareAndSet long value");
 852                 }
 853 
 854                 {
 855                     boolean success = false;
 856                     for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 857                         success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1);
 858                     }
 859                     assertEquals(success, true, "weakCompareAndSetAcquire long");
 860                     long x = (long) vh.get(array, i);
 861                     assertEquals(x, VALUE_1, "weakCompareAndSetAcquire long");
 862                 }
 863 
 864                 {
 865                     boolean success = false;
 866                     for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 867                         success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2);
 868                     }
 869                     assertEquals(success, true, "weakCompareAndSetRelease long");
 870                     long x = (long) vh.get(array, i);
 871                     assertEquals(x, VALUE_2, "weakCompareAndSetRelease long");
 872                 }
 873 
 874                 // Compare set and get
 875                 {
 876                     long o = (long) vh.getAndSet(array, i, VALUE_1);
 877                     assertEquals(o, VALUE_2, "getAndSet long");
 878                     long x = (long) vh.get(array, i);
 879                     assertEquals(x, VALUE_1, "getAndSet long value");
 880                 }
 881 
 882                 vh.set(array, i, VALUE_1);
 883 
 884                 // get and add, add and get
 885                 {
 886                     long o = (long) vh.getAndAdd(array, i, VALUE_3);
 887                     assertEquals(o, VALUE_1, "getAndAdd long");
 888                     long c = (long) vh.addAndGet(array, i, VALUE_3);
 889                     assertEquals(c, VALUE_1 + VALUE_3 + VALUE_3, "getAndAdd long value");
 890                 }
 891             }
 892         }
 893     }
 894 
 895     static void testArrayReadOnly(ByteBufferSource bs, VarHandleSource vhs) {
 896         VarHandle vh = vhs.s;
 897         ByteBuffer array = bs.s;
 898 
 899         int misalignmentAtZero = array.alignmentOffset(0, SIZE);
 900 
 901         ByteBuffer bb = ByteBuffer.allocate(SIZE);
 902         bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN);
 903         bs.fill(bb.putLong(0, VALUE_2).array());
 904 
 905         int length = array.limit() - SIZE + 1;
 906         for (int i = 0; i < length; i++) {
 907             boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
 908 
 909             long v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes)
 910                     ? rotateLeft(VALUE_2, (i % SIZE) << 3)
 911                     : rotateRight(VALUE_2, (i % SIZE) << 3);
 912             // Plain
 913             {
 914                 long x = (long) vh.get(array, i);
 915                 assertEquals(x, v, "get long value");
 916             }
 917 
 918             if (iAligned) {
 919                 // Volatile
 920                 {
 921                     long x = (long) vh.getVolatile(array, i);
 922                     assertEquals(x, v, "getVolatile long value");
 923                 }
 924 
 925                 // Lazy
 926                 {
 927                     long x = (long) vh.getAcquire(array, i);
 928                     assertEquals(x, v, "getRelease long value");
 929                 }
 930 
 931                 // Opaque
 932                 {
 933                     long x = (long) vh.getOpaque(array, i);
 934                     assertEquals(x, v, "getOpaque long value");
 935                 }
 936             }
 937         }
 938     }
 939 
 940 }
 941