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