X-VarHandleTestByteArrayView.java.template revision 14156:9c64b9eeb312
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 VarHandleTestByteArrayAs$Type$ 27 * @run testng/othervm -Diters=20000 VarHandleTestByteArrayAs$Type$ 28 * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAs$Type$ 29 */ 30 31import org.testng.annotations.DataProvider; 32import org.testng.annotations.Test; 33 34import java.lang.invoke.MethodHandles; 35import java.lang.invoke.VarHandle; 36import java.nio.ByteBuffer; 37import java.nio.ByteOrder; 38import java.util.ArrayList; 39import java.util.Arrays; 40import java.util.EnumSet; 41import java.util.List; 42 43import static org.testng.Assert.*; 44 45public class VarHandleTestByteArrayAs$Type$ extends VarHandleBaseByteArrayTest { 46 static final int SIZE = $BoxType$.BYTES; 47 48 static final $type$ VALUE_1 = $value1$; 49 50 static final $type$ VALUE_2 = $value2$; 51 52 static final $type$ VALUE_3 = $value3$; 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($type$[].class, 62 endianess == MemoryMode.BIG_ENDIAN), 63 endianess, MemoryMode.READ_WRITE); 64 vhss.add(aeh); 65 66 VarHandleSource bbh = new VarHandleSource( 67 MethodHandles.byteBufferViewVarHandle($type$[].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#if[CAS] 90 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_SET)); 91 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_VOLATILE)); 92 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE)); 93 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE)); 94 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET)); 95 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE)); 96 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE)); 97 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET)); 98#else[CAS] 99 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_SET)); 100 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_VOLATILE)); 101 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE)); 102 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE)); 103 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET)); 104 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE)); 105 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE)); 106 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET)); 107#end[CAS] 108 109#if[AtomicAdd] 110 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD)); 111 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.ADD_AND_GET)); 112#else[AtomicAdd] 113 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD)); 114 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.ADD_AND_GET)); 115#end[AtomicAdd] 116 } 117 118 @Test(dataProvider = "typesProvider") 119 public void testTypes(VarHandle vh, List<java.lang.Class<?>> pts) { 120 assertEquals(vh.varType(), $type$.class); 121 122 assertEquals(vh.coordinateTypes(), pts); 123 124 testTypes(vh); 125 } 126 127 128 @DataProvider 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 "unsupported", bav, vh, h -> testArrayUnsupported(bas, h), 143 false)); 144 cases.add(new VarHandleSourceAccessTestCase( 145 "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bas, h), 146 false)); 147 cases.add(new VarHandleSourceAccessTestCase( 148 "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bas, h), 149 false)); 150 } 151 else { 152 ByteBufferSource bbs = (ByteBufferSource) bav; 153 154 if (MemoryMode.READ_WRITE.isSet(bav.memoryModes)) { 155 cases.add(new VarHandleSourceAccessTestCase( 156 "read write", bav, vh, h -> testArrayReadWrite(bbs, h), 157 true)); 158 } 159 else { 160 cases.add(new VarHandleSourceAccessTestCase( 161 "read only", bav, vh, h -> testArrayReadOnly(bbs, h), 162 true)); 163 } 164 165 cases.add(new VarHandleSourceAccessTestCase( 166 "unsupported", bav, vh, h -> testArrayUnsupported(bbs, h), 167 false)); 168 cases.add(new VarHandleSourceAccessTestCase( 169 "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bbs, h), 170 false)); 171 cases.add(new VarHandleSourceAccessTestCase( 172 "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bbs, h), 173 false)); 174 } 175 } 176 } 177 } 178 179 // Work around issue with jtreg summary reporting which truncates 180 // the String result of Object.toString to 30 characters, hence 181 // the first dummy argument 182 return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); 183 } 184 185 @Test(dataProvider = "accessTestCaseProvider") 186 public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable { 187 T t = atc.get(); 188 int iters = atc.requiresLoop() ? ITERS : 1; 189 for (int c = 0; c < iters; c++) { 190 atc.testAccess(t); 191 } 192 } 193 194 195 static void testArrayUnsupported(ByteArraySource bs, VarHandleSource vhs) { 196 VarHandle vh = vhs.s; 197 byte[] array = bs.s; 198 int ci = 1; 199 200#if[!CAS] 201 checkUOE(() -> { 202 boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); 203 }); 204 205 checkUOE(() -> { 206 $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); 207 }); 208 209 checkUOE(() -> { 210 $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); 211 }); 212 213 checkUOE(() -> { 214 $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); 215 }); 216 217 checkUOE(() -> { 218 boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); 219 }); 220 221 checkUOE(() -> { 222 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); 223 }); 224 225 checkUOE(() -> { 226 boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); 227 }); 228 229 checkUOE(() -> { 230 $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1); 231 }); 232#end[CAS] 233 234#if[!AtomicAdd] 235 checkUOE(() -> { 236 $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1); 237 }); 238 239 checkUOE(() -> { 240 $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1); 241 }); 242#end[AtomicAdd] 243 } 244 245 static void testArrayUnsupported(ByteBufferSource bs, VarHandleSource vhs) { 246 VarHandle vh = vhs.s; 247 ByteBuffer array = bs.s; 248 int ci = 0; 249 boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes); 250 251 if (readOnly) { 252 checkROBE(() -> { 253 vh.set(array, ci, VALUE_1); 254 }); 255 } 256 257 if (readOnly) { 258 checkROBE(() -> { 259 vh.setVolatile(array, ci, VALUE_1); 260 }); 261 262 checkROBE(() -> { 263 vh.setRelease(array, ci, VALUE_1); 264 }); 265 266 checkROBE(() -> { 267 vh.setOpaque(array, ci, VALUE_1); 268 }); 269#if[CAS] 270 271 checkROBE(() -> { 272 boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); 273 }); 274 275 checkROBE(() -> { 276 $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); 277 }); 278 279 checkROBE(() -> { 280 $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); 281 }); 282 283 checkROBE(() -> { 284 $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); 285 }); 286 287 checkROBE(() -> { 288 boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); 289 }); 290 291 checkROBE(() -> { 292 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); 293 }); 294 295 checkROBE(() -> { 296 boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); 297 }); 298 299 checkROBE(() -> { 300 $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1); 301 }); 302 checkUOE(() -> { 303 boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); 304 }); 305#else[CAS] 306 checkUOE(() -> { 307 $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); 308 }); 309 310 checkUOE(() -> { 311 $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); 312 }); 313 314 checkUOE(() -> { 315 $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); 316 }); 317 318 checkUOE(() -> { 319 boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); 320 }); 321 322 checkUOE(() -> { 323 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); 324 }); 325 326 checkUOE(() -> { 327 boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); 328 }); 329 330 checkUOE(() -> { 331 $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1); 332 }); 333#end[CAS] 334 335#if[AtomicAdd] 336 checkROBE(() -> { 337 $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1); 338 }); 339 340 checkROBE(() -> { 341 $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1); 342 }); 343#else[AtomicAdd] 344 checkUOE(() -> { 345 $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1); 346 }); 347 348 checkUOE(() -> { 349 $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1); 350 }); 351#end[AtomicAdd] 352 } 353 else { 354#if[!CAS] 355 checkUOE(() -> { 356 boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); 357 }); 358 359 checkUOE(() -> { 360 $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); 361 }); 362 363 checkUOE(() -> { 364 $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); 365 }); 366 367 checkUOE(() -> { 368 $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); 369 }); 370 371 checkUOE(() -> { 372 boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); 373 }); 374 375 checkUOE(() -> { 376 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); 377 }); 378 379 checkUOE(() -> { 380 boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); 381 }); 382 383 checkUOE(() -> { 384 $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1); 385 }); 386#end[CAS] 387#if[!AtomicAdd] 388 checkUOE(() -> { 389 $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1); 390 }); 391 392 checkUOE(() -> { 393 $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1); 394 }); 395#end[AtomicAdd] 396 } 397 } 398 399 400 static void testArrayIndexOutOfBounds(ByteArraySource bs, VarHandleSource vhs) throws Throwable { 401 VarHandle vh = vhs.s; 402 byte[] array = bs.s; 403 404 int length = array.length - SIZE + 1; 405 for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) { 406 final int ci = i; 407 408 checkIOOBE(() -> { 409 $type$ x = ($type$) vh.get(array, ci); 410 }); 411 412 checkIOOBE(() -> { 413 vh.set(array, ci, VALUE_1); 414 }); 415 416 checkIOOBE(() -> { 417 $type$ x = ($type$) vh.getVolatile(array, ci); 418 }); 419 420 checkIOOBE(() -> { 421 $type$ x = ($type$) vh.getAcquire(array, ci); 422 }); 423 424 checkIOOBE(() -> { 425 $type$ x = ($type$) vh.getOpaque(array, ci); 426 }); 427 428 checkIOOBE(() -> { 429 vh.setVolatile(array, ci, VALUE_1); 430 }); 431 432 checkIOOBE(() -> { 433 vh.setRelease(array, ci, VALUE_1); 434 }); 435 436 checkIOOBE(() -> { 437 vh.setOpaque(array, ci, VALUE_1); 438 }); 439#if[CAS] 440 441 checkIOOBE(() -> { 442 boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); 443 }); 444 445 checkIOOBE(() -> { 446 $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); 447 }); 448 449 checkIOOBE(() -> { 450 $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); 451 }); 452 453 checkIOOBE(() -> { 454 $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); 455 }); 456 457 checkIOOBE(() -> { 458 boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); 459 }); 460 461 checkIOOBE(() -> { 462 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); 463 }); 464 465 checkIOOBE(() -> { 466 boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); 467 }); 468 469 checkIOOBE(() -> { 470 $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1); 471 }); 472#end[CAS] 473 474#if[AtomicAdd] 475 checkIOOBE(() -> { 476 $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1); 477 }); 478 479 checkIOOBE(() -> { 480 $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1); 481 }); 482#end[AtomicAdd] 483 484 } 485 } 486 487 static void testArrayIndexOutOfBounds(ByteBufferSource bs, VarHandleSource vhs) throws Throwable { 488 VarHandle vh = vhs.s; 489 ByteBuffer array = bs.s; 490 491 boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes); 492 493 int length = array.limit() - SIZE + 1; 494 for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) { 495 final int ci = i; 496 497 checkIOOBE(() -> { 498 $type$ x = ($type$) vh.get(array, ci); 499 }); 500 501 if (!readOnly) { 502 checkIOOBE(() -> { 503 vh.set(array, ci, VALUE_1); 504 }); 505 } 506 507 checkIOOBE(() -> { 508 $type$ x = ($type$) vh.getVolatile(array, ci); 509 }); 510 511 checkIOOBE(() -> { 512 $type$ x = ($type$) vh.getAcquire(array, ci); 513 }); 514 515 checkIOOBE(() -> { 516 $type$ x = ($type$) vh.getOpaque(array, ci); 517 }); 518 519 if (!readOnly) { 520 checkIOOBE(() -> { 521 vh.setVolatile(array, ci, VALUE_1); 522 }); 523 524 checkIOOBE(() -> { 525 vh.setRelease(array, ci, VALUE_1); 526 }); 527 528 checkIOOBE(() -> { 529 vh.setOpaque(array, ci, VALUE_1); 530 }); 531 532#if[CAS] 533 checkIOOBE(() -> { 534 boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); 535 }); 536 537 checkIOOBE(() -> { 538 $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); 539 }); 540 541 checkIOOBE(() -> { 542 $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); 543 }); 544 545 checkIOOBE(() -> { 546 $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); 547 }); 548 549 checkIOOBE(() -> { 550 boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); 551 }); 552 553 checkIOOBE(() -> { 554 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); 555 }); 556 557 checkIOOBE(() -> { 558 boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); 559 }); 560 561 checkIOOBE(() -> { 562 $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1); 563 }); 564#end[CAS] 565 566#if[AtomicAdd] 567 checkIOOBE(() -> { 568 $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1); 569 }); 570 571 checkIOOBE(() -> { 572 $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1); 573 }); 574#end[AtomicAdd] 575 } 576 } 577 } 578 579 static void testArrayMisalignedAccess(ByteArraySource bs, VarHandleSource vhs) throws Throwable { 580 VarHandle vh = vhs.s; 581 byte[] array = bs.s; 582 583 int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE); 584 585 int length = array.length - SIZE + 1; 586 for (int i = 0; i < length; i++) { 587 boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; 588 final int ci = i; 589 590 if (!iAligned) { 591 checkISE(() -> { 592 $type$ x = ($type$) vh.getVolatile(array, ci); 593 }); 594 595 checkISE(() -> { 596 $type$ x = ($type$) vh.getAcquire(array, ci); 597 }); 598 599 checkISE(() -> { 600 $type$ x = ($type$) vh.getOpaque(array, ci); 601 }); 602 603 checkISE(() -> { 604 vh.setVolatile(array, ci, VALUE_1); 605 }); 606 607 checkISE(() -> { 608 vh.setRelease(array, ci, VALUE_1); 609 }); 610 611 checkISE(() -> { 612 vh.setOpaque(array, ci, VALUE_1); 613 }); 614#if[CAS] 615 616 checkISE(() -> { 617 boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); 618 }); 619 620 checkISE(() -> { 621 $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); 622 }); 623 624 checkISE(() -> { 625 $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); 626 }); 627 628 checkISE(() -> { 629 $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); 630 }); 631 632 checkISE(() -> { 633 boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); 634 }); 635 636 checkISE(() -> { 637 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); 638 }); 639 640 checkISE(() -> { 641 boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); 642 }); 643 644 checkISE(() -> { 645 $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1); 646 }); 647#end[CAS] 648 649#if[AtomicAdd] 650 checkISE(() -> { 651 $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1); 652 }); 653 654 checkISE(() -> { 655 $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1); 656 }); 657#end[AtomicAdd] 658 659 } 660 } 661 } 662 663 static void testArrayMisalignedAccess(ByteBufferSource bs, VarHandleSource vhs) throws Throwable { 664 VarHandle vh = vhs.s; 665 ByteBuffer array = bs.s; 666 667 boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes); 668 int misalignmentAtZero = array.alignmentOffset(0, SIZE); 669 670 int length = array.limit() - SIZE + 1; 671 for (int i = 0; i < length; i++) { 672 boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; 673 final int ci = i; 674 675 if (!iAligned) { 676 checkISE(() -> { 677 $type$ x = ($type$) vh.getVolatile(array, ci); 678 }); 679 680 checkISE(() -> { 681 $type$ x = ($type$) vh.getAcquire(array, ci); 682 }); 683 684 checkISE(() -> { 685 $type$ x = ($type$) vh.getOpaque(array, ci); 686 }); 687 688 if (!readOnly) { 689 checkISE(() -> { 690 vh.setVolatile(array, ci, VALUE_1); 691 }); 692 693 checkISE(() -> { 694 vh.setRelease(array, ci, VALUE_1); 695 }); 696 697 checkISE(() -> { 698 vh.setOpaque(array, ci, VALUE_1); 699 }); 700 701#if[CAS] 702 checkISE(() -> { 703 boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); 704 }); 705 706 checkISE(() -> { 707 $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); 708 }); 709 710 checkISE(() -> { 711 $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); 712 }); 713 714 checkISE(() -> { 715 $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); 716 }); 717 718 checkISE(() -> { 719 boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); 720 }); 721 722 checkISE(() -> { 723 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); 724 }); 725 726 checkISE(() -> { 727 boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); 728 }); 729 730 checkISE(() -> { 731 $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1); 732 }); 733#end[CAS] 734 735#if[AtomicAdd] 736 checkISE(() -> { 737 $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1); 738 }); 739 740 checkISE(() -> { 741 $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1); 742 }); 743#end[AtomicAdd] 744 } 745 } 746 } 747 } 748 749 static void testArrayReadWrite(ByteArraySource bs, VarHandleSource vhs) { 750 VarHandle vh = vhs.s; 751 byte[] array = bs.s; 752 753 int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE); 754 755 bs.fill((byte) 0xff); 756 int length = array.length - SIZE + 1; 757 for (int i = 0; i < length; i++) { 758 boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; 759 760 // Plain 761 { 762 vh.set(array, i, VALUE_1); 763 $type$ x = ($type$) vh.get(array, i); 764 assertEquals(x, VALUE_1, "get $type$ value"); 765 } 766 767 768 if (iAligned) { 769 // Volatile 770 { 771 vh.setVolatile(array, i, VALUE_2); 772 $type$ x = ($type$) vh.getVolatile(array, i); 773 assertEquals(x, VALUE_2, "setVolatile $type$ value"); 774 } 775 776 // Lazy 777 { 778 vh.setRelease(array, i, VALUE_1); 779 $type$ x = ($type$) vh.getAcquire(array, i); 780 assertEquals(x, VALUE_1, "setRelease $type$ value"); 781 } 782 783 // Opaque 784 { 785 vh.setOpaque(array, i, VALUE_2); 786 $type$ x = ($type$) vh.getOpaque(array, i); 787 assertEquals(x, VALUE_2, "setOpaque $type$ value"); 788 } 789#if[CAS] 790 791 vh.set(array, i, VALUE_1); 792 793 // Compare 794 { 795 boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2); 796 assertEquals(r, true, "success compareAndSet $type$"); 797 $type$ x = ($type$) vh.get(array, i); 798 assertEquals(x, VALUE_2, "success compareAndSet $type$ value"); 799 } 800 801 { 802 boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3); 803 assertEquals(r, false, "failing compareAndSet $type$"); 804 $type$ x = ($type$) vh.get(array, i); 805 assertEquals(x, VALUE_2, "failing compareAndSet $type$ value"); 806 } 807 808 { 809 $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1); 810 assertEquals(r, VALUE_2, "success compareAndExchangeVolatile $type$"); 811 $type$ x = ($type$) vh.get(array, i); 812 assertEquals(x, VALUE_1, "success compareAndExchangeVolatile $type$ value"); 813 } 814 815 { 816 $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3); 817 assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile $type$"); 818 $type$ x = ($type$) vh.get(array, i); 819 assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile $type$ value"); 820 } 821 822 { 823 $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2); 824 assertEquals(r, VALUE_1, "success compareAndExchangeAcquire $type$"); 825 $type$ x = ($type$) vh.get(array, i); 826 assertEquals(x, VALUE_2, "success compareAndExchangeAcquire $type$ value"); 827 } 828 829 { 830 $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3); 831 assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire $type$"); 832 $type$ x = ($type$) vh.get(array, i); 833 assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire $type$ value"); 834 } 835 836 { 837 $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1); 838 assertEquals(r, VALUE_2, "success compareAndExchangeRelease $type$"); 839 $type$ x = ($type$) vh.get(array, i); 840 assertEquals(x, VALUE_1, "success compareAndExchangeRelease $type$ value"); 841 } 842 843 { 844 $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3); 845 assertEquals(r, VALUE_1, "failing compareAndExchangeRelease $type$"); 846 $type$ x = ($type$) vh.get(array, i); 847 assertEquals(x, VALUE_1, "failing compareAndExchangeRelease $type$ value"); 848 } 849 850 { 851 boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2); 852 assertEquals(r, true, "weakCompareAndSet $type$"); 853 $type$ x = ($type$) vh.get(array, i); 854 assertEquals(x, VALUE_2, "weakCompareAndSet $type$ value"); 855 } 856 857 { 858 boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); 859 assertEquals(r, true, "weakCompareAndSetAcquire $type$"); 860 $type$ x = ($type$) vh.get(array, i); 861 assertEquals(x, VALUE_1, "weakCompareAndSetAcquire $type$"); 862 } 863 864 { 865 boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); 866 assertEquals(r, true, "weakCompareAndSetRelease $type$"); 867 $type$ x = ($type$) vh.get(array, i); 868 assertEquals(x, VALUE_2, "weakCompareAndSetRelease $type$"); 869 } 870 871 // Compare set and get 872 { 873 $type$ o = ($type$) vh.getAndSet(array, i, VALUE_1); 874 assertEquals(o, VALUE_2, "getAndSet $type$"); 875 $type$ x = ($type$) vh.get(array, i); 876 assertEquals(x, VALUE_1, "getAndSet $type$ value"); 877 } 878#end[CAS] 879 880#if[AtomicAdd] 881 vh.set(array, i, VALUE_1); 882 883 // get and add, add and get 884 { 885 $type$ o = ($type$) vh.getAndAdd(array, i, VALUE_3); 886 assertEquals(o, VALUE_1, "getAndAdd $type$"); 887 $type$ c = ($type$) vh.addAndGet(array, i, VALUE_3); 888 assertEquals(c, VALUE_1 + VALUE_3 + VALUE_3, "getAndAdd $type$ value"); 889 } 890#end[AtomicAdd] 891 } 892 } 893 } 894 895 896 static void testArrayReadWrite(ByteBufferSource bs, VarHandleSource vhs) { 897 VarHandle vh = vhs.s; 898 ByteBuffer array = bs.s; 899 900 int misalignmentAtZero = array.alignmentOffset(0, SIZE); 901 902 bs.fill((byte) 0xff); 903 int length = array.limit() - SIZE + 1; 904 for (int i = 0; i < length; i++) { 905 boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; 906 907 // Plain 908 { 909 vh.set(array, i, VALUE_1); 910 $type$ x = ($type$) vh.get(array, i); 911 assertEquals(x, VALUE_1, "get $type$ value"); 912 } 913 914 if (iAligned) { 915 // Volatile 916 { 917 vh.setVolatile(array, i, VALUE_2); 918 $type$ x = ($type$) vh.getVolatile(array, i); 919 assertEquals(x, VALUE_2, "setVolatile $type$ value"); 920 } 921 922 // Lazy 923 { 924 vh.setRelease(array, i, VALUE_1); 925 $type$ x = ($type$) vh.getAcquire(array, i); 926 assertEquals(x, VALUE_1, "setRelease $type$ value"); 927 } 928 929 // Opaque 930 { 931 vh.setOpaque(array, i, VALUE_2); 932 $type$ x = ($type$) vh.getOpaque(array, i); 933 assertEquals(x, VALUE_2, "setOpaque $type$ value"); 934 } 935#if[CAS] 936 937 vh.set(array, i, VALUE_1); 938 939 // Compare 940 { 941 boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2); 942 assertEquals(r, true, "success compareAndSet $type$"); 943 $type$ x = ($type$) vh.get(array, i); 944 assertEquals(x, VALUE_2, "success compareAndSet $type$ value"); 945 } 946 947 { 948 boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3); 949 assertEquals(r, false, "failing compareAndSet $type$"); 950 $type$ x = ($type$) vh.get(array, i); 951 assertEquals(x, VALUE_2, "failing compareAndSet $type$ value"); 952 } 953 954 { 955 $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1); 956 assertEquals(r, VALUE_2, "success compareAndExchangeVolatile $type$"); 957 $type$ x = ($type$) vh.get(array, i); 958 assertEquals(x, VALUE_1, "success compareAndExchangeVolatile $type$ value"); 959 } 960 961 { 962 $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3); 963 assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile $type$"); 964 $type$ x = ($type$) vh.get(array, i); 965 assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile $type$ value"); 966 } 967 968 { 969 $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2); 970 assertEquals(r, VALUE_1, "success compareAndExchangeAcquire $type$"); 971 $type$ x = ($type$) vh.get(array, i); 972 assertEquals(x, VALUE_2, "success compareAndExchangeAcquire $type$ value"); 973 } 974 975 { 976 $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3); 977 assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire $type$"); 978 $type$ x = ($type$) vh.get(array, i); 979 assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire $type$ value"); 980 } 981 982 { 983 $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1); 984 assertEquals(r, VALUE_2, "success compareAndExchangeRelease $type$"); 985 $type$ x = ($type$) vh.get(array, i); 986 assertEquals(x, VALUE_1, "success compareAndExchangeRelease $type$ value"); 987 } 988 989 { 990 $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3); 991 assertEquals(r, VALUE_1, "failing compareAndExchangeRelease $type$"); 992 $type$ x = ($type$) vh.get(array, i); 993 assertEquals(x, VALUE_1, "failing compareAndExchangeRelease $type$ value"); 994 } 995 996 { 997 boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2); 998 assertEquals(r, true, "weakCompareAndSet $type$"); 999 $type$ x = ($type$) vh.get(array, i); 1000 assertEquals(x, VALUE_2, "weakCompareAndSet $type$ value"); 1001 } 1002 1003 { 1004 boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); 1005 assertEquals(r, true, "weakCompareAndSetAcquire $type$"); 1006 $type$ x = ($type$) vh.get(array, i); 1007 assertEquals(x, VALUE_1, "weakCompareAndSetAcquire $type$"); 1008 } 1009 1010 { 1011 boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); 1012 assertEquals(r, true, "weakCompareAndSetRelease $type$"); 1013 $type$ x = ($type$) vh.get(array, i); 1014 assertEquals(x, VALUE_2, "weakCompareAndSetRelease $type$"); 1015 } 1016 1017 // Compare set and get 1018 { 1019 $type$ o = ($type$) vh.getAndSet(array, i, VALUE_1); 1020 assertEquals(o, VALUE_2, "getAndSet $type$"); 1021 $type$ x = ($type$) vh.get(array, i); 1022 assertEquals(x, VALUE_1, "getAndSet $type$ value"); 1023 } 1024#end[CAS] 1025 1026#if[AtomicAdd] 1027 vh.set(array, i, VALUE_1); 1028 1029 // get and add, add and get 1030 { 1031 $type$ o = ($type$) vh.getAndAdd(array, i, VALUE_3); 1032 assertEquals(o, VALUE_1, "getAndAdd $type$"); 1033 $type$ c = ($type$) vh.addAndGet(array, i, VALUE_3); 1034 assertEquals(c, VALUE_1 + VALUE_3 + VALUE_3, "getAndAdd $type$ value"); 1035 } 1036#end[AtomicAdd] 1037 } 1038 } 1039 } 1040 1041 static void testArrayReadOnly(ByteBufferSource bs, VarHandleSource vhs) { 1042 VarHandle vh = vhs.s; 1043 ByteBuffer array = bs.s; 1044 1045 int misalignmentAtZero = array.alignmentOffset(0, SIZE); 1046 1047 ByteBuffer bb = ByteBuffer.allocate(SIZE); 1048 bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN); 1049 bs.fill(bb.put$Type$(0, VALUE_2).array()); 1050 1051 int length = array.limit() - SIZE + 1; 1052 for (int i = 0; i < length; i++) { 1053 boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; 1054 1055 $type$ v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) 1056 ? rotateLeft(VALUE_2, (i % SIZE) << 3) 1057 : rotateRight(VALUE_2, (i % SIZE) << 3); 1058 // Plain 1059 { 1060 $type$ x = ($type$) vh.get(array, i); 1061 assertEquals(x, v, "get $type$ value"); 1062 } 1063 1064 if (iAligned) { 1065 // Volatile 1066 { 1067 $type$ x = ($type$) vh.getVolatile(array, i); 1068 assertEquals(x, v, "getVolatile $type$ value"); 1069 } 1070 1071 // Lazy 1072 { 1073 $type$ x = ($type$) vh.getAcquire(array, i); 1074 assertEquals(x, v, "getRelease $type$ value"); 1075 } 1076 1077 // Opaque 1078 { 1079 $type$ x = ($type$) vh.getOpaque(array, i); 1080 assertEquals(x, v, "getOpaque $type$ value"); 1081 } 1082 } 1083 } 1084 } 1085 1086} 1087 1088