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