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