1 /*
2  * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 /*
25  * @test
26  * @bug 8154556
27  * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsChar
28  * @run testng/othervm -Diters=20000                         VarHandleTestByteArrayAsChar
29  * @run testng/othervm -Diters=20000 -XX:-TieredCompilation  VarHandleTestByteArrayAsChar
30  */
31 
32 import org.testng.annotations.DataProvider;
33 import org.testng.annotations.Test;
34 
35 import java.lang.invoke.MethodHandles;
36 import java.lang.invoke.VarHandle;
37 import java.nio.ByteBuffer;
38 import java.nio.ByteOrder;
39 import java.util.ArrayList;
40 import java.util.Arrays;
41 import java.util.EnumSet;
42 import java.util.List;
43 
44 import static org.testng.Assert.*;
45 
46 public class VarHandleTestByteArrayAsChar extends VarHandleBaseByteArrayTest {
47     static final int SIZE = Character.BYTES;
48 
49     static final char VALUE_1 = (char)0x0102;
50 
51     static final char VALUE_2 = (char)0x1112;
52 
53     static final char VALUE_3 = (char)0xFFFE;
54 
55 
56     @Override
setupVarHandleSources(boolean same)57     public List<VarHandleSource> setupVarHandleSources(boolean same) {
58         // Combinations of VarHandle byte[] or ByteBuffer
59         List<VarHandleSource> vhss = new ArrayList<>();
60         for (MemoryMode endianess : List.of(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) {
61 
62             ByteOrder bo = endianess == MemoryMode.BIG_ENDIAN
63                     ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
64 
65             Class<?> arrayType;
66             if (same) {
67                 arrayType = char[].class;
68             }
69             else {
70                 arrayType = int[].class;
71             }
72             VarHandleSource aeh = new VarHandleSource(
73                     MethodHandles.byteArrayViewVarHandle(arrayType, bo),
74                     endianess, MemoryMode.READ_WRITE);
75             vhss.add(aeh);
76 
77             VarHandleSource bbh = new VarHandleSource(
78                     MethodHandles.byteBufferViewVarHandle(arrayType, bo),
79                     endianess, MemoryMode.READ_WRITE);
80             vhss.add(bbh);
81         }
82         return vhss;
83     }
84 
85     @Test
testEquals()86     public void testEquals() {
87         VarHandle[] vhs1 = setupVarHandleSources(true).stream().
88             map(vhs -> vhs.s).toArray(VarHandle[]::new);
89         VarHandle[] vhs2 = setupVarHandleSources(true).stream().
90             map(vhs -> vhs.s).toArray(VarHandle[]::new);
91 
92         for (int i = 0; i < vhs1.length; i++) {
93             for (int j = 0; j < vhs1.length; j++) {
94                 if (i != j) {
95                     assertNotEquals(vhs1[i], vhs1[j]);
96                     assertNotEquals(vhs1[i], vhs2[j]);
97                 }
98             }
99         }
100 
101         VarHandle[] vhs3 = setupVarHandleSources(false).stream().
102             map(vhs -> vhs.s).toArray(VarHandle[]::new);
103         for (int i = 0; i < vhs1.length; i++) {
104             assertNotEquals(vhs1[i], vhs3[i]);
105         }
106     }
107 
108     @Test(dataProvider = "varHandlesProvider")
testIsAccessModeSupported(VarHandleSource vhs)109     public void testIsAccessModeSupported(VarHandleSource vhs) {
110         VarHandle vh = vhs.s;
111 
112         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET));
113         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET));
114 
115         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_VOLATILE));
116         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_VOLATILE));
117         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_ACQUIRE));
118         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_RELEASE));
119         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_OPAQUE));
120         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_OPAQUE));
121 
122         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_SET));
123         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE));
124         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
125         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
126         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_PLAIN));
127         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
128         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
129         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
130         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
131         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET_ACQUIRE));
132         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET_RELEASE));
133 
134         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
135         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD_ACQUIRE));
136         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD_RELEASE));
137 
138         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR));
139         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR_ACQUIRE));
140         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR_RELEASE));
141         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND));
142         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND_ACQUIRE));
143         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND_RELEASE));
144         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR));
145         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_ACQUIRE));
146         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_RELEASE));
147     }
148 
149     @Test(dataProvider = "typesProvider")
testTypes(VarHandle vh, List<java.lang.Class<?>> pts)150     public void testTypes(VarHandle vh, List<java.lang.Class<?>> pts) {
151         assertEquals(vh.varType(), char.class);
152 
153         assertEquals(vh.coordinateTypes(), pts);
154 
155         testTypes(vh);
156     }
157 
158 
159     @DataProvider
accessTestCaseProvider()160     public Object[][] accessTestCaseProvider() throws Exception {
161         List<AccessTestCase<?>> cases = new ArrayList<>();
162 
163         for (ByteArrayViewSource<?> bav : bavss) {
164             for (VarHandleSource vh : vhss) {
165                 if (vh.matches(bav)) {
166                     if (bav instanceof ByteArraySource) {
167                         ByteArraySource bas = (ByteArraySource) bav;
168 
169                         cases.add(new VarHandleSourceAccessTestCase(
170                                 "read write", bav, vh, h -> testArrayReadWrite(bas, h),
171                                 true));
172                         cases.add(new VarHandleSourceAccessTestCase(
173                                 "null array", bav, vh, h -> testArrayNPE(bas, h),
174                                 false));
175                         cases.add(new VarHandleSourceAccessTestCase(
176                                 "unsupported", bav, vh, h -> testArrayUnsupported(bas, h),
177                                 false));
178                         cases.add(new VarHandleSourceAccessTestCase(
179                                 "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bas, h),
180                                 false));
181                         cases.add(new VarHandleSourceAccessTestCase(
182                                 "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bas, h),
183                                 false));
184                     }
185                     else {
186                         ByteBufferSource bbs = (ByteBufferSource) bav;
187 
188                         if (MemoryMode.READ_WRITE.isSet(bav.memoryModes)) {
189                             cases.add(new VarHandleSourceAccessTestCase(
190                                     "read write", bav, vh, h -> testArrayReadWrite(bbs, h),
191                                     true));
192                         }
193                         else {
194                             cases.add(new VarHandleSourceAccessTestCase(
195                                     "read only", bav, vh, h -> testArrayReadOnly(bbs, h),
196                                     true));
197                         }
198 
199                         cases.add(new VarHandleSourceAccessTestCase(
200                                 "null buffer", bav, vh, h -> testArrayNPE(bbs, h),
201                                 false));
202                         cases.add(new VarHandleSourceAccessTestCase(
203                                 "unsupported", bav, vh, h -> testArrayUnsupported(bbs, h),
204                                 false));
205                         cases.add(new VarHandleSourceAccessTestCase(
206                                 "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bbs, h),
207                                 false));
208                         cases.add(new VarHandleSourceAccessTestCase(
209                                 "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bbs, h),
210                                 false));
211                     }
212                 }
213             }
214         }
215 
216         // Work around issue with jtreg summary reporting which truncates
217         // the String result of Object.toString to 30 characters, hence
218         // the first dummy argument
219         return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
220     }
221 
222     @Test(dataProvider = "accessTestCaseProvider")
testAccess(String desc, AccessTestCase<T> atc)223     public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
224         T t = atc.get();
225         int iters = atc.requiresLoop() ? ITERS : 1;
226         for (int c = 0; c < iters; c++) {
227             atc.testAccess(t);
228         }
229     }
230 
231 
testArrayNPE(ByteArraySource bs, VarHandleSource vhs)232     static void testArrayNPE(ByteArraySource bs, VarHandleSource vhs) {
233         VarHandle vh = vhs.s;
234         byte[] array = null;
235         int ci = 1;
236 
237         checkNPE(() -> {
238             char x = (char) vh.get(array, ci);
239         });
240 
241         checkNPE(() -> {
242             vh.set(array, ci, VALUE_1);
243         });
244 
245         checkNPE(() -> {
246             char x = (char) vh.getVolatile(array, ci);
247         });
248 
249         checkNPE(() -> {
250             char x = (char) vh.getAcquire(array, ci);
251         });
252 
253         checkNPE(() -> {
254             char x = (char) vh.getOpaque(array, ci);
255         });
256 
257         checkNPE(() -> {
258             vh.setVolatile(array, ci, VALUE_1);
259         });
260 
261         checkNPE(() -> {
262             vh.setRelease(array, ci, VALUE_1);
263         });
264 
265         checkNPE(() -> {
266             vh.setOpaque(array, ci, VALUE_1);
267         });
268 
269 
270 
271     }
272 
testArrayNPE(ByteBufferSource bs, VarHandleSource vhs)273     static void testArrayNPE(ByteBufferSource bs, VarHandleSource vhs) {
274         VarHandle vh = vhs.s;
275         ByteBuffer array = null;
276         int ci = 1;
277 
278         checkNPE(() -> {
279             char x = (char) vh.get(array, ci);
280         });
281 
282         checkNPE(() -> {
283             vh.set(array, ci, VALUE_1);
284         });
285 
286         checkNPE(() -> {
287             char x = (char) vh.getVolatile(array, ci);
288         });
289 
290         checkNPE(() -> {
291             char x = (char) vh.getAcquire(array, ci);
292         });
293 
294         checkNPE(() -> {
295             char x = (char) vh.getOpaque(array, ci);
296         });
297 
298         checkNPE(() -> {
299             vh.setVolatile(array, ci, VALUE_1);
300         });
301 
302         checkNPE(() -> {
303             vh.setRelease(array, ci, VALUE_1);
304         });
305 
306         checkNPE(() -> {
307             vh.setOpaque(array, ci, VALUE_1);
308         });
309 
310 
311 
312     }
313 
testArrayUnsupported(ByteArraySource bs, VarHandleSource vhs)314     static void testArrayUnsupported(ByteArraySource bs, VarHandleSource vhs) {
315         VarHandle vh = vhs.s;
316         byte[] array = bs.s;
317         int ci = 1;
318 
319         checkUOE(() -> {
320             boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
321         });
322 
323         checkUOE(() -> {
324             char r = (char) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
325         });
326 
327         checkUOE(() -> {
328             char r = (char) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
329         });
330 
331         checkUOE(() -> {
332             char r = (char) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
333         });
334 
335         checkUOE(() -> {
336             boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
337         });
338 
339         checkUOE(() -> {
340             boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
341         });
342 
343         checkUOE(() -> {
344             boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
345         });
346 
347         checkUOE(() -> {
348             boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
349         });
350 
351         checkUOE(() -> {
352             char o = (char) vh.getAndSet(array, ci, VALUE_1);
353         });
354 
355         checkUOE(() -> {
356             char o = (char) vh.getAndSetAcquire(array, ci, VALUE_1);
357         });
358 
359         checkUOE(() -> {
360             char o = (char) vh.getAndSetRelease(array, ci, VALUE_1);
361         });
362 
363         checkUOE(() -> {
364             char o = (char) vh.getAndAdd(array, ci, VALUE_1);
365         });
366 
367         checkUOE(() -> {
368             char o = (char) vh.getAndAddAcquire(array, ci, VALUE_1);
369         });
370 
371         checkUOE(() -> {
372             char o = (char) vh.getAndAddRelease(array, ci, VALUE_1);
373         });
374 
375         checkUOE(() -> {
376             char o = (char) vh.getAndBitwiseOr(array, ci, VALUE_1);
377         });
378 
379         checkUOE(() -> {
380             char o = (char) vh.getAndBitwiseOrAcquire(array, ci, VALUE_1);
381         });
382 
383         checkUOE(() -> {
384             char o = (char) vh.getAndBitwiseOrRelease(array, ci, VALUE_1);
385         });
386 
387         checkUOE(() -> {
388             char o = (char) vh.getAndBitwiseAnd(array, ci, VALUE_1);
389         });
390 
391         checkUOE(() -> {
392             char o = (char) vh.getAndBitwiseAndAcquire(array, ci, VALUE_1);
393         });
394 
395         checkUOE(() -> {
396             char o = (char) vh.getAndBitwiseAndRelease(array, ci, VALUE_1);
397         });
398 
399         checkUOE(() -> {
400             char o = (char) vh.getAndBitwiseXor(array, ci, VALUE_1);
401         });
402 
403         checkUOE(() -> {
404             char o = (char) vh.getAndBitwiseXorAcquire(array, ci, VALUE_1);
405         });
406 
407         checkUOE(() -> {
408             char o = (char) vh.getAndBitwiseXorRelease(array, ci, VALUE_1);
409         });
410     }
411 
testArrayUnsupported(ByteBufferSource bs, VarHandleSource vhs)412     static void testArrayUnsupported(ByteBufferSource bs, VarHandleSource vhs) {
413         VarHandle vh = vhs.s;
414         ByteBuffer array = bs.s;
415         int ci = 0;
416         boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
417 
418         if (readOnly) {
419             checkROBE(() -> {
420                 vh.set(array, ci, VALUE_1);
421             });
422         }
423 
424         if (readOnly) {
425             checkROBE(() -> {
426                 vh.setVolatile(array, ci, VALUE_1);
427             });
428 
429             checkROBE(() -> {
430                 vh.setRelease(array, ci, VALUE_1);
431             });
432 
433             checkROBE(() -> {
434                 vh.setOpaque(array, ci, VALUE_1);
435             });
436             checkUOE(() -> {
437                 boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
438             });
439 
440             checkUOE(() -> {
441                 char r = (char) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
442             });
443 
444             checkUOE(() -> {
445                 char r = (char) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
446             });
447 
448             checkUOE(() -> {
449                 char r = (char) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
450             });
451 
452             checkUOE(() -> {
453                 boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
454             });
455 
456             checkUOE(() -> {
457                 boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
458             });
459 
460             checkUOE(() -> {
461                 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
462             });
463 
464             checkUOE(() -> {
465                 boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
466             });
467 
468             checkUOE(() -> {
469                 char o = (char) vh.getAndSet(array, ci, VALUE_1);
470             });
471 
472             checkUOE(() -> {
473                 char o = (char) vh.getAndSetAcquire(array, ci, VALUE_1);
474             });
475 
476             checkUOE(() -> {
477                 char o = (char) vh.getAndSetRelease(array, ci, VALUE_1);
478             });
479 
480             checkUOE(() -> {
481                 char o = (char) vh.getAndAdd(array, ci, VALUE_1);
482             });
483 
484             checkUOE(() -> {
485                 char o = (char) vh.getAndAddAcquire(array, ci, VALUE_1);
486             });
487 
488             checkUOE(() -> {
489                 char o = (char) vh.getAndAddRelease(array, ci, VALUE_1);
490             });
491 
492             checkUOE(() -> {
493                 char o = (char) vh.getAndBitwiseOr(array, ci, VALUE_1);
494             });
495 
496             checkUOE(() -> {
497                 char o = (char) vh.getAndBitwiseOrAcquire(array, ci, VALUE_1);
498             });
499 
500             checkUOE(() -> {
501                 char o = (char) vh.getAndBitwiseOrRelease(array, ci, VALUE_1);
502             });
503 
504             checkUOE(() -> {
505                 char o = (char) vh.getAndBitwiseAnd(array, ci, VALUE_1);
506             });
507 
508             checkUOE(() -> {
509                 char o = (char) vh.getAndBitwiseAndAcquire(array, ci, VALUE_1);
510             });
511 
512             checkUOE(() -> {
513                 char o = (char) vh.getAndBitwiseAndRelease(array, ci, VALUE_1);
514             });
515 
516             checkUOE(() -> {
517                 char o = (char) vh.getAndBitwiseXor(array, ci, VALUE_1);
518             });
519 
520             checkUOE(() -> {
521                 char o = (char) vh.getAndBitwiseXorAcquire(array, ci, VALUE_1);
522             });
523 
524             checkUOE(() -> {
525                 char o = (char) vh.getAndBitwiseXorRelease(array, ci, VALUE_1);
526             });
527         }
528         else {
529             checkUOE(() -> {
530                 boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
531             });
532 
533             checkUOE(() -> {
534                 char r = (char) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
535             });
536 
537             checkUOE(() -> {
538                 char r = (char) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
539             });
540 
541             checkUOE(() -> {
542                 char r = (char) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
543             });
544 
545             checkUOE(() -> {
546                 boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
547             });
548 
549             checkUOE(() -> {
550                 boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
551             });
552 
553             checkUOE(() -> {
554                 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
555             });
556 
557             checkUOE(() -> {
558                 boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
559             });
560 
561             checkUOE(() -> {
562                 char o = (char) vh.getAndSet(array, ci, VALUE_1);
563             });
564 
565             checkUOE(() -> {
566                 char o = (char) vh.getAndSetAcquire(array, ci, VALUE_1);
567             });
568 
569             checkUOE(() -> {
570                 char o = (char) vh.getAndSetRelease(array, ci, VALUE_1);
571             });
572             checkUOE(() -> {
573                 char o = (char) vh.getAndAdd(array, ci, VALUE_1);
574             });
575 
576             checkUOE(() -> {
577                 char o = (char) vh.getAndAddAcquire(array, ci, VALUE_1);
578             });
579 
580             checkUOE(() -> {
581                 char o = (char) vh.getAndAddRelease(array, ci, VALUE_1);
582             });
583             checkUOE(() -> {
584                 char o = (char) vh.getAndBitwiseOr(array, ci, VALUE_1);
585             });
586 
587             checkUOE(() -> {
588                 char o = (char) vh.getAndBitwiseOrAcquire(array, ci, VALUE_1);
589             });
590 
591             checkUOE(() -> {
592                 char o = (char) vh.getAndBitwiseOrRelease(array, ci, VALUE_1);
593             });
594 
595             checkUOE(() -> {
596                 char o = (char) vh.getAndBitwiseAnd(array, ci, VALUE_1);
597             });
598 
599             checkUOE(() -> {
600                 char o = (char) vh.getAndBitwiseAndAcquire(array, ci, VALUE_1);
601             });
602 
603             checkUOE(() -> {
604                 char o = (char) vh.getAndBitwiseAndRelease(array, ci, VALUE_1);
605             });
606 
607             checkUOE(() -> {
608                 char o = (char) vh.getAndBitwiseXor(array, ci, VALUE_1);
609             });
610 
611             checkUOE(() -> {
612                 char o = (char) vh.getAndBitwiseXorAcquire(array, ci, VALUE_1);
613             });
614 
615             checkUOE(() -> {
616                 char o = (char) vh.getAndBitwiseXorRelease(array, ci, VALUE_1);
617             });
618         }
619     }
620 
621 
testArrayIndexOutOfBounds(ByteArraySource bs, VarHandleSource vhs)622     static void testArrayIndexOutOfBounds(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
623         VarHandle vh = vhs.s;
624         byte[] array = bs.s;
625 
626         int length = array.length - SIZE + 1;
627         for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
628             final int ci = i;
629 
630             checkIOOBE(() -> {
631                 char x = (char) vh.get(array, ci);
632             });
633 
634             checkIOOBE(() -> {
635                 vh.set(array, ci, VALUE_1);
636             });
637 
638             checkIOOBE(() -> {
639                 char x = (char) vh.getVolatile(array, ci);
640             });
641 
642             checkIOOBE(() -> {
643                 char x = (char) vh.getAcquire(array, ci);
644             });
645 
646             checkIOOBE(() -> {
647                 char x = (char) vh.getOpaque(array, ci);
648             });
649 
650             checkIOOBE(() -> {
651                 vh.setVolatile(array, ci, VALUE_1);
652             });
653 
654             checkIOOBE(() -> {
655                 vh.setRelease(array, ci, VALUE_1);
656             });
657 
658             checkIOOBE(() -> {
659                 vh.setOpaque(array, ci, VALUE_1);
660             });
661 
662 
663 
664         }
665     }
666 
testArrayIndexOutOfBounds(ByteBufferSource bs, VarHandleSource vhs)667     static void testArrayIndexOutOfBounds(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
668         VarHandle vh = vhs.s;
669         ByteBuffer array = bs.s;
670 
671         boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
672 
673         int length = array.limit() - SIZE + 1;
674         for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
675             final int ci = i;
676 
677             checkIOOBE(() -> {
678                 char x = (char) vh.get(array, ci);
679             });
680 
681             if (!readOnly) {
682                 checkIOOBE(() -> {
683                     vh.set(array, ci, VALUE_1);
684                 });
685             }
686 
687             checkIOOBE(() -> {
688                 char x = (char) vh.getVolatile(array, ci);
689             });
690 
691             checkIOOBE(() -> {
692                 char x = (char) vh.getAcquire(array, ci);
693             });
694 
695             checkIOOBE(() -> {
696                 char x = (char) vh.getOpaque(array, ci);
697             });
698 
699             if (!readOnly) {
700                 checkIOOBE(() -> {
701                     vh.setVolatile(array, ci, VALUE_1);
702                 });
703 
704                 checkIOOBE(() -> {
705                     vh.setRelease(array, ci, VALUE_1);
706                 });
707 
708                 checkIOOBE(() -> {
709                     vh.setOpaque(array, ci, VALUE_1);
710                 });
711 
712 
713 
714             }
715         }
716     }
717 
testArrayMisalignedAccess(ByteArraySource bs, VarHandleSource vhs)718     static void testArrayMisalignedAccess(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
719         VarHandle vh = vhs.s;
720         byte[] array = bs.s;
721 
722         int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
723 
724         int length = array.length - SIZE + 1;
725         for (int i = 0; i < length; i++) {
726             boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
727             final int ci = i;
728 
729             if (!iAligned) {
730                 checkISE(() -> {
731                     char x = (char) vh.getVolatile(array, ci);
732                 });
733 
734                 checkISE(() -> {
735                     char x = (char) vh.getAcquire(array, ci);
736                 });
737 
738                 checkISE(() -> {
739                     char x = (char) vh.getOpaque(array, ci);
740                 });
741 
742                 checkISE(() -> {
743                     vh.setVolatile(array, ci, VALUE_1);
744                 });
745 
746                 checkISE(() -> {
747                     vh.setRelease(array, ci, VALUE_1);
748                 });
749 
750                 checkISE(() -> {
751                     vh.setOpaque(array, ci, VALUE_1);
752                 });
753 
754 
755             }
756         }
757     }
758 
testArrayMisalignedAccess(ByteBufferSource bs, VarHandleSource vhs)759     static void testArrayMisalignedAccess(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
760         VarHandle vh = vhs.s;
761         ByteBuffer array = bs.s;
762 
763         boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
764         int misalignmentAtZero = array.alignmentOffset(0, SIZE);
765 
766         int length = array.limit() - SIZE + 1;
767         for (int i = 0; i < length; i++) {
768             boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
769             final int ci = i;
770 
771             if (!iAligned) {
772                 checkISE(() -> {
773                     char x = (char) vh.getVolatile(array, ci);
774                 });
775 
776                 checkISE(() -> {
777                     char x = (char) vh.getAcquire(array, ci);
778                 });
779 
780                 checkISE(() -> {
781                     char x = (char) vh.getOpaque(array, ci);
782                 });
783 
784                 if (!readOnly) {
785                     checkISE(() -> {
786                         vh.setVolatile(array, ci, VALUE_1);
787                     });
788 
789                     checkISE(() -> {
790                         vh.setRelease(array, ci, VALUE_1);
791                     });
792 
793                     checkISE(() -> {
794                         vh.setOpaque(array, ci, VALUE_1);
795                     });
796 
797 
798 
799                 }
800             }
801         }
802     }
803 
testArrayReadWrite(ByteArraySource bs, VarHandleSource vhs)804     static void testArrayReadWrite(ByteArraySource bs, VarHandleSource vhs) {
805         VarHandle vh = vhs.s;
806         byte[] array = bs.s;
807 
808         int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
809 
810         bs.fill((byte) 0xff);
811         int length = array.length - SIZE + 1;
812         for (int i = 0; i < length; i++) {
813             boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
814 
815             // Plain
816             {
817                 vh.set(array, i, VALUE_1);
818                 char x = (char) vh.get(array, i);
819                 assertEquals(x, VALUE_1, "get char value");
820             }
821 
822 
823             if (iAligned) {
824                 // Volatile
825                 {
826                     vh.setVolatile(array, i, VALUE_2);
827                     char x = (char) vh.getVolatile(array, i);
828                     assertEquals(x, VALUE_2, "setVolatile char value");
829                 }
830 
831                 // Lazy
832                 {
833                     vh.setRelease(array, i, VALUE_1);
834                     char x = (char) vh.getAcquire(array, i);
835                     assertEquals(x, VALUE_1, "setRelease char value");
836                 }
837 
838                 // Opaque
839                 {
840                     vh.setOpaque(array, i, VALUE_2);
841                     char x = (char) vh.getOpaque(array, i);
842                     assertEquals(x, VALUE_2, "setOpaque char value");
843                 }
844 
845 
846             }
847         }
848     }
849 
850 
testArrayReadWrite(ByteBufferSource bs, VarHandleSource vhs)851     static void testArrayReadWrite(ByteBufferSource bs, VarHandleSource vhs) {
852         VarHandle vh = vhs.s;
853         ByteBuffer array = bs.s;
854 
855         int misalignmentAtZero = array.alignmentOffset(0, SIZE);
856 
857         bs.fill((byte) 0xff);
858         int length = array.limit() - SIZE + 1;
859         for (int i = 0; i < length; i++) {
860             boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
861 
862             // Plain
863             {
864                 vh.set(array, i, VALUE_1);
865                 char x = (char) vh.get(array, i);
866                 assertEquals(x, VALUE_1, "get char value");
867             }
868 
869             if (iAligned) {
870                 // Volatile
871                 {
872                     vh.setVolatile(array, i, VALUE_2);
873                     char x = (char) vh.getVolatile(array, i);
874                     assertEquals(x, VALUE_2, "setVolatile char value");
875                 }
876 
877                 // Lazy
878                 {
879                     vh.setRelease(array, i, VALUE_1);
880                     char x = (char) vh.getAcquire(array, i);
881                     assertEquals(x, VALUE_1, "setRelease char value");
882                 }
883 
884                 // Opaque
885                 {
886                     vh.setOpaque(array, i, VALUE_2);
887                     char x = (char) vh.getOpaque(array, i);
888                     assertEquals(x, VALUE_2, "setOpaque char value");
889                 }
890 
891 
892             }
893         }
894     }
895 
testArrayReadOnly(ByteBufferSource bs, VarHandleSource vhs)896     static void testArrayReadOnly(ByteBufferSource bs, VarHandleSource vhs) {
897         VarHandle vh = vhs.s;
898         ByteBuffer array = bs.s;
899 
900         int misalignmentAtZero = array.alignmentOffset(0, SIZE);
901 
902         ByteBuffer bb = ByteBuffer.allocate(SIZE);
903         bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN);
904         bs.fill(bb.putChar(0, VALUE_2).array());
905 
906         int length = array.limit() - SIZE + 1;
907         for (int i = 0; i < length; i++) {
908             boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
909 
910             char v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes)
911                     ? rotateLeft(VALUE_2, (i % SIZE) << 3)
912                     : rotateRight(VALUE_2, (i % SIZE) << 3);
913             // Plain
914             {
915                 char x = (char) vh.get(array, i);
916                 assertEquals(x, v, "get char value");
917             }
918 
919             if (iAligned) {
920                 // Volatile
921                 {
922                     char x = (char) vh.getVolatile(array, i);
923                     assertEquals(x, v, "getVolatile char value");
924                 }
925 
926                 // Lazy
927                 {
928                     char x = (char) vh.getAcquire(array, i);
929                     assertEquals(x, v, "getRelease char value");
930                 }
931 
932                 // Opaque
933                 {
934                     char x = (char) vh.getOpaque(array, i);
935                     assertEquals(x, v, "getOpaque char value");
936                 }
937             }
938         }
939     }
940 
941 }
942 
943