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     VarHandle vhArrayObject;
  64 
  65     @BeforeClass
  66     public void setup() throws Exception {
  67         vhFinalField = MethodHandles.lookup().findVarHandle(
  68                 VarHandleTestAccessString.class, "final_v", String.class);
  69 
  70         vhField = MethodHandles.lookup().findVarHandle(
  71                 VarHandleTestAccessString.class, "v", String.class);
  72 
  73         vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
  74             VarHandleTestAccessString.class, "static_final_v", String.class);
  75 
  76         vhStaticField = MethodHandles.lookup().findStaticVarHandle(
  77             VarHandleTestAccessString.class, "static_v", String.class);
  78 
  79         vhArray = MethodHandles.arrayElementVarHandle(String[].class);
  80         vhArrayObject = MethodHandles.arrayElementVarHandle(Object[].class);
  81     }
  82 
  83 
  84     @DataProvider
  85     public Object[][] varHandlesProvider() throws Exception {
  86         List<VarHandle> vhs = new ArrayList<>();
  87         vhs.add(vhField);
  88         vhs.add(vhStaticField);
  89         vhs.add(vhArray);
  90 
  91         return vhs.stream().map(tc -> new Object[]{tc}).toArray(Object[][]::new);
  92     }
  93 
  94     @Test(dataProvider = "varHandlesProvider")
  95     public void testIsAccessModeSupported(VarHandle vh) {
  96         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET));
  97         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET));
  98         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_VOLATILE));
  99         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_VOLATILE));
 100         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_ACQUIRE));
 101         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_RELEASE));
 102         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_OPAQUE));
 103         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_OPAQUE));
 104 
 105         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_SET));
 106         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE));
 107         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
 108         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
 109         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_PLAIN));
 110         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
 111         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
 112         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
 113         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
 114         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET_ACQUIRE));
 115         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET_RELEASE));
 116 
 117         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
 118         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD_ACQUIRE));
 119         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD_RELEASE));
 120 
 121         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR));
 122         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR_ACQUIRE));
 123         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR_RELEASE));
 124         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND));
 125         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND_ACQUIRE));
 126         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND_RELEASE));
 127         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR));
 128         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_ACQUIRE));
 129         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_RELEASE));
 130     }
 131 
 132 
 133     @DataProvider
 134     public Object[][] typesProvider() throws Exception {
 135         List<Object[]> types = new ArrayList<>();
 136         types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccessString.class)});
 137         types.add(new Object[] {vhStaticField, Arrays.asList()});
 138         types.add(new Object[] {vhArray, Arrays.asList(String[].class, int.class)});
 139 
 140         return types.stream().toArray(Object[][]::new);
 141     }
 142 
 143     @Test(dataProvider = "typesProvider")
 144     public void testTypes(VarHandle vh, List<Class<?>> pts) {
 145         assertEquals(vh.varType(), String.class);
 146 
 147         assertEquals(vh.coordinateTypes(), pts);
 148 
 149         testTypes(vh);
 150     }
 151 
 152 
 153     @Test
 154     public void testLookupInstanceToStatic() {
 155         checkIAE("Lookup of static final field to instance final field", () -> {
 156             MethodHandles.lookup().findStaticVarHandle(
 157                     VarHandleTestAccessString.class, "final_v", String.class);
 158         });
 159 
 160         checkIAE("Lookup of static field to instance field", () -> {
 161             MethodHandles.lookup().findStaticVarHandle(
 162                     VarHandleTestAccessString.class, "v", String.class);
 163         });
 164     }
 165 
 166     @Test
 167     public void testLookupStaticToInstance() {
 168         checkIAE("Lookup of instance final field to static final field", () -> {
 169             MethodHandles.lookup().findVarHandle(
 170                 VarHandleTestAccessString.class, "static_final_v", String.class);
 171         });
 172 
 173         checkIAE("Lookup of instance field to static field", () -> {
 174             vhStaticField = MethodHandles.lookup().findVarHandle(
 175                 VarHandleTestAccessString.class, "static_v", String.class);
 176         });
 177     }
 178 
 179 
 180     @DataProvider
 181     public Object[][] accessTestCaseProvider() throws Exception {
 182         List<AccessTestCase<?>> cases = new ArrayList<>();
 183 
 184         cases.add(new VarHandleAccessTestCase("Instance final field",
 185                                               vhFinalField, vh -> testInstanceFinalField(this, vh)));
 186         cases.add(new VarHandleAccessTestCase("Instance final field unsupported",
 187                                               vhFinalField, vh -> testInstanceFinalFieldUnsupported(this, vh),
 188                                               false));
 189 
 190         cases.add(new VarHandleAccessTestCase("Static final field",
 191                                               vhStaticFinalField, VarHandleTestAccessString::testStaticFinalField));
 192         cases.add(new VarHandleAccessTestCase("Static final field unsupported",
 193                                               vhStaticFinalField, VarHandleTestAccessString::testStaticFinalFieldUnsupported,
 194                                               false));
 195 
 196         cases.add(new VarHandleAccessTestCase("Instance field",
 197                                               vhField, vh -> testInstanceField(this, vh)));
 198         cases.add(new VarHandleAccessTestCase("Instance field unsupported",
 199                                               vhField, vh -> testInstanceFieldUnsupported(this, vh),
 200                                               false));
 201 
 202         cases.add(new VarHandleAccessTestCase("Static field",
 203                                               vhStaticField, VarHandleTestAccessString::testStaticField));
 204         cases.add(new VarHandleAccessTestCase("Static field unsupported",
 205                                               vhStaticField, VarHandleTestAccessString::testStaticFieldUnsupported,
 206                                               false));
 207 
 208         cases.add(new VarHandleAccessTestCase("Array",
 209                                               vhArray, VarHandleTestAccessString::testArray));
 210         cases.add(new VarHandleAccessTestCase("Array Object[]",
 211                                               vhArrayObject, VarHandleTestAccessString::testArray));
 212         cases.add(new VarHandleAccessTestCase("Array unsupported",
 213                                               vhArray, VarHandleTestAccessString::testArrayUnsupported,
 214                                               false));
 215         cases.add(new VarHandleAccessTestCase("Array index out of bounds",
 216                                               vhArray, VarHandleTestAccessString::testArrayIndexOutOfBounds,
 217                                               false));
 218         cases.add(new VarHandleAccessTestCase("Array store exception",
 219                                               vhArrayObject, VarHandleTestAccessString::testArrayStoreException,
 220                                               false));
 221         // Work around issue with jtreg summary reporting which truncates
 222         // the String result of Object.toString to 30 characters, hence
 223         // the first dummy argument
 224         return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
 225     }
 226 
 227     @Test(dataProvider = "accessTestCaseProvider")
 228     public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
 229         T t = atc.get();
 230         int iters = atc.requiresLoop() ? ITERS : 1;
 231         for (int c = 0; c < iters; c++) {
 232             atc.testAccess(t);
 233         }
 234     }
 235 
 236 
 237 
 238 
 239     static void testInstanceFinalField(VarHandleTestAccessString recv, VarHandle vh) {
 240         // Plain
 241         {
 242             String x = (String) vh.get(recv);
 243             assertEquals(x, "foo", "get String value");
 244         }
 245 
 246 
 247         // Volatile
 248         {
 249             String x = (String) vh.getVolatile(recv);
 250             assertEquals(x, "foo", "getVolatile String value");
 251         }
 252 
 253         // Lazy
 254         {
 255             String x = (String) vh.getAcquire(recv);
 256             assertEquals(x, "foo", "getRelease String value");
 257         }
 258 
 259         // Opaque
 260         {
 261             String x = (String) vh.getOpaque(recv);
 262             assertEquals(x, "foo", "getOpaque String value");
 263         }
 264     }
 265 
 266     static void testInstanceFinalFieldUnsupported(VarHandleTestAccessString recv, VarHandle vh) {
 267         checkUOE(() -> {
 268             vh.set(recv, "bar");
 269         });
 270 
 271         checkUOE(() -> {
 272             vh.setVolatile(recv, "bar");
 273         });
 274 
 275         checkUOE(() -> {
 276             vh.setRelease(recv, "bar");
 277         });
 278 
 279         checkUOE(() -> {
 280             vh.setOpaque(recv, "bar");
 281         });
 282 
 283 
 284         checkUOE(() -> {
 285             String o = (String) vh.getAndAdd(recv, "foo");
 286         });
 287 
 288         checkUOE(() -> {
 289             String o = (String) vh.getAndAddAcquire(recv, "foo");
 290         });
 291 
 292         checkUOE(() -> {
 293             String o = (String) vh.getAndAddRelease(recv, "foo");
 294         });
 295 
 296         checkUOE(() -> {
 297             String o = (String) vh.getAndBitwiseOr(recv, "foo");
 298         });
 299 
 300         checkUOE(() -> {
 301             String o = (String) vh.getAndBitwiseOrAcquire(recv, "foo");
 302         });
 303 
 304         checkUOE(() -> {
 305             String o = (String) vh.getAndBitwiseOrRelease(recv, "foo");
 306         });
 307 
 308         checkUOE(() -> {
 309             String o = (String) vh.getAndBitwiseAnd(recv, "foo");
 310         });
 311 
 312         checkUOE(() -> {
 313             String o = (String) vh.getAndBitwiseAndAcquire(recv, "foo");
 314         });
 315 
 316         checkUOE(() -> {
 317             String o = (String) vh.getAndBitwiseAndRelease(recv, "foo");
 318         });
 319 
 320         checkUOE(() -> {
 321             String o = (String) vh.getAndBitwiseXor(recv, "foo");
 322         });
 323 
 324         checkUOE(() -> {
 325             String o = (String) vh.getAndBitwiseXorAcquire(recv, "foo");
 326         });
 327 
 328         checkUOE(() -> {
 329             String o = (String) vh.getAndBitwiseXorRelease(recv, "foo");
 330         });
 331     }
 332 
 333 
 334     static void testStaticFinalField(VarHandle vh) {
 335         // Plain
 336         {
 337             String x = (String) vh.get();
 338             assertEquals(x, "foo", "get String value");
 339         }
 340 
 341 
 342         // Volatile
 343         {
 344             String x = (String) vh.getVolatile();
 345             assertEquals(x, "foo", "getVolatile String value");
 346         }
 347 
 348         // Lazy
 349         {
 350             String x = (String) vh.getAcquire();
 351             assertEquals(x, "foo", "getRelease String value");
 352         }
 353 
 354         // Opaque
 355         {
 356             String x = (String) vh.getOpaque();
 357             assertEquals(x, "foo", "getOpaque String value");
 358         }
 359     }
 360 
 361     static void testStaticFinalFieldUnsupported(VarHandle vh) {
 362         checkUOE(() -> {
 363             vh.set("bar");
 364         });
 365 
 366         checkUOE(() -> {
 367             vh.setVolatile("bar");
 368         });
 369 
 370         checkUOE(() -> {
 371             vh.setRelease("bar");
 372         });
 373 
 374         checkUOE(() -> {
 375             vh.setOpaque("bar");
 376         });
 377 
 378 
 379         checkUOE(() -> {
 380             String o = (String) vh.getAndAdd("foo");
 381         });
 382 
 383         checkUOE(() -> {
 384             String o = (String) vh.getAndAddAcquire("foo");
 385         });
 386 
 387         checkUOE(() -> {
 388             String o = (String) vh.getAndAddRelease("foo");
 389         });
 390 
 391         checkUOE(() -> {
 392             String o = (String) vh.getAndBitwiseOr("foo");
 393         });
 394 
 395         checkUOE(() -> {
 396             String o = (String) vh.getAndBitwiseOrAcquire("foo");
 397         });
 398 
 399         checkUOE(() -> {
 400             String o = (String) vh.getAndBitwiseOrRelease("foo");
 401         });
 402 
 403         checkUOE(() -> {
 404             String o = (String) vh.getAndBitwiseAnd("foo");
 405         });
 406 
 407         checkUOE(() -> {
 408             String o = (String) vh.getAndBitwiseAndAcquire("foo");
 409         });
 410 
 411         checkUOE(() -> {
 412             String o = (String) vh.getAndBitwiseAndRelease("foo");
 413         });
 414 
 415         checkUOE(() -> {
 416             String o = (String) vh.getAndBitwiseXor("foo");
 417         });
 418 
 419         checkUOE(() -> {
 420             String o = (String) vh.getAndBitwiseXorAcquire("foo");
 421         });
 422 
 423         checkUOE(() -> {
 424             String o = (String) vh.getAndBitwiseXorRelease("foo");
 425         });
 426     }
 427 
 428 
 429     static void testInstanceField(VarHandleTestAccessString recv, VarHandle vh) {
 430         // Plain
 431         {
 432             vh.set(recv, "foo");
 433             String x = (String) vh.get(recv);
 434             assertEquals(x, "foo", "set String value");
 435         }
 436 
 437 
 438         // Volatile
 439         {
 440             vh.setVolatile(recv, "bar");
 441             String x = (String) vh.getVolatile(recv);
 442             assertEquals(x, "bar", "setVolatile String value");
 443         }
 444 
 445         // Lazy
 446         {
 447             vh.setRelease(recv, "foo");
 448             String x = (String) vh.getAcquire(recv);
 449             assertEquals(x, "foo", "setRelease String value");
 450         }
 451 
 452         // Opaque
 453         {
 454             vh.setOpaque(recv, "bar");
 455             String x = (String) vh.getOpaque(recv);
 456             assertEquals(x, "bar", "setOpaque String value");
 457         }
 458 
 459         vh.set(recv, "foo");
 460 
 461         // Compare
 462         {
 463             boolean r = vh.compareAndSet(recv, "foo", "bar");
 464             assertEquals(r, true, "success compareAndSet String");
 465             String x = (String) vh.get(recv);
 466             assertEquals(x, "bar", "success compareAndSet String value");
 467         }
 468 
 469         {
 470             boolean r = vh.compareAndSet(recv, "foo", "baz");
 471             assertEquals(r, false, "failing compareAndSet String");
 472             String x = (String) vh.get(recv);
 473             assertEquals(x, "bar", "failing compareAndSet String value");
 474         }
 475 
 476         {
 477             String r = (String) vh.compareAndExchange(recv, "bar", "foo");
 478             assertEquals(r, "bar", "success compareAndExchange String");
 479             String x = (String) vh.get(recv);
 480             assertEquals(x, "foo", "success compareAndExchange String value");
 481         }
 482 
 483         {
 484             String r = (String) vh.compareAndExchange(recv, "bar", "baz");
 485             assertEquals(r, "foo", "failing compareAndExchange String");
 486             String x = (String) vh.get(recv);
 487             assertEquals(x, "foo", "failing compareAndExchange String value");
 488         }
 489 
 490         {
 491             String r = (String) vh.compareAndExchangeAcquire(recv, "foo", "bar");
 492             assertEquals(r, "foo", "success compareAndExchangeAcquire String");
 493             String x = (String) vh.get(recv);
 494             assertEquals(x, "bar", "success compareAndExchangeAcquire String value");
 495         }
 496 
 497         {
 498             String r = (String) vh.compareAndExchangeAcquire(recv, "foo", "baz");
 499             assertEquals(r, "bar", "failing compareAndExchangeAcquire String");
 500             String x = (String) vh.get(recv);
 501             assertEquals(x, "bar", "failing compareAndExchangeAcquire String value");
 502         }
 503 
 504         {
 505             String r = (String) vh.compareAndExchangeRelease(recv, "bar", "foo");
 506             assertEquals(r, "bar", "success compareAndExchangeRelease String");
 507             String x = (String) vh.get(recv);
 508             assertEquals(x, "foo", "success compareAndExchangeRelease String value");
 509         }
 510 
 511         {
 512             String r = (String) vh.compareAndExchangeRelease(recv, "bar", "baz");
 513             assertEquals(r, "foo", "failing compareAndExchangeRelease String");
 514             String x = (String) vh.get(recv);
 515             assertEquals(x, "foo", "failing compareAndExchangeRelease String value");
 516         }
 517 
 518         {
 519             boolean success = false;
 520             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 521                 success = vh.weakCompareAndSetPlain(recv, "foo", "bar");
 522             }
 523             assertEquals(success, true, "weakCompareAndSetPlain String");
 524             String x = (String) vh.get(recv);
 525             assertEquals(x, "bar", "weakCompareAndSetPlain String value");
 526         }
 527 
 528         {
 529             boolean success = false;
 530             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 531                 success = vh.weakCompareAndSetAcquire(recv, "bar", "foo");
 532             }
 533             assertEquals(success, true, "weakCompareAndSetAcquire String");
 534             String x = (String) vh.get(recv);
 535             assertEquals(x, "foo", "weakCompareAndSetAcquire String");
 536         }
 537 
 538         {
 539             boolean success = false;
 540             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 541                 success = vh.weakCompareAndSetRelease(recv, "foo", "bar");
 542             }
 543             assertEquals(success, true, "weakCompareAndSetRelease String");
 544             String x = (String) vh.get(recv);
 545             assertEquals(x, "bar", "weakCompareAndSetRelease String");
 546         }
 547 
 548         {
 549             boolean success = false;
 550             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 551                 success = vh.weakCompareAndSet(recv, "bar", "foo");
 552             }
 553             assertEquals(success, true, "weakCompareAndSet String");
 554             String x = (String) vh.get(recv);
 555             assertEquals(x, "foo", "weakCompareAndSet String value");
 556         }
 557 
 558         // Compare set and get
 559         {
 560             vh.set(recv, "foo");
 561 
 562             String o = (String) vh.getAndSet(recv, "bar");
 563             assertEquals(o, "foo", "getAndSet String");
 564             String x = (String) vh.get(recv);
 565             assertEquals(x, "bar", "getAndSet String value");
 566         }
 567 
 568         {
 569             vh.set(recv, "foo");
 570 
 571             String o = (String) vh.getAndSetAcquire(recv, "bar");
 572             assertEquals(o, "foo", "getAndSetAcquire String");
 573             String x = (String) vh.get(recv);
 574             assertEquals(x, "bar", "getAndSetAcquire String value");
 575         }
 576 
 577         {
 578             vh.set(recv, "foo");
 579 
 580             String o = (String) vh.getAndSetRelease(recv, "bar");
 581             assertEquals(o, "foo", "getAndSetRelease String");
 582             String x = (String) vh.get(recv);
 583             assertEquals(x, "bar", "getAndSetRelease String value");
 584         }
 585 
 586 
 587     }
 588 
 589     static void testInstanceFieldUnsupported(VarHandleTestAccessString recv, VarHandle vh) {
 590 
 591         checkUOE(() -> {
 592             String o = (String) vh.getAndAdd(recv, "foo");
 593         });
 594 
 595         checkUOE(() -> {
 596             String o = (String) vh.getAndAddAcquire(recv, "foo");
 597         });
 598 
 599         checkUOE(() -> {
 600             String o = (String) vh.getAndAddRelease(recv, "foo");
 601         });
 602 
 603         checkUOE(() -> {
 604             String o = (String) vh.getAndBitwiseOr(recv, "foo");
 605         });
 606 
 607         checkUOE(() -> {
 608             String o = (String) vh.getAndBitwiseOrAcquire(recv, "foo");
 609         });
 610 
 611         checkUOE(() -> {
 612             String o = (String) vh.getAndBitwiseOrRelease(recv, "foo");
 613         });
 614 
 615         checkUOE(() -> {
 616             String o = (String) vh.getAndBitwiseAnd(recv, "foo");
 617         });
 618 
 619         checkUOE(() -> {
 620             String o = (String) vh.getAndBitwiseAndAcquire(recv, "foo");
 621         });
 622 
 623         checkUOE(() -> {
 624             String o = (String) vh.getAndBitwiseAndRelease(recv, "foo");
 625         });
 626 
 627         checkUOE(() -> {
 628             String o = (String) vh.getAndBitwiseXor(recv, "foo");
 629         });
 630 
 631         checkUOE(() -> {
 632             String o = (String) vh.getAndBitwiseXorAcquire(recv, "foo");
 633         });
 634 
 635         checkUOE(() -> {
 636             String o = (String) vh.getAndBitwiseXorRelease(recv, "foo");
 637         });
 638     }
 639 
 640 
 641     static void testStaticField(VarHandle vh) {
 642         // Plain
 643         {
 644             vh.set("foo");
 645             String x = (String) vh.get();
 646             assertEquals(x, "foo", "set String value");
 647         }
 648 
 649 
 650         // Volatile
 651         {
 652             vh.setVolatile("bar");
 653             String x = (String) vh.getVolatile();
 654             assertEquals(x, "bar", "setVolatile String value");
 655         }
 656 
 657         // Lazy
 658         {
 659             vh.setRelease("foo");
 660             String x = (String) vh.getAcquire();
 661             assertEquals(x, "foo", "setRelease String value");
 662         }
 663 
 664         // Opaque
 665         {
 666             vh.setOpaque("bar");
 667             String x = (String) vh.getOpaque();
 668             assertEquals(x, "bar", "setOpaque String value");
 669         }
 670 
 671         vh.set("foo");
 672 
 673         // Compare
 674         {
 675             boolean r = vh.compareAndSet("foo", "bar");
 676             assertEquals(r, true, "success compareAndSet String");
 677             String x = (String) vh.get();
 678             assertEquals(x, "bar", "success compareAndSet String value");
 679         }
 680 
 681         {
 682             boolean r = vh.compareAndSet("foo", "baz");
 683             assertEquals(r, false, "failing compareAndSet String");
 684             String x = (String) vh.get();
 685             assertEquals(x, "bar", "failing compareAndSet String value");
 686         }
 687 
 688         {
 689             String r = (String) vh.compareAndExchange("bar", "foo");
 690             assertEquals(r, "bar", "success compareAndExchange String");
 691             String x = (String) vh.get();
 692             assertEquals(x, "foo", "success compareAndExchange String value");
 693         }
 694 
 695         {
 696             String r = (String) vh.compareAndExchange("bar", "baz");
 697             assertEquals(r, "foo", "failing compareAndExchange String");
 698             String x = (String) vh.get();
 699             assertEquals(x, "foo", "failing compareAndExchange String value");
 700         }
 701 
 702         {
 703             String r = (String) vh.compareAndExchangeAcquire("foo", "bar");
 704             assertEquals(r, "foo", "success compareAndExchangeAcquire String");
 705             String x = (String) vh.get();
 706             assertEquals(x, "bar", "success compareAndExchangeAcquire String value");
 707         }
 708 
 709         {
 710             String r = (String) vh.compareAndExchangeAcquire("foo", "baz");
 711             assertEquals(r, "bar", "failing compareAndExchangeAcquire String");
 712             String x = (String) vh.get();
 713             assertEquals(x, "bar", "failing compareAndExchangeAcquire String value");
 714         }
 715 
 716         {
 717             String r = (String) vh.compareAndExchangeRelease("bar", "foo");
 718             assertEquals(r, "bar", "success compareAndExchangeRelease String");
 719             String x = (String) vh.get();
 720             assertEquals(x, "foo", "success compareAndExchangeRelease String value");
 721         }
 722 
 723         {
 724             String r = (String) vh.compareAndExchangeRelease("bar", "baz");
 725             assertEquals(r, "foo", "failing compareAndExchangeRelease String");
 726             String x = (String) vh.get();
 727             assertEquals(x, "foo", "failing compareAndExchangeRelease String value");
 728         }
 729 
 730         {
 731             boolean success = false;
 732             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 733                 success = vh.weakCompareAndSetPlain("foo", "bar");
 734             }
 735             assertEquals(success, true, "weakCompareAndSetPlain String");
 736             String x = (String) vh.get();
 737             assertEquals(x, "bar", "weakCompareAndSetPlain String value");
 738         }
 739 
 740         {
 741             boolean success = false;
 742             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 743                 success = vh.weakCompareAndSetAcquire("bar", "foo");
 744             }
 745             assertEquals(success, true, "weakCompareAndSetAcquire String");
 746             String x = (String) vh.get();
 747             assertEquals(x, "foo", "weakCompareAndSetAcquire String");
 748         }
 749 
 750         {
 751             boolean success = false;
 752             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 753                 success = vh.weakCompareAndSetRelease("foo", "bar");
 754             }
 755             assertEquals(success, true, "weakCompareAndSetRelease String");
 756             String x = (String) vh.get();
 757             assertEquals(x, "bar", "weakCompareAndSetRelease String");
 758         }
 759 
 760         {
 761             boolean success = false;
 762             for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 763                 success = vh.weakCompareAndSet("bar", "foo");
 764             }
 765             assertEquals(success, true, "weakCompareAndSet String");
 766             String x = (String) vh.get();
 767             assertEquals(x, "foo", "weakCompareAndSet String");
 768         }
 769 
 770         // Compare set and get
 771         {
 772             vh.set("foo");
 773 
 774             String o = (String) vh.getAndSet("bar");
 775             assertEquals(o, "foo", "getAndSet String");
 776             String x = (String) vh.get();
 777             assertEquals(x, "bar", "getAndSet String value");
 778         }
 779 
 780         {
 781             vh.set("foo");
 782 
 783             String o = (String) vh.getAndSetAcquire("bar");
 784             assertEquals(o, "foo", "getAndSetAcquire String");
 785             String x = (String) vh.get();
 786             assertEquals(x, "bar", "getAndSetAcquire String value");
 787         }
 788 
 789         {
 790             vh.set("foo");
 791 
 792             String o = (String) vh.getAndSetRelease("bar");
 793             assertEquals(o, "foo", "getAndSetRelease String");
 794             String x = (String) vh.get();
 795             assertEquals(x, "bar", "getAndSetRelease String value");
 796         }
 797 
 798 
 799     }
 800 
 801     static void testStaticFieldUnsupported(VarHandle vh) {
 802 
 803         checkUOE(() -> {
 804             String o = (String) vh.getAndAdd("foo");
 805         });
 806 
 807         checkUOE(() -> {
 808             String o = (String) vh.getAndAddAcquire("foo");
 809         });
 810 
 811         checkUOE(() -> {
 812             String o = (String) vh.getAndAddRelease("foo");
 813         });
 814 
 815         checkUOE(() -> {
 816             String o = (String) vh.getAndBitwiseOr("foo");
 817         });
 818 
 819         checkUOE(() -> {
 820             String o = (String) vh.getAndBitwiseOrAcquire("foo");
 821         });
 822 
 823         checkUOE(() -> {
 824             String o = (String) vh.getAndBitwiseOrRelease("foo");
 825         });
 826 
 827         checkUOE(() -> {
 828             String o = (String) vh.getAndBitwiseAnd("foo");
 829         });
 830 
 831         checkUOE(() -> {
 832             String o = (String) vh.getAndBitwiseAndAcquire("foo");
 833         });
 834 
 835         checkUOE(() -> {
 836             String o = (String) vh.getAndBitwiseAndRelease("foo");
 837         });
 838 
 839         checkUOE(() -> {
 840             String o = (String) vh.getAndBitwiseXor("foo");
 841         });
 842 
 843         checkUOE(() -> {
 844             String o = (String) vh.getAndBitwiseXorAcquire("foo");
 845         });
 846 
 847         checkUOE(() -> {
 848             String o = (String) vh.getAndBitwiseXorRelease("foo");
 849         });
 850     }
 851 
 852 
 853     static void testArray(VarHandle vh) {
 854         String[] array = new String[10];
 855 
 856         for (int i = 0; i < array.length; i++) {
 857             // Plain
 858             {
 859                 vh.set(array, i, "foo");
 860                 String x = (String) vh.get(array, i);
 861                 assertEquals(x, "foo", "get String value");
 862             }
 863 
 864 
 865             // Volatile
 866             {
 867                 vh.setVolatile(array, i, "bar");
 868                 String x = (String) vh.getVolatile(array, i);
 869                 assertEquals(x, "bar", "setVolatile String value");
 870             }
 871 
 872             // Lazy
 873             {
 874                 vh.setRelease(array, i, "foo");
 875                 String x = (String) vh.getAcquire(array, i);
 876                 assertEquals(x, "foo", "setRelease String value");
 877             }
 878 
 879             // Opaque
 880             {
 881                 vh.setOpaque(array, i, "bar");
 882                 String x = (String) vh.getOpaque(array, i);
 883                 assertEquals(x, "bar", "setOpaque String value");
 884             }
 885 
 886             vh.set(array, i, "foo");
 887 
 888             // Compare
 889             {
 890                 boolean r = vh.compareAndSet(array, i, "foo", "bar");
 891                 assertEquals(r, true, "success compareAndSet String");
 892                 String x = (String) vh.get(array, i);
 893                 assertEquals(x, "bar", "success compareAndSet String value");
 894             }
 895 
 896             {
 897                 boolean r = vh.compareAndSet(array, i, "foo", "baz");
 898                 assertEquals(r, false, "failing compareAndSet String");
 899                 String x = (String) vh.get(array, i);
 900                 assertEquals(x, "bar", "failing compareAndSet String value");
 901             }
 902 
 903             {
 904                 String r = (String) vh.compareAndExchange(array, i, "bar", "foo");
 905                 assertEquals(r, "bar", "success compareAndExchange String");
 906                 String x = (String) vh.get(array, i);
 907                 assertEquals(x, "foo", "success compareAndExchange String value");
 908             }
 909 
 910             {
 911                 String r = (String) vh.compareAndExchange(array, i, "bar", "baz");
 912                 assertEquals(r, "foo", "failing compareAndExchange String");
 913                 String x = (String) vh.get(array, i);
 914                 assertEquals(x, "foo", "failing compareAndExchange String value");
 915             }
 916 
 917             {
 918                 String r = (String) vh.compareAndExchangeAcquire(array, i, "foo", "bar");
 919                 assertEquals(r, "foo", "success compareAndExchangeAcquire String");
 920                 String x = (String) vh.get(array, i);
 921                 assertEquals(x, "bar", "success compareAndExchangeAcquire String value");
 922             }
 923 
 924             {
 925                 String r = (String) vh.compareAndExchangeAcquire(array, i, "foo", "baz");
 926                 assertEquals(r, "bar", "failing compareAndExchangeAcquire String");
 927                 String x = (String) vh.get(array, i);
 928                 assertEquals(x, "bar", "failing compareAndExchangeAcquire String value");
 929             }
 930 
 931             {
 932                 String r = (String) vh.compareAndExchangeRelease(array, i, "bar", "foo");
 933                 assertEquals(r, "bar", "success compareAndExchangeRelease String");
 934                 String x = (String) vh.get(array, i);
 935                 assertEquals(x, "foo", "success compareAndExchangeRelease String value");
 936             }
 937 
 938             {
 939                 String r = (String) vh.compareAndExchangeRelease(array, i, "bar", "baz");
 940                 assertEquals(r, "foo", "failing compareAndExchangeRelease String");
 941                 String x = (String) vh.get(array, i);
 942                 assertEquals(x, "foo", "failing compareAndExchangeRelease String value");
 943             }
 944 
 945             {
 946                 boolean success = false;
 947                 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 948                     success = vh.weakCompareAndSetPlain(array, i, "foo", "bar");
 949                 }
 950                 assertEquals(success, true, "weakCompareAndSetPlain String");
 951                 String x = (String) vh.get(array, i);
 952                 assertEquals(x, "bar", "weakCompareAndSetPlain String value");
 953             }
 954 
 955             {
 956                 boolean success = false;
 957                 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 958                     success = vh.weakCompareAndSetAcquire(array, i, "bar", "foo");
 959                 }
 960                 assertEquals(success, true, "weakCompareAndSetAcquire String");
 961                 String x = (String) vh.get(array, i);
 962                 assertEquals(x, "foo", "weakCompareAndSetAcquire String");
 963             }
 964 
 965             {
 966                 boolean success = false;
 967                 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 968                     success = vh.weakCompareAndSetRelease(array, i, "foo", "bar");
 969                 }
 970                 assertEquals(success, true, "weakCompareAndSetRelease String");
 971                 String x = (String) vh.get(array, i);
 972                 assertEquals(x, "bar", "weakCompareAndSetRelease String");
 973             }
 974 
 975             {
 976                 boolean success = false;
 977                 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
 978                     success = vh.weakCompareAndSet(array, i, "bar", "foo");
 979                 }
 980                 assertEquals(success, true, "weakCompareAndSet String");
 981                 String x = (String) vh.get(array, i);
 982                 assertEquals(x, "foo", "weakCompareAndSet String");
 983             }
 984 
 985             // Compare set and get
 986             {
 987                 vh.set(array, i, "foo");
 988 
 989                 String o = (String) vh.getAndSet(array, i, "bar");
 990                 assertEquals(o, "foo", "getAndSet String");
 991                 String x = (String) vh.get(array, i);
 992                 assertEquals(x, "bar", "getAndSet String value");
 993             }
 994 
 995             {
 996                 vh.set(array, i, "foo");
 997 
 998                 String o = (String) vh.getAndSetAcquire(array, i, "bar");
 999                 assertEquals(o, "foo", "getAndSetAcquire String");
1000                 String x = (String) vh.get(array, i);
1001                 assertEquals(x, "bar", "getAndSetAcquire String value");
1002             }
1003 
1004             {
1005                 vh.set(array, i, "foo");
1006 
1007                 String o = (String) vh.getAndSetRelease(array, i, "bar");
1008                 assertEquals(o, "foo", "getAndSetRelease String");
1009                 String x = (String) vh.get(array, i);
1010                 assertEquals(x, "bar", "getAndSetRelease String value");
1011             }
1012 
1013 
1014         }
1015     }
1016 
1017     static void testArrayUnsupported(VarHandle vh) {
1018         String[] array = new String[10];
1019 
1020         int i = 0;
1021 
1022         checkUOE(() -> {
1023             String o = (String) vh.getAndAdd(array, i, "foo");
1024         });
1025 
1026         checkUOE(() -> {
1027             String o = (String) vh.getAndAddAcquire(array, i, "foo");
1028         });
1029 
1030         checkUOE(() -> {
1031             String o = (String) vh.getAndAddRelease(array, i, "foo");
1032         });
1033 
1034         checkUOE(() -> {
1035             String o = (String) vh.getAndBitwiseOr(array, i, "foo");
1036         });
1037 
1038         checkUOE(() -> {
1039             String o = (String) vh.getAndBitwiseOrAcquire(array, i, "foo");
1040         });
1041 
1042         checkUOE(() -> {
1043             String o = (String) vh.getAndBitwiseOrRelease(array, i, "foo");
1044         });
1045 
1046         checkUOE(() -> {
1047             String o = (String) vh.getAndBitwiseAnd(array, i, "foo");
1048         });
1049 
1050         checkUOE(() -> {
1051             String o = (String) vh.getAndBitwiseAndAcquire(array, i, "foo");
1052         });
1053 
1054         checkUOE(() -> {
1055             String o = (String) vh.getAndBitwiseAndRelease(array, i, "foo");
1056         });
1057 
1058         checkUOE(() -> {
1059             String o = (String) vh.getAndBitwiseXor(array, i, "foo");
1060         });
1061 
1062         checkUOE(() -> {
1063             String o = (String) vh.getAndBitwiseXorAcquire(array, i, "foo");
1064         });
1065 
1066         checkUOE(() -> {
1067             String o = (String) vh.getAndBitwiseXorRelease(array, i, "foo");
1068         });
1069     }
1070 
1071     static void testArrayIndexOutOfBounds(VarHandle vh) throws Throwable {
1072         String[] array = new String[10];
1073 
1074         for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
1075             final int ci = i;
1076 
1077             checkIOOBE(() -> {
1078                 String x = (String) vh.get(array, ci);
1079             });
1080 
1081             checkIOOBE(() -> {
1082                 vh.set(array, ci, "foo");
1083             });
1084 
1085             checkIOOBE(() -> {
1086                 String x = (String) vh.getVolatile(array, ci);
1087             });
1088 
1089             checkIOOBE(() -> {
1090                 vh.setVolatile(array, ci, "foo");
1091             });
1092 
1093             checkIOOBE(() -> {
1094                 String x = (String) vh.getAcquire(array, ci);
1095             });
1096 
1097             checkIOOBE(() -> {
1098                 vh.setRelease(array, ci, "foo");
1099             });
1100 
1101             checkIOOBE(() -> {
1102                 String x = (String) vh.getOpaque(array, ci);
1103             });
1104 
1105             checkIOOBE(() -> {
1106                 vh.setOpaque(array, ci, "foo");
1107             });
1108 
1109             checkIOOBE(() -> {
1110                 boolean r = vh.compareAndSet(array, ci, "foo", "bar");
1111             });
1112 
1113             checkIOOBE(() -> {
1114                 String r = (String) vh.compareAndExchange(array, ci, "bar", "foo");
1115             });
1116 
1117             checkIOOBE(() -> {
1118                 String r = (String) vh.compareAndExchangeAcquire(array, ci, "bar", "foo");
1119             });
1120 
1121             checkIOOBE(() -> {
1122                 String r = (String) vh.compareAndExchangeRelease(array, ci, "bar", "foo");
1123             });
1124 
1125             checkIOOBE(() -> {
1126                 boolean r = vh.weakCompareAndSetPlain(array, ci, "foo", "bar");
1127             });
1128 
1129             checkIOOBE(() -> {
1130                 boolean r = vh.weakCompareAndSet(array, ci, "foo", "bar");
1131             });
1132 
1133             checkIOOBE(() -> {
1134                 boolean r = vh.weakCompareAndSetAcquire(array, ci, "foo", "bar");
1135             });
1136 
1137             checkIOOBE(() -> {
1138                 boolean r = vh.weakCompareAndSetRelease(array, ci, "foo", "bar");
1139             });
1140 
1141             checkIOOBE(() -> {
1142                 String o = (String) vh.getAndSet(array, ci, "foo");
1143             });
1144 
1145             checkIOOBE(() -> {
1146                 String o = (String) vh.getAndSetAcquire(array, ci, "foo");
1147             });
1148 
1149             checkIOOBE(() -> {
1150                 String o = (String) vh.getAndSetRelease(array, ci, "foo");
1151             });
1152 
1153 
1154         }
1155     }
1156 
1157     static void testArrayStoreException(VarHandle vh) throws Throwable {
1158         Object[] array = new String[10];
1159         Arrays.fill(array, "foo");
1160         Object value = new Object();
1161 
1162         // Set
1163         checkASE(() -> {
1164             vh.set(array, 0, value);
1165         });
1166 
1167         // SetVolatile
1168         checkASE(() -> {
1169             vh.setVolatile(array, 0, value);
1170         });
1171 
1172         // SetOpaque
1173         checkASE(() -> {
1174             vh.setOpaque(array, 0, value);
1175         });
1176 
1177         // SetRelease
1178         checkASE(() -> {
1179             vh.setRelease(array, 0, value);
1180         });
1181 
1182         // CompareAndSet
1183         checkASE(() -> { // receiver reference class
1184             boolean r = vh.compareAndSet(array, 0, "foo", value);
1185         });
1186 
1187         // WeakCompareAndSet
1188         checkASE(() -> { // receiver reference class
1189             boolean r = vh.weakCompareAndSetPlain(array, 0, "foo", value);
1190         });
1191 
1192         // WeakCompareAndSetVolatile
1193         checkASE(() -> { // receiver reference class
1194             boolean r = vh.weakCompareAndSet(array, 0, "foo", value);
1195         });
1196 
1197         // WeakCompareAndSetAcquire
1198         checkASE(() -> { // receiver reference class
1199             boolean r = vh.weakCompareAndSetAcquire(array, 0, "foo", value);
1200         });
1201 
1202         // WeakCompareAndSetRelease
1203         checkASE(() -> { // receiver reference class
1204             boolean r = vh.weakCompareAndSetRelease(array, 0, "foo", value);
1205         });
1206 
1207         // CompareAndExchange
1208         checkASE(() -> { // receiver reference class
1209             String x = (String) vh.compareAndExchange(array, 0, "foo", value);
1210         });
1211 
1212         // CompareAndExchangeAcquire
1213         checkASE(() -> { // receiver reference class
1214             String x = (String) vh.compareAndExchangeAcquire(array, 0, "foo", value);
1215         });
1216 
1217         // CompareAndExchangeRelease
1218         checkASE(() -> { // receiver reference class
1219             String x = (String) vh.compareAndExchangeRelease(array, 0, "foo", value);
1220         });
1221 
1222         // GetAndSet
1223         checkASE(() -> { // receiver reference class
1224             String x = (String) vh.getAndSet(array, 0, value);
1225         });
1226 
1227         // GetAndSetAcquire
1228         checkASE(() -> { // receiver reference class
1229             String x = (String) vh.getAndSetAcquire(array, 0, value);
1230         });
1231 
1232         // GetAndSetRelease
1233         checkASE(() -> { // receiver reference class
1234             String x = (String) vh.getAndSetRelease(array, 0, value);
1235         });
1236     }
1237 }
1238