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