1 /* 2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @run testng/othervm -Diters=10 -Xint VarHandleTestAccess$Type$ 27 * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccess$Type$ 28 * @run testng/othervm -Diters=20000 VarHandleTestAccess$Type$ 29 * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccess$Type$ 30 */ 31 32 import org.testng.annotations.BeforeClass; 33 import org.testng.annotations.DataProvider; 34 import org.testng.annotations.Test; 35 36 import java.lang.invoke.MethodHandles; 37 import java.lang.invoke.VarHandle; 38 import java.util.ArrayList; 39 import java.util.Arrays; 40 import java.util.List; 41 42 import static org.testng.Assert.*; 43 44 public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { 45 static final $type$ static_final_v = $value1$; 46 47 static $type$ static_v; 48 49 final $type$ final_v = $value1$; 50 51 $type$ v; 52 53 VarHandle vhFinalField; 54 55 VarHandle vhField; 56 57 VarHandle vhStaticField; 58 59 VarHandle vhStaticFinalField; 60 61 VarHandle vhArray; 62 63 @BeforeClass 64 public void setup() throws Exception { 65 vhFinalField = MethodHandles.lookup().findVarHandle( 66 VarHandleTestAccess$Type$.class, "final_v", $type$.class); 67 68 vhField = MethodHandles.lookup().findVarHandle( 69 VarHandleTestAccess$Type$.class, "v", $type$.class); 70 71 vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle( 72 VarHandleTestAccess$Type$.class, "static_final_v", $type$.class); 73 74 vhStaticField = MethodHandles.lookup().findStaticVarHandle( 75 VarHandleTestAccess$Type$.class, "static_v", $type$.class); 76 77 vhArray = MethodHandles.arrayElementVarHandle($type$[].class); 78 } 79 80 81 @DataProvider 82 public Object[][] varHandlesProvider() throws Exception { 83 List<VarHandle> vhs = new ArrayList<>(); 84 vhs.add(vhField); 85 vhs.add(vhStaticField); 86 vhs.add(vhArray); 87 88 return vhs.stream().map(tc -> new Object[]{tc}).toArray(Object[][]::new); 89 } 90 91 @Test(dataProvider = "varHandlesProvider") 92 public void testIsAccessModeSupported(VarHandle vh) { 93 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET)); 94 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET)); 95 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_VOLATILE)); 96 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_VOLATILE)); 97 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_ACQUIRE)); 98 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_RELEASE)); 99 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_OPAQUE)); 100 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_OPAQUE)); 101 102 #if[CAS] 103 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_SET)); 104 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_VOLATILE)); 105 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE)); 106 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE)); 107 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET)); 108 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE)); 109 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE)); 110 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET)); 111 #else[CAS] 112 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_SET)); 113 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_VOLATILE)); 114 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE)); 115 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE)); 116 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET)); 117 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE)); 118 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE)); 119 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET)); 120 #end[CAS] 121 122 #if[AtomicAdd] 123 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD)); 124 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.ADD_AND_GET)); 125 #else[AtomicAdd] 126 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD)); 127 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.ADD_AND_GET)); 128 #end[AtomicAdd] 129 } 130 131 132 @DataProvider 133 public Object[][] typesProvider() throws Exception { 134 List<Object[]> types = new ArrayList<>(); 135 types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccess$Type$.class)}); 136 types.add(new Object[] {vhStaticField, Arrays.asList()}); 137 types.add(new Object[] {vhArray, Arrays.asList($type$[].class, int.class)}); 138 139 return types.stream().toArray(Object[][]::new); 140 } 141 142 @Test(dataProvider = "typesProvider") 143 public void testTypes(VarHandle vh, List<Class<?>> pts) { 144 assertEquals(vh.varType(), $type$.class); 145 146 assertEquals(vh.coordinateTypes(), pts); 147 148 testTypes(vh); 149 } 150 151 152 @Test 153 public void testLookupInstanceToStatic() { 154 checkIAE("Lookup of static final field to instance final field", () -> { 155 MethodHandles.lookup().findStaticVarHandle( 156 VarHandleTestAccess$Type$.class, "final_v", $type$.class); 157 }); 158 159 checkIAE("Lookup of static field to instance field", () -> { 160 MethodHandles.lookup().findStaticVarHandle( 161 VarHandleTestAccess$Type$.class, "v", $type$.class); 162 }); 163 } 164 165 @Test 166 public void testLookupStaticToInstance() { 167 checkIAE("Lookup of instance final field to static final field", () -> { 168 MethodHandles.lookup().findVarHandle( 169 VarHandleTestAccess$Type$.class, "static_final_v", $type$.class); 170 }); 171 172 checkIAE("Lookup of instance field to static field", () -> { 173 vhStaticField = MethodHandles.lookup().findVarHandle( 174 VarHandleTestAccess$Type$.class, "static_v", $type$.class); 175 }); 176 } 177 178 179 @DataProvider 180 public Object[][] accessTestCaseProvider() throws Exception { 181 List<AccessTestCase<?>> cases = new ArrayList<>(); 182 183 cases.add(new VarHandleAccessTestCase("Instance final field", 184 vhFinalField, vh -> testInstanceFinalField(this, vh))); 185 cases.add(new VarHandleAccessTestCase("Instance final field unsupported", 186 vhFinalField, vh -> testInstanceFinalFieldUnsupported(this, vh), 187 false)); 188 189 cases.add(new VarHandleAccessTestCase("Static final field", 190 vhStaticFinalField, VarHandleTestAccess$Type$::testStaticFinalField)); 191 cases.add(new VarHandleAccessTestCase("Static final field unsupported", 192 vhStaticFinalField, VarHandleTestAccess$Type$::testStaticFinalFieldUnsupported, 193 false)); 194 195 cases.add(new VarHandleAccessTestCase("Instance field", 196 vhField, vh -> testInstanceField(this, vh))); 197 cases.add(new VarHandleAccessTestCase("Instance field unsupported", 198 vhField, vh -> testInstanceFieldUnsupported(this, vh), 199 false)); 200 201 cases.add(new VarHandleAccessTestCase("Static field", 202 vhStaticField, VarHandleTestAccess$Type$::testStaticField)); 203 cases.add(new VarHandleAccessTestCase("Static field unsupported", 204 vhStaticField, VarHandleTestAccess$Type$::testStaticFieldUnsupported, 205 false)); 206 207 cases.add(new VarHandleAccessTestCase("Array", 208 vhArray, VarHandleTestAccess$Type$::testArray)); 209 cases.add(new VarHandleAccessTestCase("Array unsupported", 210 vhArray, VarHandleTestAccess$Type$::testArrayUnsupported, 211 false)); 212 cases.add(new VarHandleAccessTestCase("Array index out of bounds", 213 vhArray, VarHandleTestAccess$Type$::testArrayIndexOutOfBounds, 214 false)); 215 216 // Work around issue with jtreg summary reporting which truncates 217 // the String result of Object.toString to 30 characters, hence 218 // the first dummy argument 219 return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); 220 } 221 222 @Test(dataProvider = "accessTestCaseProvider") 223 public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable { 224 T t = atc.get(); 225 int iters = atc.requiresLoop() ? ITERS : 1; 226 for (int c = 0; c < iters; c++) { 227 atc.testAccess(t); 228 } 229 } 230 231 232 233 234 static void testInstanceFinalField(VarHandleTestAccess$Type$ recv, VarHandle vh) { 235 // Plain 236 { 237 $type$ x = ($type$) vh.get(recv); 238 assertEquals(x, $value1$, "get $type$ value"); 239 } 240 241 242 // Volatile 243 { 244 $type$ x = ($type$) vh.getVolatile(recv); 245 assertEquals(x, $value1$, "getVolatile $type$ value"); 246 } 247 248 // Lazy 249 { 250 $type$ x = ($type$) vh.getAcquire(recv); 251 assertEquals(x, $value1$, "getRelease $type$ value"); 252 } 253 254 // Opaque 255 { 256 $type$ x = ($type$) vh.getOpaque(recv); 257 assertEquals(x, $value1$, "getOpaque $type$ value"); 258 } 259 } 260 261 static void testInstanceFinalFieldUnsupported(VarHandleTestAccess$Type$ recv, VarHandle vh) { 262 checkUOE(() -> { 263 vh.set(recv, $value2$); 264 }); 265 266 checkUOE(() -> { 267 vh.setVolatile(recv, $value2$); 268 }); 269 270 checkUOE(() -> { 271 vh.setRelease(recv, $value2$); 272 }); 273 274 checkUOE(() -> { 275 vh.setOpaque(recv, $value2$); 276 }); 277 278 #if[!CAS] 279 checkUOE(() -> { 280 boolean r = vh.compareAndSet(recv, $value1$, $value2$); 281 }); 282 283 checkUOE(() -> { 284 $type$ r = ($type$) vh.compareAndExchangeVolatile(recv, $value1$, $value2$); 285 }); 286 287 checkUOE(() -> { 288 $type$ r = ($type$) vh.compareAndExchangeAcquire(recv, $value1$, $value2$); 289 }); 290 291 checkUOE(() -> { 292 $type$ r = ($type$) vh.compareAndExchangeRelease(recv, $value1$, $value2$); 293 }); 294 295 checkUOE(() -> { 296 boolean r = vh.weakCompareAndSet(recv, $value1$, $value2$); 297 }); 298 299 checkUOE(() -> { 300 boolean r = vh.weakCompareAndSetAcquire(recv, $value1$, $value2$); 301 }); 302 303 checkUOE(() -> { 304 boolean r = vh.weakCompareAndSetRelease(recv, $value1$, $value2$); 305 }); 306 #end[CAS] 307 308 #if[!AtomicAdd] 309 checkUOE(() -> { 310 $type$ o = ($type$) vh.getAndAdd(recv, $value1$); 311 }); 312 313 checkUOE(() -> { 314 $type$ o = ($type$) vh.addAndGet(recv, $value1$); 315 }); 316 #end[AtomicAdd] 317 } 318 319 320 static void testStaticFinalField(VarHandle vh) { 321 // Plain 322 { 323 $type$ x = ($type$) vh.get(); 324 assertEquals(x, $value1$, "get $type$ value"); 325 } 326 327 328 // Volatile 329 { 330 $type$ x = ($type$) vh.getVolatile(); 331 assertEquals(x, $value1$, "getVolatile $type$ value"); 332 } 333 334 // Lazy 335 { 336 $type$ x = ($type$) vh.getAcquire(); 337 assertEquals(x, $value1$, "getRelease $type$ value"); 338 } 339 340 // Opaque 341 { 342 $type$ x = ($type$) vh.getOpaque(); 343 assertEquals(x, $value1$, "getOpaque $type$ value"); 344 } 345 } 346 347 static void testStaticFinalFieldUnsupported(VarHandle vh) { 348 checkUOE(() -> { 349 vh.set($value2$); 350 }); 351 352 checkUOE(() -> { 353 vh.setVolatile($value2$); 354 }); 355 356 checkUOE(() -> { 357 vh.setRelease($value2$); 358 }); 359 360 checkUOE(() -> { 361 vh.setOpaque($value2$); 362 }); 363 364 #if[!CAS] 365 checkUOE(() -> { 366 boolean r = vh.compareAndSet($value1$, $value2$); 367 }); 368 369 checkUOE(() -> { 370 $type$ r = ($type$) vh.compareAndExchangeVolatile($value1$, $value2$); 371 }); 372 373 checkUOE(() -> { 374 $type$ r = ($type$) vh.compareAndExchangeAcquire($value1$, $value2$); 375 }); 376 377 checkUOE(() -> { 378 $type$ r = ($type$) vh.compareAndExchangeRelease($value1$, $value2$); 379 }); 380 381 checkUOE(() -> { 382 boolean r = vh.weakCompareAndSet($value1$, $value2$); 383 }); 384 385 checkUOE(() -> { 386 boolean r = vh.weakCompareAndSetAcquire($value1$, $value2$); 387 }); 388 389 checkUOE(() -> { 390 boolean r = vh.weakCompareAndSetRelease($value1$, $value2$); 391 }); 392 #end[CAS] 393 394 #if[!AtomicAdd] 395 checkUOE(() -> { 396 $type$ o = ($type$) vh.getAndAdd($value1$); 397 }); 398 399 checkUOE(() -> { 400 $type$ o = ($type$) vh.addAndGet($value1$); 401 }); 402 #end[AtomicAdd] 403 } 404 405 406 static void testInstanceField(VarHandleTestAccess$Type$ recv, VarHandle vh) { 407 // Plain 408 { 409 vh.set(recv, $value1$); 410 $type$ x = ($type$) vh.get(recv); 411 assertEquals(x, $value1$, "set $type$ value"); 412 } 413 414 415 // Volatile 416 { 417 vh.setVolatile(recv, $value2$); 418 $type$ x = ($type$) vh.getVolatile(recv); 419 assertEquals(x, $value2$, "setVolatile $type$ value"); 420 } 421 422 // Lazy 423 { 424 vh.setRelease(recv, $value1$); 425 $type$ x = ($type$) vh.getAcquire(recv); 426 assertEquals(x, $value1$, "setRelease $type$ value"); 427 } 428 429 // Opaque 430 { 431 vh.setOpaque(recv, $value2$); 432 $type$ x = ($type$) vh.getOpaque(recv); 433 assertEquals(x, $value2$, "setOpaque $type$ value"); 434 } 435 436 #if[CAS] 437 vh.set(recv, $value1$); 438 439 // Compare 440 { 441 boolean r = vh.compareAndSet(recv, $value1$, $value2$); 442 assertEquals(r, true, "success compareAndSet $type$"); 443 $type$ x = ($type$) vh.get(recv); 444 assertEquals(x, $value2$, "success compareAndSet $type$ value"); 445 } 446 447 { 448 boolean r = vh.compareAndSet(recv, $value1$, $value3$); 449 assertEquals(r, false, "failing compareAndSet $type$"); 450 $type$ x = ($type$) vh.get(recv); 451 assertEquals(x, $value2$, "failing compareAndSet $type$ value"); 452 } 453 454 { 455 $type$ r = ($type$) vh.compareAndExchangeVolatile(recv, $value2$, $value1$); 456 assertEquals(r, $value2$, "success compareAndExchangeVolatile $type$"); 457 $type$ x = ($type$) vh.get(recv); 458 assertEquals(x, $value1$, "success compareAndExchangeVolatile $type$ value"); 459 } 460 461 { 462 $type$ r = ($type$) vh.compareAndExchangeVolatile(recv, $value2$, $value3$); 463 assertEquals(r, $value1$, "failing compareAndExchangeVolatile $type$"); 464 $type$ x = ($type$) vh.get(recv); 465 assertEquals(x, $value1$, "failing compareAndExchangeVolatile $type$ value"); 466 } 467 468 { 469 $type$ r = ($type$) vh.compareAndExchangeAcquire(recv, $value1$, $value2$); 470 assertEquals(r, $value1$, "success compareAndExchangeAcquire $type$"); 471 $type$ x = ($type$) vh.get(recv); 472 assertEquals(x, $value2$, "success compareAndExchangeAcquire $type$ value"); 473 } 474 475 { 476 $type$ r = ($type$) vh.compareAndExchangeAcquire(recv, $value1$, $value3$); 477 assertEquals(r, $value2$, "failing compareAndExchangeAcquire $type$"); 478 $type$ x = ($type$) vh.get(recv); 479 assertEquals(x, $value2$, "failing compareAndExchangeAcquire $type$ value"); 480 } 481 482 { 483 $type$ r = ($type$) vh.compareAndExchangeRelease(recv, $value2$, $value1$); 484 assertEquals(r, $value2$, "success compareAndExchangeRelease $type$"); 485 $type$ x = ($type$) vh.get(recv); 486 assertEquals(x, $value1$, "success compareAndExchangeRelease $type$ value"); 487 } 488 489 { 490 $type$ r = ($type$) vh.compareAndExchangeRelease(recv, $value2$, $value3$); 491 assertEquals(r, $value1$, "failing compareAndExchangeRelease $type$"); 492 $type$ x = ($type$) vh.get(recv); 493 assertEquals(x, $value1$, "failing compareAndExchangeRelease $type$ value"); 494 } 495 496 { 497 boolean success = false; 498 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 499 success = vh.weakCompareAndSet(recv, $value1$, $value2$); 500 } 501 assertEquals(success, true, "weakCompareAndSet $type$"); 502 $type$ x = ($type$) vh.get(recv); 503 assertEquals(x, $value2$, "weakCompareAndSet $type$ value"); 504 } 505 506 { 507 boolean success = false; 508 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 509 success = vh.weakCompareAndSetAcquire(recv, $value2$, $value1$); 510 } 511 assertEquals(success, true, "weakCompareAndSetAcquire $type$"); 512 $type$ x = ($type$) vh.get(recv); 513 assertEquals(x, $value1$, "weakCompareAndSetAcquire $type$"); 514 } 515 516 { 517 boolean success = false; 518 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 519 success = vh.weakCompareAndSetRelease(recv, $value1$, $value2$); 520 } 521 assertEquals(success, true, "weakCompareAndSetRelease $type$"); 522 $type$ x = ($type$) vh.get(recv); 523 assertEquals(x, $value2$, "weakCompareAndSetRelease $type$"); 524 } 525 526 // Compare set and get 527 { 528 $type$ o = ($type$) vh.getAndSet(recv, $value1$); 529 assertEquals(o, $value2$, "getAndSet $type$"); 530 $type$ x = ($type$) vh.get(recv); 531 assertEquals(x, $value1$, "getAndSet $type$ value"); 532 } 533 #end[CAS] 534 535 #if[AtomicAdd] 536 vh.set(recv, $value1$); 537 538 // get and add, add and get 539 { 540 $type$ o = ($type$) vh.getAndAdd(recv, $value3$); 541 assertEquals(o, $value1$, "getAndAdd $type$"); 542 $type$ c = ($type$) vh.addAndGet(recv, $value3$); 543 assertEquals(c, $value1$ + $value3$ + $value3$, "getAndAdd $type$ value"); 544 } 545 #end[AtomicAdd] 546 } 547 548 static void testInstanceFieldUnsupported(VarHandleTestAccess$Type$ recv, VarHandle vh) { 549 #if[!CAS] 550 checkUOE(() -> { 551 boolean r = vh.compareAndSet(recv, $value1$, $value2$); 552 }); 553 554 checkUOE(() -> { 555 $type$ r = ($type$) vh.compareAndExchangeVolatile(recv, $value1$, $value2$); 556 }); 557 558 checkUOE(() -> { 559 $type$ r = ($type$) vh.compareAndExchangeAcquire(recv, $value1$, $value2$); 560 }); 561 562 checkUOE(() -> { 563 $type$ r = ($type$) vh.compareAndExchangeRelease(recv, $value1$, $value2$); 564 }); 565 566 checkUOE(() -> { 567 boolean r = vh.weakCompareAndSet(recv, $value1$, $value2$); 568 }); 569 570 checkUOE(() -> { 571 boolean r = vh.weakCompareAndSetAcquire(recv, $value1$, $value2$); 572 }); 573 574 checkUOE(() -> { 575 boolean r = vh.weakCompareAndSetRelease(recv, $value1$, $value2$); 576 }); 577 #end[CAS] 578 579 #if[!AtomicAdd] 580 checkUOE(() -> { 581 $type$ o = ($type$) vh.getAndAdd(recv, $value1$); 582 }); 583 584 checkUOE(() -> { 585 $type$ o = ($type$) vh.addAndGet(recv, $value1$); 586 }); 587 #end[AtomicAdd] 588 } 589 590 591 static void testStaticField(VarHandle vh) { 592 // Plain 593 { 594 vh.set($value1$); 595 $type$ x = ($type$) vh.get(); 596 assertEquals(x, $value1$, "set $type$ value"); 597 } 598 599 600 // Volatile 601 { 602 vh.setVolatile($value2$); 603 $type$ x = ($type$) vh.getVolatile(); 604 assertEquals(x, $value2$, "setVolatile $type$ value"); 605 } 606 607 // Lazy 608 { 609 vh.setRelease($value1$); 610 $type$ x = ($type$) vh.getAcquire(); 611 assertEquals(x, $value1$, "setRelease $type$ value"); 612 } 613 614 // Opaque 615 { 616 vh.setOpaque($value2$); 617 $type$ x = ($type$) vh.getOpaque(); 618 assertEquals(x, $value2$, "setOpaque $type$ value"); 619 } 620 621 #if[CAS] 622 vh.set($value1$); 623 624 // Compare 625 { 626 boolean r = vh.compareAndSet($value1$, $value2$); 627 assertEquals(r, true, "success compareAndSet $type$"); 628 $type$ x = ($type$) vh.get(); 629 assertEquals(x, $value2$, "success compareAndSet $type$ value"); 630 } 631 632 { 633 boolean r = vh.compareAndSet($value1$, $value3$); 634 assertEquals(r, false, "failing compareAndSet $type$"); 635 $type$ x = ($type$) vh.get(); 636 assertEquals(x, $value2$, "failing compareAndSet $type$ value"); 637 } 638 639 { 640 $type$ r = ($type$) vh.compareAndExchangeVolatile($value2$, $value1$); 641 assertEquals(r, $value2$, "success compareAndExchangeVolatile $type$"); 642 $type$ x = ($type$) vh.get(); 643 assertEquals(x, $value1$, "success compareAndExchangeVolatile $type$ value"); 644 } 645 646 { 647 $type$ r = ($type$) vh.compareAndExchangeVolatile($value2$, $value3$); 648 assertEquals(r, $value1$, "failing compareAndExchangeVolatile $type$"); 649 $type$ x = ($type$) vh.get(); 650 assertEquals(x, $value1$, "failing compareAndExchangeVolatile $type$ value"); 651 } 652 653 { 654 $type$ r = ($type$) vh.compareAndExchangeAcquire($value1$, $value2$); 655 assertEquals(r, $value1$, "success compareAndExchangeAcquire $type$"); 656 $type$ x = ($type$) vh.get(); 657 assertEquals(x, $value2$, "success compareAndExchangeAcquire $type$ value"); 658 } 659 660 { 661 $type$ r = ($type$) vh.compareAndExchangeAcquire($value1$, $value3$); 662 assertEquals(r, $value2$, "failing compareAndExchangeAcquire $type$"); 663 $type$ x = ($type$) vh.get(); 664 assertEquals(x, $value2$, "failing compareAndExchangeAcquire $type$ value"); 665 } 666 667 { 668 $type$ r = ($type$) vh.compareAndExchangeRelease($value2$, $value1$); 669 assertEquals(r, $value2$, "success compareAndExchangeRelease $type$"); 670 $type$ x = ($type$) vh.get(); 671 assertEquals(x, $value1$, "success compareAndExchangeRelease $type$ value"); 672 } 673 674 { 675 $type$ r = ($type$) vh.compareAndExchangeRelease($value2$, $value3$); 676 assertEquals(r, $value1$, "failing compareAndExchangeRelease $type$"); 677 $type$ x = ($type$) vh.get(); 678 assertEquals(x, $value1$, "failing compareAndExchangeRelease $type$ value"); 679 } 680 681 { 682 boolean success = false; 683 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 684 success = vh.weakCompareAndSet($value1$, $value2$); 685 } 686 assertEquals(success, true, "weakCompareAndSet $type$"); 687 $type$ x = ($type$) vh.get(); 688 assertEquals(x, $value2$, "weakCompareAndSet $type$ value"); 689 } 690 691 { 692 boolean success = false; 693 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 694 success = vh.weakCompareAndSetAcquire($value2$, $value1$); 695 } 696 assertEquals(success, true, "weakCompareAndSetAcquire $type$"); 697 $type$ x = ($type$) vh.get(); 698 assertEquals(x, $value1$, "weakCompareAndSetAcquire $type$"); 699 } 700 701 { 702 boolean success = false; 703 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 704 success = vh.weakCompareAndSetRelease($value1$, $value2$); 705 } 706 assertEquals(success, true, "weakCompareAndSetRelease $type$"); 707 $type$ x = ($type$) vh.get(); 708 assertEquals(x, $value2$, "weakCompareAndSetRelease $type$"); 709 } 710 711 // Compare set and get 712 { 713 $type$ o = ($type$) vh.getAndSet( $value1$); 714 assertEquals(o, $value2$, "getAndSet $type$"); 715 $type$ x = ($type$) vh.get(); 716 assertEquals(x, $value1$, "getAndSet $type$ value"); 717 } 718 #end[CAS] 719 720 #if[AtomicAdd] 721 vh.set($value1$); 722 723 // get and add, add and get 724 { 725 $type$ o = ($type$) vh.getAndAdd( $value3$); 726 assertEquals(o, $value1$, "getAndAdd $type$"); 727 $type$ c = ($type$) vh.addAndGet($value3$); 728 assertEquals(c, $value1$ + $value3$ + $value3$, "getAndAdd $type$ value"); 729 } 730 #end[AtomicAdd] 731 } 732 733 static void testStaticFieldUnsupported(VarHandle vh) { 734 #if[!CAS] 735 checkUOE(() -> { 736 boolean r = vh.compareAndSet($value1$, $value2$); 737 }); 738 739 checkUOE(() -> { 740 $type$ r = ($type$) vh.compareAndExchangeVolatile($value1$, $value2$); 741 }); 742 743 checkUOE(() -> { 744 $type$ r = ($type$) vh.compareAndExchangeAcquire($value1$, $value2$); 745 }); 746 747 checkUOE(() -> { 748 $type$ r = ($type$) vh.compareAndExchangeRelease($value1$, $value2$); 749 }); 750 751 checkUOE(() -> { 752 boolean r = vh.weakCompareAndSet($value1$, $value2$); 753 }); 754 755 checkUOE(() -> { 756 boolean r = vh.weakCompareAndSetAcquire($value1$, $value2$); 757 }); 758 759 checkUOE(() -> { 760 boolean r = vh.weakCompareAndSetRelease($value1$, $value2$); 761 }); 762 #end[CAS] 763 764 #if[!AtomicAdd] 765 checkUOE(() -> { 766 $type$ o = ($type$) vh.getAndAdd($value1$); 767 }); 768 769 checkUOE(() -> { 770 $type$ o = ($type$) vh.addAndGet($value1$); 771 }); 772 #end[AtomicAdd] 773 } 774 775 776 static void testArray(VarHandle vh) { 777 $type$[] array = new $type$[10]; 778 779 for (int i = 0; i < array.length; i++) { 780 // Plain 781 { 782 vh.set(array, i, $value1$); 783 $type$ x = ($type$) vh.get(array, i); 784 assertEquals(x, $value1$, "get $type$ value"); 785 } 786 787 788 // Volatile 789 { 790 vh.setVolatile(array, i, $value2$); 791 $type$ x = ($type$) vh.getVolatile(array, i); 792 assertEquals(x, $value2$, "setVolatile $type$ value"); 793 } 794 795 // Lazy 796 { 797 vh.setRelease(array, i, $value1$); 798 $type$ x = ($type$) vh.getAcquire(array, i); 799 assertEquals(x, $value1$, "setRelease $type$ value"); 800 } 801 802 // Opaque 803 { 804 vh.setOpaque(array, i, $value2$); 805 $type$ x = ($type$) vh.getOpaque(array, i); 806 assertEquals(x, $value2$, "setOpaque $type$ value"); 807 } 808 809 #if[CAS] 810 vh.set(array, i, $value1$); 811 812 // Compare 813 { 814 boolean r = vh.compareAndSet(array, i, $value1$, $value2$); 815 assertEquals(r, true, "success compareAndSet $type$"); 816 $type$ x = ($type$) vh.get(array, i); 817 assertEquals(x, $value2$, "success compareAndSet $type$ value"); 818 } 819 820 { 821 boolean r = vh.compareAndSet(array, i, $value1$, $value3$); 822 assertEquals(r, false, "failing compareAndSet $type$"); 823 $type$ x = ($type$) vh.get(array, i); 824 assertEquals(x, $value2$, "failing compareAndSet $type$ value"); 825 } 826 827 { 828 $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, $value2$, $value1$); 829 assertEquals(r, $value2$, "success compareAndExchangeVolatile $type$"); 830 $type$ x = ($type$) vh.get(array, i); 831 assertEquals(x, $value1$, "success compareAndExchangeVolatile $type$ value"); 832 } 833 834 { 835 $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, $value2$, $value3$); 836 assertEquals(r, $value1$, "failing compareAndExchangeVolatile $type$"); 837 $type$ x = ($type$) vh.get(array, i); 838 assertEquals(x, $value1$, "failing compareAndExchangeVolatile $type$ value"); 839 } 840 841 { 842 $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, $value1$, $value2$); 843 assertEquals(r, $value1$, "success compareAndExchangeAcquire $type$"); 844 $type$ x = ($type$) vh.get(array, i); 845 assertEquals(x, $value2$, "success compareAndExchangeAcquire $type$ value"); 846 } 847 848 { 849 $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, $value1$, $value3$); 850 assertEquals(r, $value2$, "failing compareAndExchangeAcquire $type$"); 851 $type$ x = ($type$) vh.get(array, i); 852 assertEquals(x, $value2$, "failing compareAndExchangeAcquire $type$ value"); 853 } 854 855 { 856 $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, $value2$, $value1$); 857 assertEquals(r, $value2$, "success compareAndExchangeRelease $type$"); 858 $type$ x = ($type$) vh.get(array, i); 859 assertEquals(x, $value1$, "success compareAndExchangeRelease $type$ value"); 860 } 861 862 { 863 $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, $value2$, $value3$); 864 assertEquals(r, $value1$, "failing compareAndExchangeRelease $type$"); 865 $type$ x = ($type$) vh.get(array, i); 866 assertEquals(x, $value1$, "failing compareAndExchangeRelease $type$ value"); 867 } 868 869 { 870 boolean success = false; 871 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 872 success = vh.weakCompareAndSet(array, i, $value1$, $value2$); 873 } 874 assertEquals(success, true, "weakCompareAndSet $type$"); 875 $type$ x = ($type$) vh.get(array, i); 876 assertEquals(x, $value2$, "weakCompareAndSet $type$ value"); 877 } 878 879 { 880 boolean success = false; 881 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 882 success = vh.weakCompareAndSetAcquire(array, i, $value2$, $value1$); 883 } 884 assertEquals(success, true, "weakCompareAndSetAcquire $type$"); 885 $type$ x = ($type$) vh.get(array, i); 886 assertEquals(x, $value1$, "weakCompareAndSetAcquire $type$"); 887 } 888 889 { 890 boolean success = false; 891 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 892 success = vh.weakCompareAndSetRelease(array, i, $value1$, $value2$); 893 } 894 assertEquals(success, true, "weakCompareAndSetRelease $type$"); 895 $type$ x = ($type$) vh.get(array, i); 896 assertEquals(x, $value2$, "weakCompareAndSetRelease $type$"); 897 } 898 899 // Compare set and get 900 { 901 $type$ o = ($type$) vh.getAndSet(array, i, $value1$); 902 assertEquals(o, $value2$, "getAndSet $type$"); 903 $type$ x = ($type$) vh.get(array, i); 904 assertEquals(x, $value1$, "getAndSet $type$ value"); 905 } 906 #end[CAS] 907 908 #if[AtomicAdd] 909 vh.set(array, i, $value1$); 910 911 // get and add, add and get 912 { 913 $type$ o = ($type$) vh.getAndAdd(array, i, $value3$); 914 assertEquals(o, $value1$, "getAndAdd $type$"); 915 $type$ c = ($type$) vh.addAndGet(array, i, $value3$); 916 assertEquals(c, $value1$ + $value3$ + $value3$, "getAndAdd $type$ value"); 917 } 918 #end[AtomicAdd] 919 } 920 } 921 922 static void testArrayUnsupported(VarHandle vh) { 923 $type$[] array = new $type$[10]; 924 925 int i = 0; 926 #if[!CAS] 927 checkUOE(() -> { 928 boolean r = vh.compareAndSet(array, i, $value1$, $value2$); 929 }); 930 931 checkUOE(() -> { 932 $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, $value1$, $value2$); 933 }); 934 935 checkUOE(() -> { 936 $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, $value1$, $value2$); 937 }); 938 939 checkUOE(() -> { 940 $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, $value1$, $value2$); 941 }); 942 943 checkUOE(() -> { 944 boolean r = vh.weakCompareAndSet(array, i, $value1$, $value2$); 945 }); 946 947 checkUOE(() -> { 948 boolean r = vh.weakCompareAndSetAcquire(array, i, $value1$, $value2$); 949 }); 950 951 checkUOE(() -> { 952 boolean r = vh.weakCompareAndSetRelease(array, i, $value1$, $value2$); 953 }); 954 #end[CAS] 955 956 #if[!AtomicAdd] 957 checkUOE(() -> { 958 $type$ o = ($type$) vh.getAndAdd(array, i, $value1$); 959 }); 960 961 checkUOE(() -> { 962 $type$ o = ($type$) vh.addAndGet(array, i, $value1$); 963 }); 964 #end[AtomicAdd] 965 } 966 967 static void testArrayIndexOutOfBounds(VarHandle vh) throws Throwable { 968 $type$[] array = new $type$[10]; 969 970 for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) { 971 final int ci = i; 972 973 checkIOOBE(() -> { 974 $type$ x = ($type$) vh.get(array, ci); 975 }); 976 977 checkIOOBE(() -> { 978 vh.set(array, ci, $value1$); 979 }); 980 981 checkIOOBE(() -> { 982 $type$ x = ($type$) vh.getVolatile(array, ci); 983 }); 984 985 checkIOOBE(() -> { 986 vh.setVolatile(array, ci, $value1$); 987 }); 988 989 checkIOOBE(() -> { 990 $type$ x = ($type$) vh.getAcquire(array, ci); 991 }); 992 993 checkIOOBE(() -> { 994 vh.setRelease(array, ci, $value1$); 995 }); 996 997 checkIOOBE(() -> { 998 $type$ x = ($type$) vh.getOpaque(array, ci); 999 }); 1000 1001 checkIOOBE(() -> { 1002 vh.setOpaque(array, ci, $value1$); 1003 }); 1004 1005 #if[CAS] 1006 checkIOOBE(() -> { 1007 boolean r = vh.compareAndSet(array, ci, $value1$, $value2$); 1008 }); 1009 1010 checkIOOBE(() -> { 1011 $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, $value2$, $value1$); 1012 }); 1013 1014 checkIOOBE(() -> { 1015 $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, $value2$, $value1$); 1016 }); 1017 1018 checkIOOBE(() -> { 1019 $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, $value2$, $value1$); 1020 }); 1021 1022 checkIOOBE(() -> { 1023 boolean r = vh.weakCompareAndSet(array, ci, $value1$, $value2$); 1024 }); 1025 1026 checkIOOBE(() -> { 1027 boolean r = vh.weakCompareAndSetAcquire(array, ci, $value1$, $value2$); 1028 }); 1029 1030 checkIOOBE(() -> { 1031 boolean r = vh.weakCompareAndSetRelease(array, ci, $value1$, $value2$); 1032 }); 1033 1034 checkIOOBE(() -> { 1035 $type$ o = ($type$) vh.getAndSet(array, ci, $value1$); 1036 }); 1037 #end[CAS] 1038 1039 #if[AtomicAdd] 1040 checkIOOBE(() -> { 1041 $type$ o = ($type$) vh.getAndAdd(array, ci, $value3$); 1042 }); 1043 1044 checkIOOBE(() -> { 1045 $type$ o = ($type$) vh.addAndGet(array, ci, $value3$); 1046 }); 1047 #end[AtomicAdd] 1048 } 1049 } 1050 } 1051