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