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