X-VarHandleTestByteArrayView.java.template revision 14347:6929d396c267
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 r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2); 888 assertEquals(r, true, "weakCompareAndSet $type$"); 889 $type$ x = ($type$) vh.get(array, i); 890 assertEquals(x, VALUE_2, "weakCompareAndSet $type$ value"); 891 } 892 893 { 894 boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); 895 assertEquals(r, true, "weakCompareAndSetAcquire $type$"); 896 $type$ x = ($type$) vh.get(array, i); 897 assertEquals(x, VALUE_1, "weakCompareAndSetAcquire $type$"); 898 } 899 900 { 901 boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); 902 assertEquals(r, true, "weakCompareAndSetRelease $type$"); 903 $type$ x = ($type$) vh.get(array, i); 904 assertEquals(x, VALUE_2, "weakCompareAndSetRelease $type$"); 905 } 906 907 { 908 boolean r = vh.weakCompareAndSetVolatile(array, i, VALUE_2, VALUE_1); 909 assertEquals(r, true, "weakCompareAndSetVolatile $type$"); 910 $type$ x = ($type$) vh.get(array, i); 911 assertEquals(x, VALUE_1, "weakCompareAndSetVolatile $type$ value"); 912 } 913 914 // Compare set and get 915 { 916 $type$ o = ($type$) vh.getAndSet(array, i, VALUE_2); 917 assertEquals(o, VALUE_1, "getAndSet $type$"); 918 $type$ x = ($type$) vh.get(array, i); 919 assertEquals(x, VALUE_2, "getAndSet $type$ value"); 920 } 921#end[CAS] 922 923#if[AtomicAdd] 924 vh.set(array, i, VALUE_1); 925 926 // get and add, add and get 927 { 928 $type$ o = ($type$) vh.getAndAdd(array, i, VALUE_3); 929 assertEquals(o, VALUE_1, "getAndAdd $type$"); 930 $type$ c = ($type$) vh.addAndGet(array, i, VALUE_3); 931 assertEquals(c, VALUE_1 + VALUE_3 + VALUE_3, "getAndAdd $type$ value"); 932 } 933#end[AtomicAdd] 934 } 935 } 936 } 937 938 939 static void testArrayReadWrite(ByteBufferSource bs, VarHandleSource vhs) { 940 VarHandle vh = vhs.s; 941 ByteBuffer array = bs.s; 942 943 int misalignmentAtZero = array.alignmentOffset(0, SIZE); 944 945 bs.fill((byte) 0xff); 946 int length = array.limit() - SIZE + 1; 947 for (int i = 0; i < length; i++) { 948 boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; 949 950 // Plain 951 { 952 vh.set(array, i, VALUE_1); 953 $type$ x = ($type$) vh.get(array, i); 954 assertEquals(x, VALUE_1, "get $type$ value"); 955 } 956 957 if (iAligned) { 958 // Volatile 959 { 960 vh.setVolatile(array, i, VALUE_2); 961 $type$ x = ($type$) vh.getVolatile(array, i); 962 assertEquals(x, VALUE_2, "setVolatile $type$ value"); 963 } 964 965 // Lazy 966 { 967 vh.setRelease(array, i, VALUE_1); 968 $type$ x = ($type$) vh.getAcquire(array, i); 969 assertEquals(x, VALUE_1, "setRelease $type$ value"); 970 } 971 972 // Opaque 973 { 974 vh.setOpaque(array, i, VALUE_2); 975 $type$ x = ($type$) vh.getOpaque(array, i); 976 assertEquals(x, VALUE_2, "setOpaque $type$ value"); 977 } 978#if[CAS] 979 980 vh.set(array, i, VALUE_1); 981 982 // Compare 983 { 984 boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2); 985 assertEquals(r, true, "success compareAndSet $type$"); 986 $type$ x = ($type$) vh.get(array, i); 987 assertEquals(x, VALUE_2, "success compareAndSet $type$ value"); 988 } 989 990 { 991 boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3); 992 assertEquals(r, false, "failing compareAndSet $type$"); 993 $type$ x = ($type$) vh.get(array, i); 994 assertEquals(x, VALUE_2, "failing compareAndSet $type$ value"); 995 } 996 997 { 998 $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1); 999 assertEquals(r, VALUE_2, "success compareAndExchangeVolatile $type$"); 1000 $type$ x = ($type$) vh.get(array, i); 1001 assertEquals(x, VALUE_1, "success compareAndExchangeVolatile $type$ value"); 1002 } 1003 1004 { 1005 $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3); 1006 assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile $type$"); 1007 $type$ x = ($type$) vh.get(array, i); 1008 assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile $type$ value"); 1009 } 1010 1011 { 1012 $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2); 1013 assertEquals(r, VALUE_1, "success compareAndExchangeAcquire $type$"); 1014 $type$ x = ($type$) vh.get(array, i); 1015 assertEquals(x, VALUE_2, "success compareAndExchangeAcquire $type$ value"); 1016 } 1017 1018 { 1019 $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3); 1020 assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire $type$"); 1021 $type$ x = ($type$) vh.get(array, i); 1022 assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire $type$ value"); 1023 } 1024 1025 { 1026 $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1); 1027 assertEquals(r, VALUE_2, "success compareAndExchangeRelease $type$"); 1028 $type$ x = ($type$) vh.get(array, i); 1029 assertEquals(x, VALUE_1, "success compareAndExchangeRelease $type$ value"); 1030 } 1031 1032 { 1033 $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3); 1034 assertEquals(r, VALUE_1, "failing compareAndExchangeRelease $type$"); 1035 $type$ x = ($type$) vh.get(array, i); 1036 assertEquals(x, VALUE_1, "failing compareAndExchangeRelease $type$ value"); 1037 } 1038 1039 { 1040 boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2); 1041 assertEquals(r, true, "weakCompareAndSet $type$"); 1042 $type$ x = ($type$) vh.get(array, i); 1043 assertEquals(x, VALUE_2, "weakCompareAndSet $type$ value"); 1044 } 1045 1046 { 1047 boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); 1048 assertEquals(r, true, "weakCompareAndSetAcquire $type$"); 1049 $type$ x = ($type$) vh.get(array, i); 1050 assertEquals(x, VALUE_1, "weakCompareAndSetAcquire $type$"); 1051 } 1052 1053 { 1054 boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); 1055 assertEquals(r, true, "weakCompareAndSetRelease $type$"); 1056 $type$ x = ($type$) vh.get(array, i); 1057 assertEquals(x, VALUE_2, "weakCompareAndSetRelease $type$"); 1058 } 1059 1060 { 1061 boolean r = vh.weakCompareAndSetVolatile(array, i, VALUE_2, VALUE_1); 1062 assertEquals(r, true, "weakCompareAndSetVolatile $type$"); 1063 $type$ x = ($type$) vh.get(array, i); 1064 assertEquals(x, VALUE_1, "weakCompareAndSetVolatile $type$ value"); 1065 } 1066 1067 // Compare set and get 1068 { 1069 $type$ o = ($type$) vh.getAndSet(array, i, VALUE_2); 1070 assertEquals(o, VALUE_1, "getAndSet $type$"); 1071 $type$ x = ($type$) vh.get(array, i); 1072 assertEquals(x, VALUE_2, "getAndSet $type$ value"); 1073 } 1074#end[CAS] 1075 1076#if[AtomicAdd] 1077 vh.set(array, i, VALUE_1); 1078 1079 // get and add, add and get 1080 { 1081 $type$ o = ($type$) vh.getAndAdd(array, i, VALUE_3); 1082 assertEquals(o, VALUE_1, "getAndAdd $type$"); 1083 $type$ c = ($type$) vh.addAndGet(array, i, VALUE_3); 1084 assertEquals(c, VALUE_1 + VALUE_3 + VALUE_3, "getAndAdd $type$ value"); 1085 } 1086#end[AtomicAdd] 1087 } 1088 } 1089 } 1090 1091 static void testArrayReadOnly(ByteBufferSource bs, VarHandleSource vhs) { 1092 VarHandle vh = vhs.s; 1093 ByteBuffer array = bs.s; 1094 1095 int misalignmentAtZero = array.alignmentOffset(0, SIZE); 1096 1097 ByteBuffer bb = ByteBuffer.allocate(SIZE); 1098 bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN); 1099 bs.fill(bb.put$Type$(0, VALUE_2).array()); 1100 1101 int length = array.limit() - SIZE + 1; 1102 for (int i = 0; i < length; i++) { 1103 boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; 1104 1105 $type$ v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) 1106 ? rotateLeft(VALUE_2, (i % SIZE) << 3) 1107 : rotateRight(VALUE_2, (i % SIZE) << 3); 1108 // Plain 1109 { 1110 $type$ x = ($type$) vh.get(array, i); 1111 assertEquals(x, v, "get $type$ value"); 1112 } 1113 1114 if (iAligned) { 1115 // Volatile 1116 { 1117 $type$ x = ($type$) vh.getVolatile(array, i); 1118 assertEquals(x, v, "getVolatile $type$ value"); 1119 } 1120 1121 // Lazy 1122 { 1123 $type$ x = ($type$) vh.getAcquire(array, i); 1124 assertEquals(x, v, "getRelease $type$ value"); 1125 } 1126 1127 // Opaque 1128 { 1129 $type$ x = ($type$) vh.getOpaque(array, i); 1130 assertEquals(x, v, "getOpaque $type$ value"); 1131 } 1132 } 1133 } 1134 } 1135 1136} 1137 1138