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