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