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