jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessChar.java
changeset 36934 590fc47a0aeb
child 37343 35a2231828a7
equal deleted inserted replaced
36933:3e6453e2d833 36934:590fc47a0aeb
       
     1 /*
       
     2  * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  */
       
    23 
       
    24 /*
       
    25  * @test
       
    26  * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccessChar
       
    27  */
       
    28 
       
    29 import org.testng.annotations.BeforeClass;
       
    30 import org.testng.annotations.DataProvider;
       
    31 import org.testng.annotations.Test;
       
    32 
       
    33 import java.lang.invoke.MethodHandles;
       
    34 import java.lang.invoke.VarHandle;
       
    35 import java.util.ArrayList;
       
    36 import java.util.Arrays;
       
    37 import java.util.List;
       
    38 
       
    39 import static org.testng.Assert.*;
       
    40 
       
    41 public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest {
       
    42     static final char static_final_v = 'a';
       
    43 
       
    44     static char static_v;
       
    45 
       
    46     final char final_v = 'a';
       
    47 
       
    48     char v;
       
    49 
       
    50     VarHandle vhFinalField;
       
    51 
       
    52     VarHandle vhField;
       
    53 
       
    54     VarHandle vhStaticField;
       
    55 
       
    56     VarHandle vhStaticFinalField;
       
    57 
       
    58     VarHandle vhArray;
       
    59 
       
    60     @BeforeClass
       
    61     public void setup() throws Exception {
       
    62         vhFinalField = MethodHandles.lookup().findVarHandle(
       
    63                 VarHandleTestMethodHandleAccessChar.class, "final_v", char.class);
       
    64 
       
    65         vhField = MethodHandles.lookup().findVarHandle(
       
    66                 VarHandleTestMethodHandleAccessChar.class, "v", char.class);
       
    67 
       
    68         vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
       
    69             VarHandleTestMethodHandleAccessChar.class, "static_final_v", char.class);
       
    70 
       
    71         vhStaticField = MethodHandles.lookup().findStaticVarHandle(
       
    72             VarHandleTestMethodHandleAccessChar.class, "static_v", char.class);
       
    73 
       
    74         vhArray = MethodHandles.arrayElementVarHandle(char[].class);
       
    75     }
       
    76 
       
    77 
       
    78     @DataProvider
       
    79     public Object[][] accessTestCaseProvider() throws Exception {
       
    80         List<AccessTestCase<?>> cases = new ArrayList<>();
       
    81 
       
    82         for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
       
    83             cases.add(new MethodHandleAccessTestCase("Instance field",
       
    84                                                      vhField, f, hs -> testInstanceField(this, hs)));
       
    85             cases.add(new MethodHandleAccessTestCase("Instance field unsupported",
       
    86                                                      vhField, f, hs -> testInstanceFieldUnsupported(this, hs),
       
    87                                                      false));
       
    88 
       
    89             cases.add(new MethodHandleAccessTestCase("Static field",
       
    90                                                      vhStaticField, f, VarHandleTestMethodHandleAccessChar::testStaticField));
       
    91             cases.add(new MethodHandleAccessTestCase("Static field unsupported",
       
    92                                                      vhStaticField, f, VarHandleTestMethodHandleAccessChar::testStaticFieldUnsupported,
       
    93                                                      false));
       
    94 
       
    95             cases.add(new MethodHandleAccessTestCase("Array",
       
    96                                                      vhArray, f, VarHandleTestMethodHandleAccessChar::testArray));
       
    97             cases.add(new MethodHandleAccessTestCase("Array unsupported",
       
    98                                                      vhArray, f, VarHandleTestMethodHandleAccessChar::testArrayUnsupported,
       
    99                                                      false));
       
   100             cases.add(new MethodHandleAccessTestCase("Array index out of bounds",
       
   101                                                      vhArray, f, VarHandleTestMethodHandleAccessChar::testArrayIndexOutOfBounds,
       
   102                                                      false));
       
   103         }
       
   104 
       
   105         // Work around issue with jtreg summary reporting which truncates
       
   106         // the String result of Object.toString to 30 characters, hence
       
   107         // the first dummy argument
       
   108         return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
       
   109     }
       
   110 
       
   111     @Test(dataProvider = "accessTestCaseProvider")
       
   112     public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
       
   113         T t = atc.get();
       
   114         int iters = atc.requiresLoop() ? ITERS : 1;
       
   115         for (int c = 0; c < iters; c++) {
       
   116             atc.testAccess(t);
       
   117         }
       
   118     }
       
   119 
       
   120 
       
   121     static void testInstanceField(VarHandleTestMethodHandleAccessChar recv, Handles hs) throws Throwable {
       
   122         // Plain
       
   123         {
       
   124             hs.get(TestAccessMode.set).invokeExact(recv, 'a');
       
   125             char x = (char) hs.get(TestAccessMode.get).invokeExact(recv);
       
   126             assertEquals(x, 'a', "set char value");
       
   127         }
       
   128 
       
   129 
       
   130         // Volatile
       
   131         {
       
   132             hs.get(TestAccessMode.setVolatile).invokeExact(recv, 'b');
       
   133             char x = (char) hs.get(TestAccessMode.getVolatile).invokeExact(recv);
       
   134             assertEquals(x, 'b', "setVolatile char value");
       
   135         }
       
   136 
       
   137         // Lazy
       
   138         {
       
   139             hs.get(TestAccessMode.setRelease).invokeExact(recv, 'a');
       
   140             char x = (char) hs.get(TestAccessMode.getAcquire).invokeExact(recv);
       
   141             assertEquals(x, 'a', "setRelease char value");
       
   142         }
       
   143 
       
   144         // Opaque
       
   145         {
       
   146             hs.get(TestAccessMode.setOpaque).invokeExact(recv, 'b');
       
   147             char x = (char) hs.get(TestAccessMode.getOpaque).invokeExact(recv);
       
   148             assertEquals(x, 'b', "setOpaque char value");
       
   149         }
       
   150 
       
   151 
       
   152     }
       
   153 
       
   154     static void testInstanceFieldUnsupported(VarHandleTestMethodHandleAccessChar recv, Handles hs) throws Throwable {
       
   155         for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
       
   156             checkUOE(am, () -> {
       
   157                 boolean r = (boolean) hs.get(am).invokeExact(recv, 'a', 'b');
       
   158             });
       
   159         }
       
   160 
       
   161         for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
       
   162             checkUOE(am, () -> {
       
   163                 char r = (char) hs.get(am).invokeExact(recv, 'a', 'b');
       
   164             });
       
   165         }
       
   166 
       
   167         for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
       
   168             checkUOE(am, () -> {
       
   169                 char r = (char) hs.get(am).invokeExact(recv, 'a');
       
   170             });
       
   171         }
       
   172 
       
   173         for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
       
   174             checkUOE(am, () -> {
       
   175                 char r = (char) hs.get(am).invokeExact(recv, 'a');
       
   176             });
       
   177         }
       
   178     }
       
   179 
       
   180 
       
   181     static void testStaticField(Handles hs) throws Throwable {
       
   182         // Plain
       
   183         {
       
   184             hs.get(TestAccessMode.set).invokeExact('a');
       
   185             char x = (char) hs.get(TestAccessMode.get).invokeExact();
       
   186             assertEquals(x, 'a', "set char value");
       
   187         }
       
   188 
       
   189 
       
   190         // Volatile
       
   191         {
       
   192             hs.get(TestAccessMode.setVolatile).invokeExact('b');
       
   193             char x = (char) hs.get(TestAccessMode.getVolatile).invokeExact();
       
   194             assertEquals(x, 'b', "setVolatile char value");
       
   195         }
       
   196 
       
   197         // Lazy
       
   198         {
       
   199             hs.get(TestAccessMode.setRelease).invokeExact('a');
       
   200             char x = (char) hs.get(TestAccessMode.getAcquire).invokeExact();
       
   201             assertEquals(x, 'a', "setRelease char value");
       
   202         }
       
   203 
       
   204         // Opaque
       
   205         {
       
   206             hs.get(TestAccessMode.setOpaque).invokeExact('b');
       
   207             char x = (char) hs.get(TestAccessMode.getOpaque).invokeExact();
       
   208             assertEquals(x, 'b', "setOpaque char value");
       
   209         }
       
   210 
       
   211 
       
   212     }
       
   213 
       
   214     static void testStaticFieldUnsupported(Handles hs) throws Throwable {
       
   215         for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
       
   216             checkUOE(am, () -> {
       
   217                 boolean r = (boolean) hs.get(am).invokeExact('a', 'b');
       
   218             });
       
   219         }
       
   220 
       
   221         for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
       
   222             checkUOE(am, () -> {
       
   223                 char r = (char) hs.get(am).invokeExact('a', 'b');
       
   224             });
       
   225         }
       
   226 
       
   227         for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
       
   228             checkUOE(am, () -> {
       
   229                 char r = (char) hs.get(am).invokeExact('a');
       
   230             });
       
   231         }
       
   232 
       
   233         for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
       
   234             checkUOE(am, () -> {
       
   235                 char r = (char) hs.get(am).invokeExact('a');
       
   236             });
       
   237         }
       
   238     }
       
   239 
       
   240 
       
   241     static void testArray(Handles hs) throws Throwable {
       
   242         char[] array = new char[10];
       
   243 
       
   244         for (int i = 0; i < array.length; i++) {
       
   245             // Plain
       
   246             {
       
   247                 hs.get(TestAccessMode.set).invokeExact(array, i, 'a');
       
   248                 char x = (char) hs.get(TestAccessMode.get).invokeExact(array, i);
       
   249                 assertEquals(x, 'a', "get char value");
       
   250             }
       
   251 
       
   252 
       
   253             // Volatile
       
   254             {
       
   255                 hs.get(TestAccessMode.setVolatile).invokeExact(array, i, 'b');
       
   256                 char x = (char) hs.get(TestAccessMode.getVolatile).invokeExact(array, i);
       
   257                 assertEquals(x, 'b', "setVolatile char value");
       
   258             }
       
   259 
       
   260             // Lazy
       
   261             {
       
   262                 hs.get(TestAccessMode.setRelease).invokeExact(array, i, 'a');
       
   263                 char x = (char) hs.get(TestAccessMode.getAcquire).invokeExact(array, i);
       
   264                 assertEquals(x, 'a', "setRelease char value");
       
   265             }
       
   266 
       
   267             // Opaque
       
   268             {
       
   269                 hs.get(TestAccessMode.setOpaque).invokeExact(array, i, 'b');
       
   270                 char x = (char) hs.get(TestAccessMode.getOpaque).invokeExact(array, i);
       
   271                 assertEquals(x, 'b', "setOpaque char value");
       
   272             }
       
   273 
       
   274 
       
   275         }
       
   276     }
       
   277 
       
   278     static void testArrayUnsupported(Handles hs) throws Throwable {
       
   279         char[] array = new char[10];
       
   280 
       
   281         final int i = 0;
       
   282         for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
       
   283             checkUOE(am, () -> {
       
   284                 boolean r = (boolean) hs.get(am).invokeExact(array, i, 'a', 'b');
       
   285             });
       
   286         }
       
   287 
       
   288         for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
       
   289             checkUOE(am, () -> {
       
   290                 char r = (char) hs.get(am).invokeExact(array, i, 'a', 'b');
       
   291             });
       
   292         }
       
   293 
       
   294         for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
       
   295             checkUOE(am, () -> {
       
   296                 char r = (char) hs.get(am).invokeExact(array, i, 'a');
       
   297             });
       
   298         }
       
   299 
       
   300         for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
       
   301             checkUOE(am, () -> {
       
   302                 char o = (char) hs.get(am).invokeExact(array, i, 'a');
       
   303             });
       
   304         }
       
   305     }
       
   306 
       
   307     static void testArrayIndexOutOfBounds(Handles hs) throws Throwable {
       
   308         char[] array = new char[10];
       
   309 
       
   310         for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
       
   311             final int ci = i;
       
   312 
       
   313             for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
       
   314                 checkIOOBE(am, () -> {
       
   315                     char x = (char) hs.get(am).invokeExact(array, ci);
       
   316                 });
       
   317             }
       
   318 
       
   319             for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
       
   320                 checkIOOBE(am, () -> {
       
   321                     hs.get(am).invokeExact(array, ci, 'a');
       
   322                 });
       
   323             }
       
   324 
       
   325 
       
   326         }
       
   327     }
       
   328 }
       
   329