1 /* 2 * Copyright (c) 2015, 2023, 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 * @comment Set CompileThresholdScaling to 0.1 so that the warmup loop sets to 2000 iterations 27 * to hit compilation thresholds 28 * @run testng/othervm -Diters=2000 -XX:CompileThresholdScaling=0.1 VarHandleTestMethodHandleAccessString 29 */ 30 31 import org.testng.annotations.BeforeClass; 32 import org.testng.annotations.DataProvider; 33 import org.testng.annotations.Test; 34 35 import java.lang.invoke.MethodHandle; 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 VarHandleTestMethodHandleAccessString extends VarHandleBaseTest { 45 static final String static_final_v = "foo"; 46 47 static String static_v; 48 49 final String final_v = "foo"; 50 51 String 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 VarHandleTestMethodHandleAccessString.class, "final_v", String.class); 67 68 vhField = MethodHandles.lookup().findVarHandle( 69 VarHandleTestMethodHandleAccessString.class, "v", String.class); 70 71 vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle( 72 VarHandleTestMethodHandleAccessString.class, "static_final_v", String.class); 73 74 vhStaticField = MethodHandles.lookup().findStaticVarHandle( 75 VarHandleTestMethodHandleAccessString.class, "static_v", String.class); 76 77 vhArray = MethodHandles.arrayElementVarHandle(String[].class); 78 } 79 80 81 @DataProvider 82 public Object[][] accessTestCaseProvider() throws Exception { 83 List<AccessTestCase<?>> cases = new ArrayList<>(); 84 85 for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) { 86 cases.add(new MethodHandleAccessTestCase("Instance field", 87 vhField, f, hs -> testInstanceField(this, hs))); 88 cases.add(new MethodHandleAccessTestCase("Instance field unsupported", 89 vhField, f, hs -> testInstanceFieldUnsupported(this, hs), 90 false)); 91 92 cases.add(new MethodHandleAccessTestCase("Static field", 93 vhStaticField, f, VarHandleTestMethodHandleAccessString::testStaticField)); 94 cases.add(new MethodHandleAccessTestCase("Static field unsupported", 95 vhStaticField, f, VarHandleTestMethodHandleAccessString::testStaticFieldUnsupported, 96 false)); 97 98 cases.add(new MethodHandleAccessTestCase("Array", 99 vhArray, f, VarHandleTestMethodHandleAccessString::testArray)); 100 cases.add(new MethodHandleAccessTestCase("Array unsupported", 101 vhArray, f, VarHandleTestMethodHandleAccessString::testArrayUnsupported, 102 false)); 103 cases.add(new MethodHandleAccessTestCase("Array index out of bounds", 104 vhArray, f, VarHandleTestMethodHandleAccessString::testArrayIndexOutOfBounds, 105 false)); 106 } 107 108 // Work around issue with jtreg summary reporting which truncates 109 // the String result of Object.toString to 30 characters, hence 110 // the first dummy argument 111 return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); 112 } 113 114 @Test(dataProvider = "accessTestCaseProvider") 115 public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable { 116 T t = atc.get(); 117 int iters = atc.requiresLoop() ? ITERS : 1; 118 for (int c = 0; c < iters; c++) { 119 atc.testAccess(t); 120 } 121 } 122 123 124 static void testInstanceField(VarHandleTestMethodHandleAccessString recv, Handles hs) throws Throwable { 125 // Plain 126 { 127 hs.get(TestAccessMode.SET).invokeExact(recv, "foo"); 128 String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); 129 assertEquals(x, "foo", "set String value"); 130 } 131 132 133 // Volatile 134 { 135 hs.get(TestAccessMode.SET_VOLATILE).invokeExact(recv, "bar"); 136 String x = (String) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(recv); 137 assertEquals(x, "bar", "setVolatile String value"); 138 } 139 140 // Lazy 141 { 142 hs.get(TestAccessMode.SET_RELEASE).invokeExact(recv, "foo"); 143 String x = (String) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(recv); 144 assertEquals(x, "foo", "setRelease String value"); 145 } 146 147 // Opaque 148 { 149 hs.get(TestAccessMode.SET_OPAQUE).invokeExact(recv, "bar"); 150 String x = (String) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(recv); 151 assertEquals(x, "bar", "setOpaque String value"); 152 } 153 154 hs.get(TestAccessMode.SET).invokeExact(recv, "foo"); 155 156 // Compare 157 { 158 boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(recv, "foo", "bar"); 159 assertEquals(r, true, "success compareAndSet String"); 160 String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); 161 assertEquals(x, "bar", "success compareAndSet String value"); 162 } 163 164 { 165 boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(recv, "foo", "baz"); 166 assertEquals(r, false, "failing compareAndSet String"); 167 String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); 168 assertEquals(x, "bar", "failing compareAndSet String value"); 169 } 170 171 { 172 String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(recv, "bar", "foo"); 173 assertEquals(r, "bar", "success compareAndExchange String"); 174 String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); 175 assertEquals(x, "foo", "success compareAndExchange String value"); 176 } 177 178 { 179 String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(recv, "bar", "baz"); 180 assertEquals(r, "foo", "failing compareAndExchange String"); 181 String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); 182 assertEquals(x, "foo", "failing compareAndExchange String value"); 183 } 184 185 { 186 String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(recv, "foo", "bar"); 187 assertEquals(r, "foo", "success compareAndExchangeAcquire String"); 188 String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); 189 assertEquals(x, "bar", "success compareAndExchangeAcquire String value"); 190 } 191 192 { 193 String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(recv, "foo", "baz"); 194 assertEquals(r, "bar", "failing compareAndExchangeAcquire String"); 195 String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); 196 assertEquals(x, "bar", "failing compareAndExchangeAcquire String value"); 197 } 198 199 { 200 String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(recv, "bar", "foo"); 201 assertEquals(r, "bar", "success compareAndExchangeRelease String"); 202 String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); 203 assertEquals(x, "foo", "success compareAndExchangeRelease String value"); 204 } 205 206 { 207 String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(recv, "bar", "baz"); 208 assertEquals(r, "foo", "failing compareAndExchangeRelease String"); 209 String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); 210 assertEquals(x, "foo", "failing compareAndExchangeRelease String value"); 211 } 212 213 { 214 MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN); 215 boolean success = false; 216 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 217 success = (boolean) mh.invokeExact(recv, "foo", "bar"); 218 if (!success) weakDelay(); 219 } 220 assertEquals(success, true, "success weakCompareAndSetPlain String"); 221 String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); 222 assertEquals(x, "bar", "success weakCompareAndSetPlain String value"); 223 } 224 225 { 226 boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, "foo", "baz"); 227 assertEquals(success, false, "failing weakCompareAndSetPlain String"); 228 String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); 229 assertEquals(x, "bar", "failing weakCompareAndSetPlain String value"); 230 } 231 232 { 233 MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); 234 boolean success = false; 235 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 236 success = (boolean) mh.invokeExact(recv, "bar", "foo"); 237 if (!success) weakDelay(); 238 } 239 assertEquals(success, true, "success weakCompareAndSetAcquire String"); 240 String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); 241 assertEquals(x, "foo", "success weakCompareAndSetAcquire String"); 242 } 243 244 { 245 boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, "bar", "baz"); 246 assertEquals(success, false, "failing weakCompareAndSetAcquire String"); 247 String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); 248 assertEquals(x, "foo", "failing weakCompareAndSetAcquire String value"); 249 } 250 251 { 252 MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE); 253 boolean success = false; 254 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 255 success = (boolean) mh.invokeExact(recv, "foo", "bar"); 256 if (!success) weakDelay(); 257 } 258 assertEquals(success, true, "success weakCompareAndSetRelease String"); 259 String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); 260 assertEquals(x, "bar", "success weakCompareAndSetRelease String"); 261 } 262 263 { 264 boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, "foo", "baz"); 265 assertEquals(success, false, "failing weakCompareAndSetRelease String"); 266 String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); 267 assertEquals(x, "bar", "failing weakCompareAndSetRelease String value"); 268 } 269 270 { 271 boolean success = false; 272 MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET); 273 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 274 success = (boolean) mh.invokeExact(recv, "bar", "foo"); 275 if (!success) weakDelay(); 276 } 277 assertEquals(success, true, "success weakCompareAndSet String"); 278 String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); 279 assertEquals(x, "foo", "success weakCompareAndSet String"); 280 } 281 282 { 283 boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, "bar", "baz"); 284 assertEquals(success, false, "failing weakCompareAndSet String"); 285 String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); 286 assertEquals(x, "foo", "failing weakCompareAndSet String value"); 287 } 288 289 // Compare set and get 290 { 291 String o = (String) hs.get(TestAccessMode.GET_AND_SET).invokeExact(recv, "bar"); 292 assertEquals(o, "foo", "getAndSet String"); 293 String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); 294 assertEquals(x, "bar", "getAndSet String value"); 295 } 296 297 298 } 299 300 static void testInstanceFieldUnsupported(VarHandleTestMethodHandleAccessString recv, Handles hs) throws Throwable { 301 302 for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_ADD)) { 303 checkUOE(am, () -> { 304 String r = (String) hs.get(am).invokeExact(recv, "foo"); 305 }); 306 } 307 308 for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_BITWISE)) { 309 checkUOE(am, () -> { 310 String r = (String) hs.get(am).invokeExact(recv, "foo"); 311 }); 312 } 313 } 314 315 316 static void testStaticField(Handles hs) throws Throwable { 317 // Plain 318 { 319 hs.get(TestAccessMode.SET).invokeExact("foo"); 320 String x = (String) hs.get(TestAccessMode.GET).invokeExact(); 321 assertEquals(x, "foo", "set String value"); 322 } 323 324 325 // Volatile 326 { 327 hs.get(TestAccessMode.SET_VOLATILE).invokeExact("bar"); 328 String x = (String) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(); 329 assertEquals(x, "bar", "setVolatile String value"); 330 } 331 332 // Lazy 333 { 334 hs.get(TestAccessMode.SET_RELEASE).invokeExact("foo"); 335 String x = (String) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(); 336 assertEquals(x, "foo", "setRelease String value"); 337 } 338 339 // Opaque 340 { 341 hs.get(TestAccessMode.SET_OPAQUE).invokeExact("bar"); 342 String x = (String) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(); 343 assertEquals(x, "bar", "setOpaque String value"); 344 } 345 346 hs.get(TestAccessMode.SET).invokeExact("foo"); 347 348 // Compare 349 { 350 boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact("foo", "bar"); 351 assertEquals(r, true, "success compareAndSet String"); 352 String x = (String) hs.get(TestAccessMode.GET).invokeExact(); 353 assertEquals(x, "bar", "success compareAndSet String value"); 354 } 355 356 { 357 boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact("foo", "baz"); 358 assertEquals(r, false, "failing compareAndSet String"); 359 String x = (String) hs.get(TestAccessMode.GET).invokeExact(); 360 assertEquals(x, "bar", "failing compareAndSet String value"); 361 } 362 363 { 364 String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact("bar", "foo"); 365 assertEquals(r, "bar", "success compareAndExchange String"); 366 String x = (String) hs.get(TestAccessMode.GET).invokeExact(); 367 assertEquals(x, "foo", "success compareAndExchange String value"); 368 } 369 370 { 371 String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact("bar", "baz"); 372 assertEquals(r, "foo", "failing compareAndExchange String"); 373 String x = (String) hs.get(TestAccessMode.GET).invokeExact(); 374 assertEquals(x, "foo", "failing compareAndExchange String value"); 375 } 376 377 { 378 String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact("foo", "bar"); 379 assertEquals(r, "foo", "success compareAndExchangeAcquire String"); 380 String x = (String) hs.get(TestAccessMode.GET).invokeExact(); 381 assertEquals(x, "bar", "success compareAndExchangeAcquire String value"); 382 } 383 384 { 385 String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact("foo", "baz"); 386 assertEquals(r, "bar", "failing compareAndExchangeAcquire String"); 387 String x = (String) hs.get(TestAccessMode.GET).invokeExact(); 388 assertEquals(x, "bar", "failing compareAndExchangeAcquire String value"); 389 } 390 391 { 392 String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact("bar", "foo"); 393 assertEquals(r, "bar", "success compareAndExchangeRelease String"); 394 String x = (String) hs.get(TestAccessMode.GET).invokeExact(); 395 assertEquals(x, "foo", "success compareAndExchangeRelease String value"); 396 } 397 398 { 399 String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact("bar", "baz"); 400 assertEquals(r, "foo", "failing compareAndExchangeRelease String"); 401 String x = (String) hs.get(TestAccessMode.GET).invokeExact(); 402 assertEquals(x, "foo", "failing compareAndExchangeRelease String value"); 403 } 404 405 { 406 MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN); 407 boolean success = false; 408 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 409 success = (boolean) mh.invokeExact("foo", "bar"); 410 if (!success) weakDelay(); 411 } 412 assertEquals(success, true, "success weakCompareAndSetPlain String"); 413 String x = (String) hs.get(TestAccessMode.GET).invokeExact(); 414 assertEquals(x, "bar", "success weakCompareAndSetPlain String value"); 415 } 416 417 { 418 boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact("foo", "baz"); 419 assertEquals(success, false, "failing weakCompareAndSetPlain String"); 420 String x = (String) hs.get(TestAccessMode.GET).invokeExact(); 421 assertEquals(x, "bar", "failing weakCompareAndSetPlain String value"); 422 } 423 424 { 425 MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); 426 boolean success = false; 427 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 428 success = (boolean) mh.invokeExact("bar", "foo"); 429 if (!success) weakDelay(); 430 } 431 assertEquals(success, true, "success weakCompareAndSetAcquire String"); 432 String x = (String) hs.get(TestAccessMode.GET).invokeExact(); 433 assertEquals(x, "foo", "success weakCompareAndSetAcquire String"); 434 } 435 436 { 437 MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); 438 boolean success = (boolean) mh.invokeExact("bar", "baz"); 439 assertEquals(success, false, "failing weakCompareAndSetAcquire String"); 440 String x = (String) hs.get(TestAccessMode.GET).invokeExact(); 441 assertEquals(x, "foo", "failing weakCompareAndSetAcquire String value"); 442 } 443 444 { 445 MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE); 446 boolean success = false; 447 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 448 success = (boolean) mh.invokeExact("foo", "bar"); 449 if (!success) weakDelay(); 450 } 451 assertEquals(success, true, "success weakCompareAndSetRelease String"); 452 String x = (String) hs.get(TestAccessMode.GET).invokeExact(); 453 assertEquals(x, "bar", "success weakCompareAndSetRelease String"); 454 } 455 456 { 457 boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact("foo", "baz"); 458 assertEquals(success, false, "failing weakCompareAndSetRelease String"); 459 String x = (String) hs.get(TestAccessMode.GET).invokeExact(); 460 assertEquals(x, "bar", "failing weakCompareAndSetRelease String value"); 461 } 462 463 { 464 MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET); 465 boolean success = false; 466 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 467 success = (boolean) mh.invokeExact("bar", "foo"); 468 if (!success) weakDelay(); 469 } 470 assertEquals(success, true, "success weakCompareAndSet String"); 471 String x = (String) hs.get(TestAccessMode.GET).invokeExact(); 472 assertEquals(x, "foo", "success weakCompareAndSet String"); 473 } 474 475 { 476 boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact("bar", "baz"); 477 assertEquals(success, false, "failing weakCompareAndSet String"); 478 String x = (String) hs.get(TestAccessMode.GET).invokeExact(); 479 assertEquals(x, "foo", "failing weakCompareAndSetRe String value"); 480 } 481 482 // Compare set and get 483 { 484 hs.get(TestAccessMode.SET).invokeExact("foo"); 485 486 String o = (String) hs.get(TestAccessMode.GET_AND_SET).invokeExact("bar"); 487 assertEquals(o, "foo", "getAndSet String"); 488 String x = (String) hs.get(TestAccessMode.GET).invokeExact(); 489 assertEquals(x, "bar", "getAndSet String value"); 490 } 491 492 // Compare set and get 493 { 494 hs.get(TestAccessMode.SET).invokeExact("foo"); 495 496 String o = (String) hs.get(TestAccessMode.GET_AND_SET_ACQUIRE).invokeExact("bar"); 497 assertEquals(o, "foo", "getAndSetAcquire String"); 498 String x = (String) hs.get(TestAccessMode.GET).invokeExact(); 499 assertEquals(x, "bar", "getAndSetAcquire String value"); 500 } 501 502 // Compare set and get 503 { 504 hs.get(TestAccessMode.SET).invokeExact("foo"); 505 506 String o = (String) hs.get(TestAccessMode.GET_AND_SET_RELEASE).invokeExact("bar"); 507 assertEquals(o, "foo", "getAndSetRelease String"); 508 String x = (String) hs.get(TestAccessMode.GET).invokeExact(); 509 assertEquals(x, "bar", "getAndSetRelease String value"); 510 } 511 512 513 } 514 515 static void testStaticFieldUnsupported(Handles hs) throws Throwable { 516 517 for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_ADD)) { 518 checkUOE(am, () -> { 519 String r = (String) hs.get(am).invokeExact("foo"); 520 }); 521 } 522 523 for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_BITWISE)) { 524 checkUOE(am, () -> { 525 String r = (String) hs.get(am).invokeExact("foo"); 526 }); 527 } 528 } 529 530 531 static void testArray(Handles hs) throws Throwable { 532 String[] array = new String[10]; 533 534 for (int i = 0; i < array.length; i++) { 535 // Plain 536 { 537 hs.get(TestAccessMode.SET).invokeExact(array, i, "foo"); 538 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); 539 assertEquals(x, "foo", "get String value"); 540 } 541 542 543 // Volatile 544 { 545 hs.get(TestAccessMode.SET_VOLATILE).invokeExact(array, i, "bar"); 546 String x = (String) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(array, i); 547 assertEquals(x, "bar", "setVolatile String value"); 548 } 549 550 // Lazy 551 { 552 hs.get(TestAccessMode.SET_RELEASE).invokeExact(array, i, "foo"); 553 String x = (String) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(array, i); 554 assertEquals(x, "foo", "setRelease String value"); 555 } 556 557 // Opaque 558 { 559 hs.get(TestAccessMode.SET_OPAQUE).invokeExact(array, i, "bar"); 560 String x = (String) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(array, i); 561 assertEquals(x, "bar", "setOpaque String value"); 562 } 563 564 hs.get(TestAccessMode.SET).invokeExact(array, i, "foo"); 565 566 // Compare 567 { 568 boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(array, i, "foo", "bar"); 569 assertEquals(r, true, "success compareAndSet String"); 570 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); 571 assertEquals(x, "bar", "success compareAndSet String value"); 572 } 573 574 { 575 boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(array, i, "foo", "baz"); 576 assertEquals(r, false, "failing compareAndSet String"); 577 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); 578 assertEquals(x, "bar", "failing compareAndSet String value"); 579 } 580 581 { 582 String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(array, i, "bar", "foo"); 583 assertEquals(r, "bar", "success compareAndExchange String"); 584 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); 585 assertEquals(x, "foo", "success compareAndExchange String value"); 586 } 587 588 { 589 String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(array, i, "bar", "baz"); 590 assertEquals(r, "foo", "failing compareAndExchange String"); 591 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); 592 assertEquals(x, "foo", "failing compareAndExchange String value"); 593 } 594 595 { 596 String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(array, i, "foo", "bar"); 597 assertEquals(r, "foo", "success compareAndExchangeAcquire String"); 598 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); 599 assertEquals(x, "bar", "success compareAndExchangeAcquire String value"); 600 } 601 602 { 603 String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(array, i, "foo", "baz"); 604 assertEquals(r, "bar", "failing compareAndExchangeAcquire String"); 605 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); 606 assertEquals(x, "bar", "failing compareAndExchangeAcquire String value"); 607 } 608 609 { 610 String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(array, i, "bar", "foo"); 611 assertEquals(r, "bar", "success compareAndExchangeRelease String"); 612 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); 613 assertEquals(x, "foo", "success compareAndExchangeRelease String value"); 614 } 615 616 { 617 String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(array, i, "bar", "baz"); 618 assertEquals(r, "foo", "failing compareAndExchangeRelease String"); 619 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); 620 assertEquals(x, "foo", "failing compareAndExchangeRelease String value"); 621 } 622 623 { 624 MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN); 625 boolean success = false; 626 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 627 success = (boolean) mh.invokeExact(array, i, "foo", "bar"); 628 if (!success) weakDelay(); 629 } 630 assertEquals(success, true, "success weakCompareAndSetPlain String"); 631 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); 632 assertEquals(x, "bar", "success weakCompareAndSetPlain String value"); 633 } 634 635 { 636 boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, "foo", "baz"); 637 assertEquals(success, false, "failing weakCompareAndSetPlain String"); 638 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); 639 assertEquals(x, "bar", "failing weakCompareAndSetPlain String value"); 640 } 641 642 { 643 MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE); 644 boolean success = false; 645 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 646 success = (boolean) mh.invokeExact(array, i, "bar", "foo"); 647 if (!success) weakDelay(); 648 } 649 assertEquals(success, true, "success weakCompareAndSetAcquire String"); 650 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); 651 assertEquals(x, "foo", "success weakCompareAndSetAcquire String"); 652 } 653 654 { 655 boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, "bar", "baz"); 656 assertEquals(success, false, "failing weakCompareAndSetAcquire String"); 657 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); 658 assertEquals(x, "foo", "failing weakCompareAndSetAcquire String value"); 659 } 660 661 { 662 MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE); 663 boolean success = false; 664 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 665 success = (boolean) mh.invokeExact(array, i, "foo", "bar"); 666 if (!success) weakDelay(); 667 } 668 assertEquals(success, true, "success weakCompareAndSetRelease String"); 669 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); 670 assertEquals(x, "bar", "success weakCompareAndSetRelease String"); 671 } 672 673 { 674 boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, "foo", "baz"); 675 assertEquals(success, false, "failing weakCompareAndSetAcquire String"); 676 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); 677 assertEquals(x, "bar", "failing weakCompareAndSetAcquire String value"); 678 } 679 680 { 681 MethodHandle mh = hs.get(TestAccessMode.WEAK_COMPARE_AND_SET); 682 boolean success = false; 683 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 684 success = (boolean) mh.invokeExact(array, i, "bar", "foo"); 685 if (!success) weakDelay(); 686 } 687 assertEquals(success, true, "success weakCompareAndSet String"); 688 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); 689 assertEquals(x, "foo", "success weakCompareAndSet String"); 690 } 691 692 { 693 boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, "bar", "baz"); 694 assertEquals(success, false, "failing weakCompareAndSet String"); 695 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); 696 assertEquals(x, "foo", "failing weakCompareAndSet String value"); 697 } 698 699 // Compare set and get 700 { 701 hs.get(TestAccessMode.SET).invokeExact(array, i, "foo"); 702 703 String o = (String) hs.get(TestAccessMode.GET_AND_SET).invokeExact(array, i, "bar"); 704 assertEquals(o, "foo", "getAndSet String"); 705 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); 706 assertEquals(x, "bar", "getAndSet String value"); 707 } 708 709 { 710 hs.get(TestAccessMode.SET).invokeExact(array, i, "foo"); 711 712 String o = (String) hs.get(TestAccessMode.GET_AND_SET_ACQUIRE).invokeExact(array, i, "bar"); 713 assertEquals(o, "foo", "getAndSetAcquire String"); 714 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); 715 assertEquals(x, "bar", "getAndSetAcquire String value"); 716 } 717 718 { 719 hs.get(TestAccessMode.SET).invokeExact(array, i, "foo"); 720 721 String o = (String) hs.get(TestAccessMode.GET_AND_SET_RELEASE).invokeExact(array, i, "bar"); 722 assertEquals(o, "foo", "getAndSetRelease String"); 723 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); 724 assertEquals(x, "bar", "getAndSetRelease String value"); 725 } 726 727 728 } 729 } 730 731 static void testArrayUnsupported(Handles hs) throws Throwable { 732 String[] array = new String[10]; 733 734 final int i = 0; 735 736 for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_ADD)) { 737 checkUOE(am, () -> { 738 String o = (String) hs.get(am).invokeExact(array, i, "foo"); 739 }); 740 } 741 742 for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_BITWISE)) { 743 checkUOE(am, () -> { 744 String o = (String) hs.get(am).invokeExact(array, i, "foo"); 745 }); 746 } 747 } 748 749 static void testArrayIndexOutOfBounds(Handles hs) throws Throwable { 750 String[] array = new String[10]; 751 752 for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) { 753 final int ci = i; 754 755 for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET)) { 756 checkAIOOBE(am, () -> { 757 String x = (String) hs.get(am).invokeExact(array, ci); 758 }); 759 } 760 761 for (TestAccessMode am : testAccessModesOfType(TestAccessType.SET)) { 762 checkAIOOBE(am, () -> { 763 hs.get(am).invokeExact(array, ci, "foo"); 764 }); 765 } 766 767 for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) { 768 checkAIOOBE(am, () -> { 769 boolean r = (boolean) hs.get(am).invokeExact(array, ci, "foo", "bar"); 770 }); 771 } 772 773 for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) { 774 checkAIOOBE(am, () -> { 775 String r = (String) hs.get(am).invokeExact(array, ci, "bar", "foo"); 776 }); 777 } 778 779 for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) { 780 checkAIOOBE(am, () -> { 781 String o = (String) hs.get(am).invokeExact(array, ci, "foo"); 782 }); 783 } 784 785 786 } 787 } 788 } 789