1/*
2 * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/*
25 * @test
26 * @bug 8154556
27 * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsShort
28 * @run testng/othervm -Diters=20000                         VarHandleTestByteArrayAsShort
29 * @run testng/othervm -Diters=20000 -XX:-TieredCompilation  VarHandleTestByteArrayAsShort
30 */
31
32import org.testng.annotations.DataProvider;
33import org.testng.annotations.Test;
34
35import java.lang.invoke.MethodHandles;
36import java.lang.invoke.VarHandle;
37import java.nio.ByteBuffer;
38import java.nio.ByteOrder;
39import java.util.ArrayList;
40import java.util.Arrays;
41import java.util.EnumSet;
42import java.util.List;
43
44import static org.testng.Assert.*;
45
46public class VarHandleTestByteArrayAsShort extends VarHandleBaseByteArrayTest {
47    static final int SIZE = Short.BYTES;
48
49    static final short VALUE_1 = (short)0x0102;
50
51    static final short VALUE_2 = (short)0x1112;
52
53    static final short VALUE_3 = (short)0xFFFE;
54
55
56    @Override
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(short[].class, bo),
66                    endianess, MemoryMode.READ_WRITE);
67            vhss.add(aeh);
68
69            VarHandleSource bbh = new VarHandleSource(
70                    MethodHandles.byteBufferViewVarHandle(short[].class, bo),
71                    endianess, MemoryMode.READ_WRITE);
72            vhss.add(bbh);
73        }
74    }
75
76
77    @Test(dataProvider = "varHandlesProvider")
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")
119    public void testTypes(VarHandle vh, List<java.lang.Class<?>> pts) {
120        assertEquals(vh.varType(), short.class);
121
122        assertEquals(vh.coordinateTypes(), pts);
123
124        testTypes(vh);
125    }
126
127
128    @DataProvider
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                                "unsupported", bav, vh, h -> testArrayUnsupported(bas, h),
143                                false));
144                        cases.add(new VarHandleSourceAccessTestCase(
145                                "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bas, h),
146                                false));
147                        cases.add(new VarHandleSourceAccessTestCase(
148                                "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bas, h),
149                                false));
150                    }
151                    else {
152                        ByteBufferSource bbs = (ByteBufferSource) bav;
153
154                        if (MemoryMode.READ_WRITE.isSet(bav.memoryModes)) {
155                            cases.add(new VarHandleSourceAccessTestCase(
156                                    "read write", bav, vh, h -> testArrayReadWrite(bbs, h),
157                                    true));
158                        }
159                        else {
160                            cases.add(new VarHandleSourceAccessTestCase(
161                                    "read only", bav, vh, h -> testArrayReadOnly(bbs, h),
162                                    true));
163                        }
164
165                        cases.add(new VarHandleSourceAccessTestCase(
166                                "unsupported", bav, vh, h -> testArrayUnsupported(bbs, h),
167                                false));
168                        cases.add(new VarHandleSourceAccessTestCase(
169                                "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bbs, h),
170                                false));
171                        cases.add(new VarHandleSourceAccessTestCase(
172                                "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bbs, h),
173                                false));
174                    }
175                }
176            }
177        }
178
179        // Work around issue with jtreg summary reporting which truncates
180        // the String result of Object.toString to 30 characters, hence
181        // the first dummy argument
182        return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
183    }
184
185    @Test(dataProvider = "accessTestCaseProvider")
186    public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
187        T t = atc.get();
188        int iters = atc.requiresLoop() ? ITERS : 1;
189        for (int c = 0; c < iters; c++) {
190            atc.testAccess(t);
191        }
192    }
193
194
195    static void testArrayUnsupported(ByteArraySource bs, VarHandleSource vhs) {
196        VarHandle vh = vhs.s;
197        byte[] array = bs.s;
198        int ci = 1;
199
200        checkUOE(() -> {
201            boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
202        });
203
204        checkUOE(() -> {
205            short r = (short) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
206        });
207
208        checkUOE(() -> {
209            short r = (short) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
210        });
211
212        checkUOE(() -> {
213            short r = (short) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
214        });
215
216        checkUOE(() -> {
217            boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
218        });
219
220        checkUOE(() -> {
221            boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
222        });
223
224        checkUOE(() -> {
225            boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
226        });
227
228        checkUOE(() -> {
229            boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
230        });
231
232        checkUOE(() -> {
233            short o = (short) vh.getAndSet(array, ci, VALUE_1);
234        });
235
236        checkUOE(() -> {
237            short o = (short) vh.getAndSetAcquire(array, ci, VALUE_1);
238        });
239
240        checkUOE(() -> {
241            short o = (short) vh.getAndSetRelease(array, ci, VALUE_1);
242        });
243
244        checkUOE(() -> {
245            short o = (short) vh.getAndAdd(array, ci, VALUE_1);
246        });
247
248        checkUOE(() -> {
249            short o = (short) vh.getAndAddAcquire(array, ci, VALUE_1);
250        });
251
252        checkUOE(() -> {
253            short o = (short) vh.getAndAddRelease(array, ci, VALUE_1);
254        });
255
256        checkUOE(() -> {
257            short o = (short) vh.getAndBitwiseOr(array, ci, VALUE_1);
258        });
259
260        checkUOE(() -> {
261            short o = (short) vh.getAndBitwiseOrAcquire(array, ci, VALUE_1);
262        });
263
264        checkUOE(() -> {
265            short o = (short) vh.getAndBitwiseOrRelease(array, ci, VALUE_1);
266        });
267
268        checkUOE(() -> {
269            short o = (short) vh.getAndBitwiseAnd(array, ci, VALUE_1);
270        });
271
272        checkUOE(() -> {
273            short o = (short) vh.getAndBitwiseAndAcquire(array, ci, VALUE_1);
274        });
275
276        checkUOE(() -> {
277            short o = (short) vh.getAndBitwiseAndRelease(array, ci, VALUE_1);
278        });
279
280        checkUOE(() -> {
281            short o = (short) vh.getAndBitwiseXor(array, ci, VALUE_1);
282        });
283
284        checkUOE(() -> {
285            short o = (short) vh.getAndBitwiseXorAcquire(array, ci, VALUE_1);
286        });
287
288        checkUOE(() -> {
289            short o = (short) vh.getAndBitwiseXorRelease(array, ci, VALUE_1);
290        });
291    }
292
293    static void testArrayUnsupported(ByteBufferSource bs, VarHandleSource vhs) {
294        VarHandle vh = vhs.s;
295        ByteBuffer array = bs.s;
296        int ci = 0;
297        boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
298
299        if (readOnly) {
300            checkROBE(() -> {
301                vh.set(array, ci, VALUE_1);
302            });
303        }
304
305        if (readOnly) {
306            checkROBE(() -> {
307                vh.setVolatile(array, ci, VALUE_1);
308            });
309
310            checkROBE(() -> {
311                vh.setRelease(array, ci, VALUE_1);
312            });
313
314            checkROBE(() -> {
315                vh.setOpaque(array, ci, VALUE_1);
316            });
317            checkUOE(() -> {
318                boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
319            });
320
321            checkUOE(() -> {
322                short r = (short) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
323            });
324
325            checkUOE(() -> {
326                short r = (short) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
327            });
328
329            checkUOE(() -> {
330                short r = (short) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
331            });
332
333            checkUOE(() -> {
334                boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
335            });
336
337            checkUOE(() -> {
338                boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
339            });
340
341            checkUOE(() -> {
342                boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
343            });
344
345            checkUOE(() -> {
346                boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
347            });
348
349            checkUOE(() -> {
350                short o = (short) vh.getAndSet(array, ci, VALUE_1);
351            });
352
353            checkUOE(() -> {
354                short o = (short) vh.getAndSetAcquire(array, ci, VALUE_1);
355            });
356
357            checkUOE(() -> {
358                short o = (short) vh.getAndSetRelease(array, ci, VALUE_1);
359            });
360
361            checkUOE(() -> {
362                short o = (short) vh.getAndAdd(array, ci, VALUE_1);
363            });
364
365            checkUOE(() -> {
366                short o = (short) vh.getAndAddAcquire(array, ci, VALUE_1);
367            });
368
369            checkUOE(() -> {
370                short o = (short) vh.getAndAddRelease(array, ci, VALUE_1);
371            });
372
373            checkUOE(() -> {
374                short o = (short) vh.getAndBitwiseOr(array, ci, VALUE_1);
375            });
376
377            checkUOE(() -> {
378                short o = (short) vh.getAndBitwiseOrAcquire(array, ci, VALUE_1);
379            });
380
381            checkUOE(() -> {
382                short o = (short) vh.getAndBitwiseOrRelease(array, ci, VALUE_1);
383            });
384
385            checkUOE(() -> {
386                short o = (short) vh.getAndBitwiseAnd(array, ci, VALUE_1);
387            });
388
389            checkUOE(() -> {
390                short o = (short) vh.getAndBitwiseAndAcquire(array, ci, VALUE_1);
391            });
392
393            checkUOE(() -> {
394                short o = (short) vh.getAndBitwiseAndRelease(array, ci, VALUE_1);
395            });
396
397            checkUOE(() -> {
398                short o = (short) vh.getAndBitwiseXor(array, ci, VALUE_1);
399            });
400
401            checkUOE(() -> {
402                short o = (short) vh.getAndBitwiseXorAcquire(array, ci, VALUE_1);
403            });
404
405            checkUOE(() -> {
406                short o = (short) vh.getAndBitwiseXorRelease(array, ci, VALUE_1);
407            });
408        }
409        else {
410            checkUOE(() -> {
411                boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
412            });
413
414            checkUOE(() -> {
415                short r = (short) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
416            });
417
418            checkUOE(() -> {
419                short r = (short) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
420            });
421
422            checkUOE(() -> {
423                short r = (short) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
424            });
425
426            checkUOE(() -> {
427                boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
428            });
429
430            checkUOE(() -> {
431                boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
432            });
433
434            checkUOE(() -> {
435                boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
436            });
437
438            checkUOE(() -> {
439                boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
440            });
441
442            checkUOE(() -> {
443                short o = (short) vh.getAndSet(array, ci, VALUE_1);
444            });
445
446            checkUOE(() -> {
447                short o = (short) vh.getAndSetAcquire(array, ci, VALUE_1);
448            });
449
450            checkUOE(() -> {
451                short o = (short) vh.getAndSetRelease(array, ci, VALUE_1);
452            });
453            checkUOE(() -> {
454                short o = (short) vh.getAndAdd(array, ci, VALUE_1);
455            });
456
457            checkUOE(() -> {
458                short o = (short) vh.getAndAddAcquire(array, ci, VALUE_1);
459            });
460
461            checkUOE(() -> {
462                short o = (short) vh.getAndAddRelease(array, ci, VALUE_1);
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    }
501
502
503    static void testArrayIndexOutOfBounds(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
504        VarHandle vh = vhs.s;
505        byte[] array = bs.s;
506
507        int length = array.length - SIZE + 1;
508        for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
509            final int ci = i;
510
511            checkIOOBE(() -> {
512                short x = (short) vh.get(array, ci);
513            });
514
515            checkIOOBE(() -> {
516                vh.set(array, ci, VALUE_1);
517            });
518
519            checkIOOBE(() -> {
520                short x = (short) vh.getVolatile(array, ci);
521            });
522
523            checkIOOBE(() -> {
524                short x = (short) vh.getAcquire(array, ci);
525            });
526
527            checkIOOBE(() -> {
528                short x = (short) vh.getOpaque(array, ci);
529            });
530
531            checkIOOBE(() -> {
532                vh.setVolatile(array, ci, VALUE_1);
533            });
534
535            checkIOOBE(() -> {
536                vh.setRelease(array, ci, VALUE_1);
537            });
538
539            checkIOOBE(() -> {
540                vh.setOpaque(array, ci, VALUE_1);
541            });
542
543
544
545        }
546    }
547
548    static void testArrayIndexOutOfBounds(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
549        VarHandle vh = vhs.s;
550        ByteBuffer array = bs.s;
551
552        boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
553
554        int length = array.limit() - SIZE + 1;
555        for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
556            final int ci = i;
557
558            checkIOOBE(() -> {
559                short x = (short) vh.get(array, ci);
560            });
561
562            if (!readOnly) {
563                checkIOOBE(() -> {
564                    vh.set(array, ci, VALUE_1);
565                });
566            }
567
568            checkIOOBE(() -> {
569                short x = (short) vh.getVolatile(array, ci);
570            });
571
572            checkIOOBE(() -> {
573                short x = (short) vh.getAcquire(array, ci);
574            });
575
576            checkIOOBE(() -> {
577                short x = (short) vh.getOpaque(array, ci);
578            });
579
580            if (!readOnly) {
581                checkIOOBE(() -> {
582                    vh.setVolatile(array, ci, VALUE_1);
583                });
584
585                checkIOOBE(() -> {
586                    vh.setRelease(array, ci, VALUE_1);
587                });
588
589                checkIOOBE(() -> {
590                    vh.setOpaque(array, ci, VALUE_1);
591                });
592
593
594
595            }
596        }
597    }
598
599    static void testArrayMisalignedAccess(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
600        VarHandle vh = vhs.s;
601        byte[] array = bs.s;
602
603        int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
604
605        int length = array.length - SIZE + 1;
606        for (int i = 0; i < length; i++) {
607            boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
608            final int ci = i;
609
610            if (!iAligned) {
611                checkISE(() -> {
612                    short x = (short) vh.getVolatile(array, ci);
613                });
614
615                checkISE(() -> {
616                    short x = (short) vh.getAcquire(array, ci);
617                });
618
619                checkISE(() -> {
620                    short x = (short) vh.getOpaque(array, ci);
621                });
622
623                checkISE(() -> {
624                    vh.setVolatile(array, ci, VALUE_1);
625                });
626
627                checkISE(() -> {
628                    vh.setRelease(array, ci, VALUE_1);
629                });
630
631                checkISE(() -> {
632                    vh.setOpaque(array, ci, VALUE_1);
633                });
634
635
636            }
637        }
638    }
639
640    static void testArrayMisalignedAccess(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
641        VarHandle vh = vhs.s;
642        ByteBuffer array = bs.s;
643
644        boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
645        int misalignmentAtZero = array.alignmentOffset(0, SIZE);
646
647        int length = array.limit() - SIZE + 1;
648        for (int i = 0; i < length; i++) {
649            boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
650            final int ci = i;
651
652            if (!iAligned) {
653                checkISE(() -> {
654                    short x = (short) vh.getVolatile(array, ci);
655                });
656
657                checkISE(() -> {
658                    short x = (short) vh.getAcquire(array, ci);
659                });
660
661                checkISE(() -> {
662                    short x = (short) vh.getOpaque(array, ci);
663                });
664
665                if (!readOnly) {
666                    checkISE(() -> {
667                        vh.setVolatile(array, ci, VALUE_1);
668                    });
669
670                    checkISE(() -> {
671                        vh.setRelease(array, ci, VALUE_1);
672                    });
673
674                    checkISE(() -> {
675                        vh.setOpaque(array, ci, VALUE_1);
676                    });
677
678
679
680                }
681            }
682        }
683    }
684
685    static void testArrayReadWrite(ByteArraySource bs, VarHandleSource vhs) {
686        VarHandle vh = vhs.s;
687        byte[] array = bs.s;
688
689        int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
690
691        bs.fill((byte) 0xff);
692        int length = array.length - SIZE + 1;
693        for (int i = 0; i < length; i++) {
694            boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
695
696            // Plain
697            {
698                vh.set(array, i, VALUE_1);
699                short x = (short) vh.get(array, i);
700                assertEquals(x, VALUE_1, "get short value");
701            }
702
703
704            if (iAligned) {
705                // Volatile
706                {
707                    vh.setVolatile(array, i, VALUE_2);
708                    short x = (short) vh.getVolatile(array, i);
709                    assertEquals(x, VALUE_2, "setVolatile short value");
710                }
711
712                // Lazy
713                {
714                    vh.setRelease(array, i, VALUE_1);
715                    short x = (short) vh.getAcquire(array, i);
716                    assertEquals(x, VALUE_1, "setRelease short value");
717                }
718
719                // Opaque
720                {
721                    vh.setOpaque(array, i, VALUE_2);
722                    short x = (short) vh.getOpaque(array, i);
723                    assertEquals(x, VALUE_2, "setOpaque short value");
724                }
725
726
727            }
728        }
729    }
730
731
732    static void testArrayReadWrite(ByteBufferSource bs, VarHandleSource vhs) {
733        VarHandle vh = vhs.s;
734        ByteBuffer array = bs.s;
735
736        int misalignmentAtZero = array.alignmentOffset(0, SIZE);
737
738        bs.fill((byte) 0xff);
739        int length = array.limit() - SIZE + 1;
740        for (int i = 0; i < length; i++) {
741            boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
742
743            // Plain
744            {
745                vh.set(array, i, VALUE_1);
746                short x = (short) vh.get(array, i);
747                assertEquals(x, VALUE_1, "get short value");
748            }
749
750            if (iAligned) {
751                // Volatile
752                {
753                    vh.setVolatile(array, i, VALUE_2);
754                    short x = (short) vh.getVolatile(array, i);
755                    assertEquals(x, VALUE_2, "setVolatile short value");
756                }
757
758                // Lazy
759                {
760                    vh.setRelease(array, i, VALUE_1);
761                    short x = (short) vh.getAcquire(array, i);
762                    assertEquals(x, VALUE_1, "setRelease short value");
763                }
764
765                // Opaque
766                {
767                    vh.setOpaque(array, i, VALUE_2);
768                    short x = (short) vh.getOpaque(array, i);
769                    assertEquals(x, VALUE_2, "setOpaque short value");
770                }
771
772
773            }
774        }
775    }
776
777    static void testArrayReadOnly(ByteBufferSource bs, VarHandleSource vhs) {
778        VarHandle vh = vhs.s;
779        ByteBuffer array = bs.s;
780
781        int misalignmentAtZero = array.alignmentOffset(0, SIZE);
782
783        ByteBuffer bb = ByteBuffer.allocate(SIZE);
784        bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN);
785        bs.fill(bb.putShort(0, VALUE_2).array());
786
787        int length = array.limit() - SIZE + 1;
788        for (int i = 0; i < length; i++) {
789            boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
790
791            short v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes)
792                    ? rotateLeft(VALUE_2, (i % SIZE) << 3)
793                    : rotateRight(VALUE_2, (i % SIZE) << 3);
794            // Plain
795            {
796                short x = (short) vh.get(array, i);
797                assertEquals(x, v, "get short value");
798            }
799
800            if (iAligned) {
801                // Volatile
802                {
803                    short x = (short) vh.getVolatile(array, i);
804                    assertEquals(x, v, "getVolatile short value");
805                }
806
807                // Lazy
808                {
809                    short x = (short) vh.getAcquire(array, i);
810                    assertEquals(x, v, "getRelease short value");
811                }
812
813                // Opaque
814                {
815                    short x = (short) vh.getOpaque(array, i);
816                    assertEquals(x, v, "getOpaque short value");
817                }
818            }
819        }
820    }
821
822}
823
824