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