1 /*
   2  * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccessString
  27  */
  28 
  29 import org.testng.annotations.BeforeClass;
  30 import org.testng.annotations.DataProvider;
  31 import org.testng.annotations.Test;
  32 
  33 import java.lang.invoke.MethodHandles;
  34 import java.lang.invoke.VarHandle;
  35 import java.util.ArrayList;
  36 import java.util.Arrays;
  37 import java.util.List;
  38 
  39 import static org.testng.Assert.*;
  40 
  41 public class VarHandleTestMethodHandleAccessString extends VarHandleBaseTest {
  42     static final String static_final_v = "foo";
  43 
  44     static String static_v;
  45 
  46     final String final_v = "foo";
  47 
  48     String v;
  49 
  50     VarHandle vhFinalField;
  51 
  52     VarHandle vhField;
  53 
  54     VarHandle vhStaticField;
  55 
  56     VarHandle vhStaticFinalField;
  57 
  58     VarHandle vhArray;
  59 
  60     @BeforeClass
  61     public void setup() throws Exception {
  62         vhFinalField = MethodHandles.lookup().findVarHandle(
  63                 VarHandleTestMethodHandleAccessString.class, "final_v", String.class);
  64 
  65         vhField = MethodHandles.lookup().findVarHandle(
  66                 VarHandleTestMethodHandleAccessString.class, "v", String.class);
  67 
  68         vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
  69             VarHandleTestMethodHandleAccessString.class, "static_final_v", String.class);
  70 
  71         vhStaticField = MethodHandles.lookup().findStaticVarHandle(
  72             VarHandleTestMethodHandleAccessString.class, "static_v", String.class);
  73 
  74         vhArray = MethodHandles.arrayElementVarHandle(String[].class);
  75     }
  76 
  77 
  78     @DataProvider
  79     public Object[][] accessTestCaseProvider() throws Exception {
  80         List<AccessTestCase<?>> cases = new ArrayList<>();
  81 
  82         for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
  83             cases.add(new MethodHandleAccessTestCase("Instance field",
  84                                                      vhField, f, hs -> testInstanceField(this, hs)));
  85             cases.add(new MethodHandleAccessTestCase("Instance field unsupported",
  86                                                      vhField, f, hs -> testInstanceFieldUnsupported(this, hs),
  87                                                      false));
  88 
  89             cases.add(new MethodHandleAccessTestCase("Static field",
  90                                                      vhStaticField, f, VarHandleTestMethodHandleAccessString::testStaticField));
  91             cases.add(new MethodHandleAccessTestCase("Static field unsupported",
  92                                                      vhStaticField, f, VarHandleTestMethodHandleAccessString::testStaticFieldUnsupported,
  93                                                      false));
  94 
  95             cases.add(new MethodHandleAccessTestCase("Array",
  96                                                      vhArray, f, VarHandleTestMethodHandleAccessString::testArray));
  97             cases.add(new MethodHandleAccessTestCase("Array unsupported",
  98                                                      vhArray, f, VarHandleTestMethodHandleAccessString::testArrayUnsupported,
  99                                                      false));
 100             cases.add(new MethodHandleAccessTestCase("Array index out of bounds",
 101                                                      vhArray, f, VarHandleTestMethodHandleAccessString::testArrayIndexOutOfBounds,
 102                                                      false));
 103         }
 104 
 105         // Work around issue with jtreg summary reporting which truncates
 106         // the String result of Object.toString to 30 characters, hence
 107         // the first dummy argument
 108         return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
 109     }
 110 
 111     @Test(dataProvider = "accessTestCaseProvider")
 112     public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
 113         T t = atc.get();
 114         int iters = atc.requiresLoop() ? ITERS : 1;
 115         for (int c = 0; c < iters; c++) {
 116             atc.testAccess(t);
 117         }
 118     }
 119 
 120 
 121     static void testInstanceField(VarHandleTestMethodHandleAccessString recv, Handles hs) throws Throwable {
 122         // Plain
 123         {
 124             hs.get(TestAccessMode.SET).invokeExact(recv, "foo");
 125             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
 126             assertEquals(x, "foo", "set String value");
 127         }
 128 
 129 
 130         // Volatile
 131         {
 132             hs.get(TestAccessMode.SET_VOLATILE).invokeExact(recv, "bar");
 133             String x = (String) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(recv);
 134             assertEquals(x, "bar", "setVolatile String value");
 135         }
 136 
 137         // Lazy
 138         {
 139             hs.get(TestAccessMode.SET_RELEASE).invokeExact(recv, "foo");
 140             String x = (String) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(recv);
 141             assertEquals(x, "foo", "setRelease String value");
 142         }
 143 
 144         // Opaque
 145         {
 146             hs.get(TestAccessMode.SET_OPAQUE).invokeExact(recv, "bar");
 147             String x = (String) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(recv);
 148             assertEquals(x, "bar", "setOpaque String value");
 149         }
 150 
 151         hs.get(TestAccessMode.SET).invokeExact(recv, "foo");
 152 
 153         // Compare
 154         {
 155             boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(recv, "foo", "bar");
 156             assertEquals(r, true, "success compareAndSet String");
 157             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
 158             assertEquals(x, "bar", "success compareAndSet String value");
 159         }
 160 
 161         {
 162             boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(recv, "foo", "baz");
 163             assertEquals(r, false, "failing compareAndSet String");
 164             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
 165             assertEquals(x, "bar", "failing compareAndSet String value");
 166         }
 167 
 168         {
 169             String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_VOLATILE).invokeExact(recv, "bar", "foo");
 170             assertEquals(r, "bar", "success compareAndExchangeVolatile String");
 171             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
 172             assertEquals(x, "foo", "success compareAndExchangeVolatile String value");
 173         }
 174 
 175         {
 176             String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_VOLATILE).invokeExact(recv, "bar", "baz");
 177             assertEquals(r, "foo", "failing compareAndExchangeVolatile String");
 178             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
 179             assertEquals(x, "foo", "failing compareAndExchangeVolatile String value");
 180         }
 181 
 182         {
 183             String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(recv, "foo", "bar");
 184             assertEquals(r, "foo", "success compareAndExchangeAcquire String");
 185             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
 186             assertEquals(x, "bar", "success compareAndExchangeAcquire String value");
 187         }
 188 
 189         {
 190             String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(recv, "foo", "baz");
 191             assertEquals(r, "bar", "failing compareAndExchangeAcquire String");
 192             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
 193             assertEquals(x, "bar", "failing compareAndExchangeAcquire String value");
 194         }
 195 
 196         {
 197             String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(recv, "bar", "foo");
 198             assertEquals(r, "bar", "success compareAndExchangeRelease String");
 199             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
 200             assertEquals(x, "foo", "success compareAndExchangeRelease String value");
 201         }
 202 
 203         {
 204             String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(recv, "bar", "baz");
 205             assertEquals(r, "foo", "failing compareAndExchangeRelease String");
 206             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
 207             assertEquals(x, "foo", "failing compareAndExchangeRelease String value");
 208         }
 209 
 210         {
 211             boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, "foo", "bar");
 212             assertEquals(r, true, "weakCompareAndSet String");
 213             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
 214             assertEquals(x, "bar", "weakCompareAndSet String value");
 215         }
 216 
 217         {
 218             boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, "bar", "foo");
 219             assertEquals(r, true, "weakCompareAndSetAcquire String");
 220             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
 221             assertEquals(x, "foo", "weakCompareAndSetAcquire String");
 222         }
 223 
 224         {
 225             boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, "foo", "bar");
 226             assertEquals(r, true, "weakCompareAndSetRelease String");
 227             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
 228             assertEquals(x, "bar", "weakCompareAndSetRelease String");
 229         }
 230 
 231         // Compare set and get
 232         {
 233             String o = (String) hs.get(TestAccessMode.GET_AND_SET).invokeExact(recv, "foo");
 234             assertEquals(o, "bar", "getAndSet String");
 235             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
 236             assertEquals(x, "foo", "getAndSet String value");
 237         }
 238 
 239     }
 240 
 241     static void testInstanceFieldUnsupported(VarHandleTestMethodHandleAccessString recv, Handles hs) throws Throwable {
 242 
 243         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_ADD)) {
 244             checkUOE(am, () -> {
 245                 String r = (String) hs.get(am).invokeExact(recv, "foo");
 246             });
 247         }
 248     }
 249 
 250 
 251     static void testStaticField(Handles hs) throws Throwable {
 252         // Plain
 253         {
 254             hs.get(TestAccessMode.SET).invokeExact("foo");
 255             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
 256             assertEquals(x, "foo", "set String value");
 257         }
 258 
 259 
 260         // Volatile
 261         {
 262             hs.get(TestAccessMode.SET_VOLATILE).invokeExact("bar");
 263             String x = (String) hs.get(TestAccessMode.GET_VOLATILE).invokeExact();
 264             assertEquals(x, "bar", "setVolatile String value");
 265         }
 266 
 267         // Lazy
 268         {
 269             hs.get(TestAccessMode.SET_RELEASE).invokeExact("foo");
 270             String x = (String) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact();
 271             assertEquals(x, "foo", "setRelease String value");
 272         }
 273 
 274         // Opaque
 275         {
 276             hs.get(TestAccessMode.SET_OPAQUE).invokeExact("bar");
 277             String x = (String) hs.get(TestAccessMode.GET_OPAQUE).invokeExact();
 278             assertEquals(x, "bar", "setOpaque String value");
 279         }
 280 
 281         hs.get(TestAccessMode.SET).invokeExact("foo");
 282 
 283         // Compare
 284         {
 285             boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact("foo", "bar");
 286             assertEquals(r, true, "success compareAndSet String");
 287             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
 288             assertEquals(x, "bar", "success compareAndSet String value");
 289         }
 290 
 291         {
 292             boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact("foo", "baz");
 293             assertEquals(r, false, "failing compareAndSet String");
 294             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
 295             assertEquals(x, "bar", "failing compareAndSet String value");
 296         }
 297 
 298         {
 299             String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_VOLATILE).invokeExact("bar", "foo");
 300             assertEquals(r, "bar", "success compareAndExchangeVolatile String");
 301             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
 302             assertEquals(x, "foo", "success compareAndExchangeVolatile String value");
 303         }
 304 
 305         {
 306             String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_VOLATILE).invokeExact("bar", "baz");
 307             assertEquals(r, "foo", "failing compareAndExchangeVolatile String");
 308             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
 309             assertEquals(x, "foo", "failing compareAndExchangeVolatile String value");
 310         }
 311 
 312         {
 313             String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact("foo", "bar");
 314             assertEquals(r, "foo", "success compareAndExchangeAcquire String");
 315             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
 316             assertEquals(x, "bar", "success compareAndExchangeAcquire String value");
 317         }
 318 
 319         {
 320             String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact("foo", "baz");
 321             assertEquals(r, "bar", "failing compareAndExchangeAcquire String");
 322             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
 323             assertEquals(x, "bar", "failing compareAndExchangeAcquire String value");
 324         }
 325 
 326         {
 327             String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact("bar", "foo");
 328             assertEquals(r, "bar", "success compareAndExchangeRelease String");
 329             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
 330             assertEquals(x, "foo", "success compareAndExchangeRelease String value");
 331         }
 332 
 333         {
 334             String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact("bar", "baz");
 335             assertEquals(r, "foo", "failing compareAndExchangeRelease String");
 336             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
 337             assertEquals(x, "foo", "failing compareAndExchangeRelease String value");
 338         }
 339 
 340         {
 341             boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact("foo", "bar");
 342             assertEquals(r, true, "weakCompareAndSet String");
 343             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
 344             assertEquals(x, "bar", "weakCompareAndSet String value");
 345         }
 346 
 347         {
 348             boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact("bar", "foo");
 349             assertEquals(r, true, "weakCompareAndSetAcquire String");
 350             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
 351             assertEquals(x, "foo", "weakCompareAndSetAcquire String");
 352         }
 353 
 354         {
 355             boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact( "foo", "bar");
 356             assertEquals(r, true, "weakCompareAndSetRelease String");
 357             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
 358             assertEquals(x, "bar", "weakCompareAndSetRelease String");
 359         }
 360 
 361         // Compare set and get
 362         {
 363             String o = (String) hs.get(TestAccessMode.GET_AND_SET).invokeExact( "foo");
 364             assertEquals(o, "bar", "getAndSet String");
 365             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
 366             assertEquals(x, "foo", "getAndSet String value");
 367         }
 368 
 369     }
 370 
 371     static void testStaticFieldUnsupported(Handles hs) throws Throwable {
 372 
 373         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_ADD)) {
 374             checkUOE(am, () -> {
 375                 String r = (String) hs.get(am).invokeExact("foo");
 376             });
 377         }
 378     }
 379 
 380 
 381     static void testArray(Handles hs) throws Throwable {
 382         String[] array = new String[10];
 383 
 384         for (int i = 0; i < array.length; i++) {
 385             // Plain
 386             {
 387                 hs.get(TestAccessMode.SET).invokeExact(array, i, "foo");
 388                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
 389                 assertEquals(x, "foo", "get String value");
 390             }
 391 
 392 
 393             // Volatile
 394             {
 395                 hs.get(TestAccessMode.SET_VOLATILE).invokeExact(array, i, "bar");
 396                 String x = (String) hs.get(TestAccessMode.GET_VOLATILE).invokeExact(array, i);
 397                 assertEquals(x, "bar", "setVolatile String value");
 398             }
 399 
 400             // Lazy
 401             {
 402                 hs.get(TestAccessMode.SET_RELEASE).invokeExact(array, i, "foo");
 403                 String x = (String) hs.get(TestAccessMode.GET_ACQUIRE).invokeExact(array, i);
 404                 assertEquals(x, "foo", "setRelease String value");
 405             }
 406 
 407             // Opaque
 408             {
 409                 hs.get(TestAccessMode.SET_OPAQUE).invokeExact(array, i, "bar");
 410                 String x = (String) hs.get(TestAccessMode.GET_OPAQUE).invokeExact(array, i);
 411                 assertEquals(x, "bar", "setOpaque String value");
 412             }
 413 
 414             hs.get(TestAccessMode.SET).invokeExact(array, i, "foo");
 415 
 416             // Compare
 417             {
 418                 boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(array, i, "foo", "bar");
 419                 assertEquals(r, true, "success compareAndSet String");
 420                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
 421                 assertEquals(x, "bar", "success compareAndSet String value");
 422             }
 423 
 424             {
 425                 boolean r = (boolean) hs.get(TestAccessMode.COMPARE_AND_SET).invokeExact(array, i, "foo", "baz");
 426                 assertEquals(r, false, "failing compareAndSet String");
 427                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
 428                 assertEquals(x, "bar", "failing compareAndSet String value");
 429             }
 430 
 431             {
 432                 String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_VOLATILE).invokeExact(array, i, "bar", "foo");
 433                 assertEquals(r, "bar", "success compareAndExchangeVolatile String");
 434                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
 435                 assertEquals(x, "foo", "success compareAndExchangeVolatile String value");
 436             }
 437 
 438             {
 439                 String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_VOLATILE).invokeExact(array, i, "bar", "baz");
 440                 assertEquals(r, "foo", "failing compareAndExchangeVolatile String");
 441                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
 442                 assertEquals(x, "foo", "failing compareAndExchangeVolatile String value");
 443             }
 444 
 445             {
 446                 String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(array, i, "foo", "bar");
 447                 assertEquals(r, "foo", "success compareAndExchangeAcquire String");
 448                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
 449                 assertEquals(x, "bar", "success compareAndExchangeAcquire String value");
 450             }
 451 
 452             {
 453                 String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_ACQUIRE).invokeExact(array, i, "foo", "baz");
 454                 assertEquals(r, "bar", "failing compareAndExchangeAcquire String");
 455                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
 456                 assertEquals(x, "bar", "failing compareAndExchangeAcquire String value");
 457             }
 458 
 459             {
 460                 String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(array, i, "bar", "foo");
 461                 assertEquals(r, "bar", "success compareAndExchangeRelease String");
 462                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
 463                 assertEquals(x, "foo", "success compareAndExchangeRelease String value");
 464             }
 465 
 466             {
 467                 String r = (String) hs.get(TestAccessMode.COMPARE_AND_EXCHANGE_RELEASE).invokeExact(array, i, "bar", "baz");
 468                 assertEquals(r, "foo", "failing compareAndExchangeRelease String");
 469                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
 470                 assertEquals(x, "foo", "failing compareAndExchangeRelease String value");
 471             }
 472 
 473             {
 474                 boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, "foo", "bar");
 475                 assertEquals(r, true, "weakCompareAndSet String");
 476                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
 477                 assertEquals(x, "bar", "weakCompareAndSet String value");
 478             }
 479 
 480             {
 481                 boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, "bar", "foo");
 482                 assertEquals(r, true, "weakCompareAndSetAcquire String");
 483                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
 484                 assertEquals(x, "foo", "weakCompareAndSetAcquire String");
 485             }
 486 
 487             {
 488                 boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(array, i, "foo", "bar");
 489                 assertEquals(r, true, "weakCompareAndSetRelease String");
 490                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
 491                 assertEquals(x, "bar", "weakCompareAndSetRelease String");
 492             }
 493 
 494             // Compare set and get
 495             {
 496                 String o = (String) hs.get(TestAccessMode.GET_AND_SET).invokeExact(array, i, "foo");
 497                 assertEquals(o, "bar", "getAndSet String");
 498                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
 499                 assertEquals(x, "foo", "getAndSet String value");
 500             }
 501 
 502         }
 503     }
 504 
 505     static void testArrayUnsupported(Handles hs) throws Throwable {
 506         String[] array = new String[10];
 507 
 508         final int i = 0;
 509 
 510         for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_ADD)) {
 511             checkUOE(am, () -> {
 512                 String o = (String) hs.get(am).invokeExact(array, i, "foo");
 513             });
 514         }
 515     }
 516 
 517     static void testArrayIndexOutOfBounds(Handles hs) throws Throwable {
 518         String[] array = new String[10];
 519 
 520         for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
 521             final int ci = i;
 522 
 523             for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET)) {
 524                 checkIOOBE(am, () -> {
 525                     String x = (String) hs.get(am).invokeExact(array, ci);
 526                 });
 527             }
 528 
 529             for (TestAccessMode am : testAccessModesOfType(TestAccessType.SET)) {
 530                 checkIOOBE(am, () -> {
 531                     hs.get(am).invokeExact(array, ci, "foo");
 532                 });
 533             }
 534 
 535             for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) {
 536                 checkIOOBE(am, () -> {
 537                     boolean r = (boolean) hs.get(am).invokeExact(array, ci, "foo", "bar");
 538                 });
 539             }
 540 
 541             for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) {
 542                 checkIOOBE(am, () -> {
 543                     String r = (String) hs.get(am).invokeExact(array, ci, "bar", "foo");
 544                 });
 545             }
 546 
 547             for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) {
 548                 checkIOOBE(am, () -> {
 549                     String o = (String) hs.get(am).invokeExact(array, ci, "foo");
 550                 });
 551             }
 552 
 553         }
 554     }
 555 }
 556