1 /*
   2  * Copyright (c) 2015, 2018, 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  * @compile -XDallowWithFieldOperator Value.java
  27  * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccessString
  28  */
  29 
  30 import org.testng.annotations.BeforeClass;
  31 import org.testng.annotations.DataProvider;
  32 import org.testng.annotations.Test;
  33 
  34 import java.lang.invoke.MethodHandles;
  35 import java.lang.invoke.VarHandle;
  36 import java.util.ArrayList;
  37 import java.util.Arrays;
  38 import java.util.List;
  39 
  40 import static org.testng.Assert.*;
  41 
  42 public class VarHandleTestMethodHandleAccessString extends VarHandleBaseTest {
  43     static final String static_final_v = "foo";
  44 
  45     static String static_v;
  46 
  47     final String final_v = "foo";
  48 
  49     String v;
  50 
  51     VarHandle vhFinalField;
  52 
  53     VarHandle vhField;
  54 
  55     VarHandle vhStaticField;
  56 
  57     VarHandle vhStaticFinalField;
  58 
  59     VarHandle vhArray;
  60 
  61 
  62     @BeforeClass
  63     public void setup() throws Exception {
  64         vhFinalField = MethodHandles.lookup().findVarHandle(
  65                 VarHandleTestMethodHandleAccessString.class, "final_v", String.class);
  66 
  67         vhField = MethodHandles.lookup().findVarHandle(
  68                 VarHandleTestMethodHandleAccessString.class, "v", String.class);
  69 
  70         vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
  71             VarHandleTestMethodHandleAccessString.class, "static_final_v", String.class);
  72 
  73         vhStaticField = MethodHandles.lookup().findStaticVarHandle(
  74             VarHandleTestMethodHandleAccessString.class, "static_v", String.class);
  75 
  76         vhArray = MethodHandles.arrayElementVarHandle(String[].class);
  77 
  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             boolean success = false;
 215             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 216                 success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, "foo", "bar");
 217             }
 218             assertEquals(success, true, "weakCompareAndSetPlain String");
 219             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
 220             assertEquals(x, "bar", "weakCompareAndSetPlain String value");
 221         }
 222 
 223         {
 224             boolean success = false;
 225             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 226                 success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, "bar", "foo");
 227             }
 228             assertEquals(success, true, "weakCompareAndSetAcquire String");
 229             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
 230             assertEquals(x, "foo", "weakCompareAndSetAcquire String");
 231         }
 232 
 233         {
 234             boolean success = false;
 235             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 236                 success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, "foo", "bar");
 237             }
 238             assertEquals(success, true, "weakCompareAndSetRelease String");
 239             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
 240             assertEquals(x, "bar", "weakCompareAndSetRelease String");
 241         }
 242 
 243         {
 244             boolean success = false;
 245             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 246                 success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, "bar", "foo");
 247             }
 248             assertEquals(success, true, "weakCompareAndSet String");
 249             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
 250             assertEquals(x, "foo", "weakCompareAndSet String");
 251         }
 252 
 253         // Compare set and get
 254         {
 255             String o = (String) hs.get(TestAccessMode.GET_AND_SET).invokeExact(recv, "bar");
 256             assertEquals(o, "foo", "getAndSet String");
 257             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
 258             assertEquals(x, "bar", "getAndSet String value");
 259         }
 260 
 261 
 262     }
 263 
 264     static void testInstanceFieldUnsupported(VarHandleTestMethodHandleAccessString recv, Handles hs) throws Throwable {
 265 
 266         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_ADD)) {
 267             checkUOE(am, () -> {
 268                 String r = (String) hs.get(am).invokeExact(recv, "foo");
 269             });
 270         }
 271 
 272         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_BITWISE)) {
 273             checkUOE(am, () -> {
 274                 String r = (String) hs.get(am).invokeExact(recv, "foo");
 275             });
 276         }
 277     }
 278 
 279 
 280     static void testStaticField(Handles hs) throws Throwable {
 281         // Plain
 282         {
 283             hs.get(TestAccessMode.SET).invokeExact("foo");
 284             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
 285             assertEquals(x, "foo", "set String value");
 286         }
 287 
 288 
 289         // Volatile
 290         {
 291             hs.get(TestAccessMode.SET_VOLATILE).invokeExact("bar");
 292             String x = (String) hs.get(TestAccessMode.GET_VOLATILE).invokeExact();
 293             assertEquals(x, "bar", "setVolatile String value");
 294         }
 295 
 296         // Lazy
 297         {
 298             hs.get(TestAccessMode.SET_RELEASE).invokeExact("foo");
 299             String x = (String) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact();
 300             assertEquals(x, "foo", "setRelease String value");
 301         }
 302 
 303         // Opaque
 304         {
 305             hs.get(TestAccessMode.SET_OPAQUE).invokeExact("bar");
 306             String x = (String) hs.get(TestAccessMode.GET_OPAQUE).invokeExact();
 307             assertEquals(x, "bar", "setOpaque String value");
 308         }
 309 
 310         hs.get(TestAccessMode.SET).invokeExact("foo");
 311 
 312         // Compare
 313         {
 314             boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact("foo", "bar");
 315             assertEquals(r, true, "success compareAndSet String");
 316             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
 317             assertEquals(x, "bar", "success compareAndSet String value");
 318         }
 319 
 320         {
 321             boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact("foo", "baz");
 322             assertEquals(r, false, "failing compareAndSet String");
 323             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
 324             assertEquals(x, "bar", "failing compareAndSet String value");
 325         }
 326 
 327         {
 328             String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact("bar", "foo");
 329             assertEquals(r, "bar", "success compareAndExchange String");
 330             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
 331             assertEquals(x, "foo", "success compareAndExchange String value");
 332         }
 333 
 334         {
 335             String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact("bar", "baz");
 336             assertEquals(r, "foo", "failing compareAndExchange String");
 337             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
 338             assertEquals(x, "foo", "failing compareAndExchange String value");
 339         }
 340 
 341         {
 342             String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact("foo", "bar");
 343             assertEquals(r, "foo", "success compareAndExchangeAcquire String");
 344             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
 345             assertEquals(x, "bar", "success compareAndExchangeAcquire String value");
 346         }
 347 
 348         {
 349             String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact("foo", "baz");
 350             assertEquals(r, "bar", "failing compareAndExchangeAcquire String");
 351             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
 352             assertEquals(x, "bar", "failing compareAndExchangeAcquire String value");
 353         }
 354 
 355         {
 356             String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact("bar", "foo");
 357             assertEquals(r, "bar", "success compareAndExchangeRelease String");
 358             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
 359             assertEquals(x, "foo", "success compareAndExchangeRelease String value");
 360         }
 361 
 362         {
 363             String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact("bar", "baz");
 364             assertEquals(r, "foo", "failing compareAndExchangeRelease String");
 365             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
 366             assertEquals(x, "foo", "failing compareAndExchangeRelease String value");
 367         }
 368 
 369         {
 370             boolean success = false;
 371             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 372                 success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact("foo", "bar");
 373             }
 374             assertEquals(success, true, "weakCompareAndSetPlain String");
 375             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
 376             assertEquals(x, "bar", "weakCompareAndSetPlain String value");
 377         }
 378 
 379         {
 380             boolean success = false;
 381             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 382                 success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact("bar", "foo");
 383             }
 384             assertEquals(success, true, "weakCompareAndSetAcquire String");
 385             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
 386             assertEquals(x, "foo", "weakCompareAndSetAcquire String");
 387         }
 388 
 389         {
 390             boolean success = false;
 391             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 392                 success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact("foo", "bar");
 393             }
 394             assertEquals(success, true, "weakCompareAndSetRelease String");
 395             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
 396             assertEquals(x, "bar", "weakCompareAndSetRelease String");
 397         }
 398 
 399         {
 400             boolean success = false;
 401             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 402                 success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact("bar", "foo");
 403             }
 404             assertEquals(success, true, "weakCompareAndSet String");
 405             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
 406             assertEquals(x, "foo", "weakCompareAndSet String");
 407         }
 408 
 409         // Compare set and get
 410         {
 411             hs.get(TestAccessMode.SET).invokeExact("foo");
 412 
 413             String o = (String) hs.get(TestAccessMode.GET_AND_SET).invokeExact("bar");
 414             assertEquals(o, "foo", "getAndSet String");
 415             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
 416             assertEquals(x, "bar", "getAndSet String value");
 417         }
 418 
 419         // Compare set and get
 420         {
 421             hs.get(TestAccessMode.SET).invokeExact("foo");
 422 
 423             String o = (String) hs.get(TestAccessMode.GET_AND_SET_ACQUIRE).invokeExact("bar");
 424             assertEquals(o, "foo", "getAndSetAcquire String");
 425             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
 426             assertEquals(x, "bar", "getAndSetAcquire String value");
 427         }
 428 
 429         // Compare set and get
 430         {
 431             hs.get(TestAccessMode.SET).invokeExact("foo");
 432 
 433             String o = (String) hs.get(TestAccessMode.GET_AND_SET_RELEASE).invokeExact("bar");
 434             assertEquals(o, "foo", "getAndSetRelease String");
 435             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
 436             assertEquals(x, "bar", "getAndSetRelease String value");
 437         }
 438 
 439 
 440     }
 441 
 442     static void testStaticFieldUnsupported(Handles hs) throws Throwable {
 443 
 444         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_ADD)) {
 445             checkUOE(am, () -> {
 446                 String r = (String) hs.get(am).invokeExact("foo");
 447             });
 448         }
 449 
 450         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_BITWISE)) {
 451             checkUOE(am, () -> {
 452                 String r = (String) hs.get(am).invokeExact("foo");
 453             });
 454         }
 455     }
 456 
 457 
 458     static void testArray(Handles hs) throws Throwable {
 459         String[] array = new String[10];
 460 
 461         for (int i = 0; i < array.length; i++) {
 462             // Plain
 463             {
 464                 hs.get(TestAccessMode.SET).invokeExact(array, i, "foo");
 465                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
 466                 assertEquals(x, "foo", "get String value");
 467             }
 468 
 469 
 470             // Volatile
 471             {
 472                 hs.get(TestAccessMode.SET_VOLATILE).invokeExact(array, i, "bar");
 473                 String x = (String) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(array, i);
 474                 assertEquals(x, "bar", "setVolatile String value");
 475             }
 476 
 477             // Lazy
 478             {
 479                 hs.get(TestAccessMode.SET_RELEASE).invokeExact(array, i, "foo");
 480                 String x = (String) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(array, i);
 481                 assertEquals(x, "foo", "setRelease String value");
 482             }
 483 
 484             // Opaque
 485             {
 486                 hs.get(TestAccessMode.SET_OPAQUE).invokeExact(array, i, "bar");
 487                 String x = (String) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(array, i);
 488                 assertEquals(x, "bar", "setOpaque String value");
 489             }
 490 
 491             hs.get(TestAccessMode.SET).invokeExact(array, i, "foo");
 492 
 493             // Compare
 494             {
 495                 boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(array, i, "foo", "bar");
 496                 assertEquals(r, true, "success compareAndSet String");
 497                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
 498                 assertEquals(x, "bar", "success compareAndSet String value");
 499             }
 500 
 501             {
 502                 boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(array, i, "foo", "baz");
 503                 assertEquals(r, false, "failing compareAndSet String");
 504                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
 505                 assertEquals(x, "bar", "failing compareAndSet String value");
 506             }
 507 
 508             {
 509                 String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(array, i, "bar", "foo");
 510                 assertEquals(r, "bar", "success compareAndExchange String");
 511                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
 512                 assertEquals(x, "foo", "success compareAndExchange String value");
 513             }
 514 
 515             {
 516                 String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE).invokeExact(array, i, "bar", "baz");
 517                 assertEquals(r, "foo", "failing compareAndExchange String");
 518                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
 519                 assertEquals(x, "foo", "failing compareAndExchange String value");
 520             }
 521 
 522             {
 523                 String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(array, i, "foo", "bar");
 524                 assertEquals(r, "foo", "success compareAndExchangeAcquire String");
 525                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
 526                 assertEquals(x, "bar", "success compareAndExchangeAcquire String value");
 527             }
 528 
 529             {
 530                 String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(array, i, "foo", "baz");
 531                 assertEquals(r, "bar", "failing compareAndExchangeAcquire String");
 532                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
 533                 assertEquals(x, "bar", "failing compareAndExchangeAcquire String value");
 534             }
 535 
 536             {
 537                 String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(array, i, "bar", "foo");
 538                 assertEquals(r, "bar", "success compareAndExchangeRelease String");
 539                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
 540                 assertEquals(x, "foo", "success compareAndExchangeRelease String value");
 541             }
 542 
 543             {
 544                 String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(array, i, "bar", "baz");
 545                 assertEquals(r, "foo", "failing compareAndExchangeRelease String");
 546                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
 547                 assertEquals(x, "foo", "failing compareAndExchangeRelease String value");
 548             }
 549 
 550             {
 551                 boolean success = false;
 552                 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 553                     success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, "foo", "bar");
 554                 }
 555                 assertEquals(success, true, "weakCompareAndSetPlain String");
 556                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
 557                 assertEquals(x, "bar", "weakCompareAndSetPlain String value");
 558             }
 559 
 560             {
 561                 boolean success = false;
 562                 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 563                     success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, "bar", "foo");
 564                 }
 565                 assertEquals(success, true, "weakCompareAndSetAcquire String");
 566                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
 567                 assertEquals(x, "foo", "weakCompareAndSetAcquire String");
 568             }
 569 
 570             {
 571                 boolean success = false;
 572                 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 573                     success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(array, i, "foo", "bar");
 574                 }
 575                 assertEquals(success, true, "weakCompareAndSetRelease String");
 576                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
 577                 assertEquals(x, "bar", "weakCompareAndSetRelease String");
 578             }
 579 
 580             {
 581                 boolean success = false;
 582                 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 583                     success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, "bar", "foo");
 584                 }
 585                 assertEquals(success, true, "weakCompareAndSet String");
 586                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
 587                 assertEquals(x, "foo", "weakCompareAndSet String");
 588             }
 589 
 590             // Compare set and get
 591             {
 592                 hs.get(TestAccessMode.SET).invokeExact(array, i, "foo");
 593 
 594                 String o = (String) hs.get(TestAccessMode.GET_AND_SET).invokeExact(array, i, "bar");
 595                 assertEquals(o, "foo", "getAndSet String");
 596                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
 597                 assertEquals(x, "bar", "getAndSet String value");
 598             }
 599 
 600             {
 601                 hs.get(TestAccessMode.SET).invokeExact(array, i, "foo");
 602 
 603                 String o = (String) hs.get(TestAccessMode.GET_AND_SET_ACQUIRE).invokeExact(array, i, "bar");
 604                 assertEquals(o, "foo", "getAndSetAcquire String");
 605                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
 606                 assertEquals(x, "bar", "getAndSetAcquire String value");
 607             }
 608 
 609             {
 610                 hs.get(TestAccessMode.SET).invokeExact(array, i, "foo");
 611 
 612                 String o = (String) hs.get(TestAccessMode.GET_AND_SET_RELEASE).invokeExact(array, i, "bar");
 613                 assertEquals(o, "foo", "getAndSetRelease String");
 614                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
 615                 assertEquals(x, "bar", "getAndSetRelease String value");
 616             }
 617 
 618 
 619         }
 620     }
 621 
 622     static void testArrayUnsupported(Handles hs) throws Throwable {
 623         String[] array = new String[10];
 624 
 625         final int i = 0;
 626 
 627         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_ADD)) {
 628             checkUOE(am, () -> {
 629                 String o = (String) hs.get(am).invokeExact(array, i, "foo");
 630             });
 631         }
 632 
 633         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_BITWISE)) {
 634             checkUOE(am, () -> {
 635                 String o = (String) hs.get(am).invokeExact(array, i, "foo");
 636             });
 637         }
 638     }
 639 
 640     static void testArrayIndexOutOfBounds(Handles hs) throws Throwable {
 641         String[] array = new String[10];
 642 
 643         for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
 644             final int ci = i;
 645 
 646             for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET)) {
 647                 checkIOOBE(am, () -> {
 648                     String x = (String) hs.get(am).invokeExact(array, ci);
 649                 });
 650             }
 651 
 652             for (TestAccessMode am : testAccessModesOfType(TestAccessType.SET)) {
 653                 checkIOOBE(am, () -> {
 654                     hs.get(am).invokeExact(array, ci, "foo");
 655                 });
 656             }
 657 
 658             for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) {
 659                 checkIOOBE(am, () -> {
 660                     boolean r = (boolean) hs.get(am).invokeExact(array, ci, "foo", "bar");
 661                 });
 662             }
 663 
 664             for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) {
 665                 checkIOOBE(am, () -> {
 666                     String r = (String) hs.get(am).invokeExact(array, ci, "bar", "foo");
 667                 });
 668             }
 669 
 670             for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) {
 671                 checkIOOBE(am, () -> {
 672                     String o = (String) hs.get(am).invokeExact(array, ci, "foo");
 673                 });
 674             }
 675 
 676 
 677         }
 678     }
 679 }
 680