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