X-VarHandleTestByteArrayView.java.template revision 14477:0043d6a1e416
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 * @bug 8154556 27 * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAs$Type$ 28 * @run testng/othervm -Diters=20000 VarHandleTestByteArrayAs$Type$ 29 * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAs$Type$ 30 */ 31 32import org.testng.annotations.DataProvider; 33import org.testng.annotations.Test; 34 35import java.lang.invoke.MethodHandles; 36import java.lang.invoke.VarHandle; 37import java.nio.ByteBuffer; 38import java.nio.ByteOrder; 39import java.util.ArrayList; 40import java.util.Arrays; 41import java.util.EnumSet; 42import java.util.List; 43 44import static org.testng.Assert.*; 45 46public class VarHandleTestByteArrayAs$Type$ extends VarHandleBaseByteArrayTest { 47 static final int SIZE = $BoxType$.BYTES; 48 49 static final $type$ VALUE_1 = $value1$; 50 51 static final $type$ VALUE_2 = $value2$; 52 53 static final $type$ VALUE_3 = $value3$; 54 55 56 @Override 57 public void setupVarHandleSources() { 58 // Combinations of VarHandle byte[] or ByteBuffer 59 vhss = new ArrayList<>(); 60 for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) { 61 62 ByteOrder bo = endianess == MemoryMode.BIG_ENDIAN 63 ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN; 64 VarHandleSource aeh = new VarHandleSource( 65 MethodHandles.byteArrayViewVarHandle($type$[].class, bo), 66 endianess, MemoryMode.READ_WRITE); 67 vhss.add(aeh); 68 69 VarHandleSource bbh = new VarHandleSource( 70 MethodHandles.byteBufferViewVarHandle($type$[].class, bo), 71 endianess, MemoryMode.READ_WRITE); 72 vhss.add(bbh); 73 } 74 } 75 76 77 @Test(dataProvider = "varHandlesProvider") 78 public void testIsAccessModeSupported(VarHandleSource vhs) { 79 VarHandle vh = vhs.s; 80 81 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET)); 82 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET)); 83 84 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_VOLATILE)); 85 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_VOLATILE)); 86 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_ACQUIRE)); 87 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_RELEASE)); 88 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_OPAQUE)); 89 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_OPAQUE)); 90 91#if[CAS] 92 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_SET)); 93 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_VOLATILE)); 94 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE)); 95 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE)); 96 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET)); 97 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE)); 98 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE)); 99 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET)); 100#else[CAS] 101 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_SET)); 102 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_VOLATILE)); 103 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE)); 104 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE)); 105 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET)); 106 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE)); 107 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE)); 108 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET)); 109#end[CAS] 110 111#if[AtomicAdd] 112 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD)); 113 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.ADD_AND_GET)); 114#else[AtomicAdd] 115 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD)); 116 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.ADD_AND_GET)); 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 success = false; 854 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 855 success = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2); 856 } 857 assertEquals(success, true, "weakCompareAndSet $type$"); 858 $type$ x = ($type$) vh.get(array, i); 859 assertEquals(x, VALUE_2, "weakCompareAndSet $type$ value"); 860 } 861 862 { 863 boolean success = false; 864 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 865 success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); 866 } 867 assertEquals(success, true, "weakCompareAndSetAcquire $type$"); 868 $type$ x = ($type$) vh.get(array, i); 869 assertEquals(x, VALUE_1, "weakCompareAndSetAcquire $type$"); 870 } 871 872 { 873 boolean success = false; 874 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 875 success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); 876 } 877 assertEquals(success, true, "weakCompareAndSetRelease $type$"); 878 $type$ x = ($type$) vh.get(array, i); 879 assertEquals(x, VALUE_2, "weakCompareAndSetRelease $type$"); 880 } 881 882 // Compare set and get 883 { 884 $type$ o = ($type$) vh.getAndSet(array, i, VALUE_1); 885 assertEquals(o, VALUE_2, "getAndSet $type$"); 886 $type$ x = ($type$) vh.get(array, i); 887 assertEquals(x, VALUE_1, "getAndSet $type$ value"); 888 } 889#end[CAS] 890 891#if[AtomicAdd] 892 vh.set(array, i, VALUE_1); 893 894 // get and add, add and get 895 { 896 $type$ o = ($type$) vh.getAndAdd(array, i, VALUE_3); 897 assertEquals(o, VALUE_1, "getAndAdd $type$"); 898 $type$ c = ($type$) vh.addAndGet(array, i, VALUE_3); 899 assertEquals(c, VALUE_1 + VALUE_3 + VALUE_3, "getAndAdd $type$ value"); 900 } 901#end[AtomicAdd] 902 } 903 } 904 } 905 906 907 static void testArrayReadWrite(ByteBufferSource bs, VarHandleSource vhs) { 908 VarHandle vh = vhs.s; 909 ByteBuffer array = bs.s; 910 911 int misalignmentAtZero = array.alignmentOffset(0, SIZE); 912 913 bs.fill((byte) 0xff); 914 int length = array.limit() - SIZE + 1; 915 for (int i = 0; i < length; i++) { 916 boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; 917 918 // Plain 919 { 920 vh.set(array, i, VALUE_1); 921 $type$ x = ($type$) vh.get(array, i); 922 assertEquals(x, VALUE_1, "get $type$ value"); 923 } 924 925 if (iAligned) { 926 // Volatile 927 { 928 vh.setVolatile(array, i, VALUE_2); 929 $type$ x = ($type$) vh.getVolatile(array, i); 930 assertEquals(x, VALUE_2, "setVolatile $type$ value"); 931 } 932 933 // Lazy 934 { 935 vh.setRelease(array, i, VALUE_1); 936 $type$ x = ($type$) vh.getAcquire(array, i); 937 assertEquals(x, VALUE_1, "setRelease $type$ value"); 938 } 939 940 // Opaque 941 { 942 vh.setOpaque(array, i, VALUE_2); 943 $type$ x = ($type$) vh.getOpaque(array, i); 944 assertEquals(x, VALUE_2, "setOpaque $type$ value"); 945 } 946#if[CAS] 947 948 vh.set(array, i, VALUE_1); 949 950 // Compare 951 { 952 boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2); 953 assertEquals(r, true, "success compareAndSet $type$"); 954 $type$ x = ($type$) vh.get(array, i); 955 assertEquals(x, VALUE_2, "success compareAndSet $type$ value"); 956 } 957 958 { 959 boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3); 960 assertEquals(r, false, "failing compareAndSet $type$"); 961 $type$ x = ($type$) vh.get(array, i); 962 assertEquals(x, VALUE_2, "failing compareAndSet $type$ value"); 963 } 964 965 { 966 $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1); 967 assertEquals(r, VALUE_2, "success compareAndExchangeVolatile $type$"); 968 $type$ x = ($type$) vh.get(array, i); 969 assertEquals(x, VALUE_1, "success compareAndExchangeVolatile $type$ value"); 970 } 971 972 { 973 $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3); 974 assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile $type$"); 975 $type$ x = ($type$) vh.get(array, i); 976 assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile $type$ value"); 977 } 978 979 { 980 $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2); 981 assertEquals(r, VALUE_1, "success compareAndExchangeAcquire $type$"); 982 $type$ x = ($type$) vh.get(array, i); 983 assertEquals(x, VALUE_2, "success compareAndExchangeAcquire $type$ value"); 984 } 985 986 { 987 $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3); 988 assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire $type$"); 989 $type$ x = ($type$) vh.get(array, i); 990 assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire $type$ value"); 991 } 992 993 { 994 $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1); 995 assertEquals(r, VALUE_2, "success compareAndExchangeRelease $type$"); 996 $type$ x = ($type$) vh.get(array, i); 997 assertEquals(x, VALUE_1, "success compareAndExchangeRelease $type$ value"); 998 } 999 1000 { 1001 $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3); 1002 assertEquals(r, VALUE_1, "failing compareAndExchangeRelease $type$"); 1003 $type$ x = ($type$) vh.get(array, i); 1004 assertEquals(x, VALUE_1, "failing compareAndExchangeRelease $type$ value"); 1005 } 1006 1007 { 1008 boolean success = false; 1009 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 1010 success = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2); 1011 } 1012 assertEquals(success, true, "weakCompareAndSet $type$"); 1013 $type$ x = ($type$) vh.get(array, i); 1014 assertEquals(x, VALUE_2, "weakCompareAndSet $type$ value"); 1015 } 1016 1017 { 1018 boolean success = false; 1019 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 1020 success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); 1021 } 1022 assertEquals(success, true, "weakCompareAndSetAcquire $type$"); 1023 $type$ x = ($type$) vh.get(array, i); 1024 assertEquals(x, VALUE_1, "weakCompareAndSetAcquire $type$"); 1025 } 1026 1027 { 1028 boolean success = false; 1029 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 1030 success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); 1031 } 1032 assertEquals(success, true, "weakCompareAndSetRelease $type$"); 1033 $type$ x = ($type$) vh.get(array, i); 1034 assertEquals(x, VALUE_2, "weakCompareAndSetRelease $type$"); 1035 } 1036 1037 // Compare set and get 1038 { 1039 $type$ o = ($type$) vh.getAndSet(array, i, VALUE_1); 1040 assertEquals(o, VALUE_2, "getAndSet $type$"); 1041 $type$ x = ($type$) vh.get(array, i); 1042 assertEquals(x, VALUE_1, "getAndSet $type$ value"); 1043 } 1044#end[CAS] 1045 1046#if[AtomicAdd] 1047 vh.set(array, i, VALUE_1); 1048 1049 // get and add, add and get 1050 { 1051 $type$ o = ($type$) vh.getAndAdd(array, i, VALUE_3); 1052 assertEquals(o, VALUE_1, "getAndAdd $type$"); 1053 $type$ c = ($type$) vh.addAndGet(array, i, VALUE_3); 1054 assertEquals(c, VALUE_1 + VALUE_3 + VALUE_3, "getAndAdd $type$ value"); 1055 } 1056#end[AtomicAdd] 1057 } 1058 } 1059 } 1060 1061 static void testArrayReadOnly(ByteBufferSource bs, VarHandleSource vhs) { 1062 VarHandle vh = vhs.s; 1063 ByteBuffer array = bs.s; 1064 1065 int misalignmentAtZero = array.alignmentOffset(0, SIZE); 1066 1067 ByteBuffer bb = ByteBuffer.allocate(SIZE); 1068 bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN); 1069 bs.fill(bb.put$Type$(0, VALUE_2).array()); 1070 1071 int length = array.limit() - SIZE + 1; 1072 for (int i = 0; i < length; i++) { 1073 boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; 1074 1075 $type$ v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) 1076 ? rotateLeft(VALUE_2, (i % SIZE) << 3) 1077 : rotateRight(VALUE_2, (i % SIZE) << 3); 1078 // Plain 1079 { 1080 $type$ x = ($type$) vh.get(array, i); 1081 assertEquals(x, v, "get $type$ value"); 1082 } 1083 1084 if (iAligned) { 1085 // Volatile 1086 { 1087 $type$ x = ($type$) vh.getVolatile(array, i); 1088 assertEquals(x, v, "getVolatile $type$ value"); 1089 } 1090 1091 // Lazy 1092 { 1093 $type$ x = ($type$) vh.getAcquire(array, i); 1094 assertEquals(x, v, "getRelease $type$ value"); 1095 } 1096 1097 // Opaque 1098 { 1099 $type$ x = ($type$) vh.getOpaque(array, i); 1100 assertEquals(x, v, "getOpaque $type$ value"); 1101 } 1102 } 1103 } 1104 } 1105 1106} 1107 1108