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