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