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