X-VarHandleTestByteArrayView.java.template revision 14347:6929d396c267
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 VarHandleTestByteArrayAs$Type$
28 * @run testng/othervm -Diters=20000                         VarHandleTestByteArrayAs$Type$
29 * @run testng/othervm -Diters=20000 -XX:-TieredCompilation  VarHandleTestByteArrayAs$Type$
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 VarHandleTestByteArrayAs$Type$ extends VarHandleBaseByteArrayTest {
47    static final int SIZE = $BoxType$.BYTES;
48
49    static final $type$ VALUE_1 = $value1$;
50
51    static final $type$ VALUE_2 = $value2$;
52
53    static final $type$ VALUE_3 = $value3$;
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($type$[].class, bo),
66                    endianess, MemoryMode.READ_WRITE);
67            vhss.add(aeh);
68
69            VarHandleSource bbh = new VarHandleSource(
70                    MethodHandles.byteBufferViewVarHandle($type$[].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#if[CAS]
92        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_SET));
93        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_VOLATILE));
94        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
95        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
96        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
97        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE));
98        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
99        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
100        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
101#else[CAS]
102        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_SET));
103        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_VOLATILE));
104        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
105        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
106        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
107        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE));
108        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
109        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
110        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
111#end[CAS]
112
113#if[AtomicAdd]
114        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
115        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.ADD_AND_GET));
116#else[AtomicAdd]
117        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
118        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.ADD_AND_GET));
119#end[AtomicAdd]
120    }
121
122    @Test(dataProvider = "typesProvider")
123    public void testTypes(VarHandle vh, List<java.lang.Class<?>> pts) {
124        assertEquals(vh.varType(), $type$.class);
125
126        assertEquals(vh.coordinateTypes(), pts);
127
128        testTypes(vh);
129    }
130
131
132    @DataProvider
133    public Object[][] accessTestCaseProvider() throws Exception {
134        List<AccessTestCase<?>> cases = new ArrayList<>();
135
136        for (ByteArrayViewSource<?> bav : bavss) {
137            for (VarHandleSource vh : vhss) {
138                if (vh.matches(bav)) {
139                    if (bav instanceof ByteArraySource) {
140                        ByteArraySource bas = (ByteArraySource) bav;
141
142                        cases.add(new VarHandleSourceAccessTestCase(
143                                "read write", bav, vh, h -> testArrayReadWrite(bas, h),
144                                true));
145                        cases.add(new VarHandleSourceAccessTestCase(
146                                "unsupported", bav, vh, h -> testArrayUnsupported(bas, h),
147                                false));
148                        cases.add(new VarHandleSourceAccessTestCase(
149                                "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bas, h),
150                                false));
151                        cases.add(new VarHandleSourceAccessTestCase(
152                                "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bas, h),
153                                false));
154                    }
155                    else {
156                        ByteBufferSource bbs = (ByteBufferSource) bav;
157
158                        if (MemoryMode.READ_WRITE.isSet(bav.memoryModes)) {
159                            cases.add(new VarHandleSourceAccessTestCase(
160                                    "read write", bav, vh, h -> testArrayReadWrite(bbs, h),
161                                    true));
162                        }
163                        else {
164                            cases.add(new VarHandleSourceAccessTestCase(
165                                    "read only", bav, vh, h -> testArrayReadOnly(bbs, h),
166                                    true));
167                        }
168
169                        cases.add(new VarHandleSourceAccessTestCase(
170                                "unsupported", bav, vh, h -> testArrayUnsupported(bbs, h),
171                                false));
172                        cases.add(new VarHandleSourceAccessTestCase(
173                                "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bbs, h),
174                                false));
175                        cases.add(new VarHandleSourceAccessTestCase(
176                                "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bbs, h),
177                                false));
178                    }
179                }
180            }
181        }
182
183        // Work around issue with jtreg summary reporting which truncates
184        // the String result of Object.toString to 30 characters, hence
185        // the first dummy argument
186        return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
187    }
188
189    @Test(dataProvider = "accessTestCaseProvider")
190    public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
191        T t = atc.get();
192        int iters = atc.requiresLoop() ? ITERS : 1;
193        for (int c = 0; c < iters; c++) {
194            atc.testAccess(t);
195        }
196    }
197
198
199    static void testArrayUnsupported(ByteArraySource bs, VarHandleSource vhs) {
200        VarHandle vh = vhs.s;
201        byte[] array = bs.s;
202        int ci = 1;
203
204#if[!CAS]
205        checkUOE(() -> {
206            boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
207        });
208
209        checkUOE(() -> {
210            $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
211        });
212
213        checkUOE(() -> {
214            $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
215        });
216
217        checkUOE(() -> {
218            $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
219        });
220
221        checkUOE(() -> {
222            boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
223        });
224
225        checkUOE(() -> {
226            boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
227        });
228
229        checkUOE(() -> {
230            boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
231        });
232
233        checkUOE(() -> {
234            boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
235        });
236
237        checkUOE(() -> {
238            $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
239        });
240#end[CAS]
241
242#if[!AtomicAdd]
243        checkUOE(() -> {
244            $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
245        });
246
247        checkUOE(() -> {
248            $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1);
249        });
250#end[AtomicAdd]
251    }
252
253    static void testArrayUnsupported(ByteBufferSource bs, VarHandleSource vhs) {
254        VarHandle vh = vhs.s;
255        ByteBuffer array = bs.s;
256        int ci = 0;
257        boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
258
259        if (readOnly) {
260            checkROBE(() -> {
261                vh.set(array, ci, VALUE_1);
262            });
263        }
264
265        if (readOnly) {
266            checkROBE(() -> {
267                vh.setVolatile(array, ci, VALUE_1);
268            });
269
270            checkROBE(() -> {
271                vh.setRelease(array, ci, VALUE_1);
272            });
273
274            checkROBE(() -> {
275                vh.setOpaque(array, ci, VALUE_1);
276            });
277#if[CAS]
278
279            checkROBE(() -> {
280                boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
281            });
282
283            checkROBE(() -> {
284                $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
285            });
286
287            checkROBE(() -> {
288                $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
289            });
290
291            checkROBE(() -> {
292                $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
293            });
294
295            checkROBE(() -> {
296                boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
297            });
298
299            checkROBE(() -> {
300                boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
301            });
302
303            checkROBE(() -> {
304                boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
305            });
306
307            checkROBE(() -> {
308                boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
309            });
310
311            checkROBE(() -> {
312                $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
313            });
314            checkUOE(() -> {
315                boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
316            });
317#else[CAS]
318            checkUOE(() -> {
319                $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
320            });
321
322            checkUOE(() -> {
323                $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
324            });
325
326            checkUOE(() -> {
327                $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
328            });
329
330            checkUOE(() -> {
331                boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
332            });
333
334            checkUOE(() -> {
335                boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
336            });
337
338            checkUOE(() -> {
339                boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
340            });
341
342            checkUOE(() -> {
343                boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
344            });
345
346            checkUOE(() -> {
347                $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
348            });
349#end[CAS]
350
351#if[AtomicAdd]
352            checkROBE(() -> {
353                $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
354            });
355
356            checkROBE(() -> {
357                $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1);
358            });
359#else[AtomicAdd]
360            checkUOE(() -> {
361                $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
362            });
363
364            checkUOE(() -> {
365                $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1);
366            });
367#end[AtomicAdd]
368        }
369        else {
370#if[!CAS]
371            checkUOE(() -> {
372                boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
373            });
374
375            checkUOE(() -> {
376                $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
377            });
378
379            checkUOE(() -> {
380                $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
381            });
382
383            checkUOE(() -> {
384                $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
385            });
386
387            checkUOE(() -> {
388                boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
389            });
390
391            checkUOE(() -> {
392                boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
393            });
394
395            checkUOE(() -> {
396                boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
397            });
398
399            checkUOE(() -> {
400                boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
401            });
402
403            checkUOE(() -> {
404                $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
405            });
406#end[CAS]
407#if[!AtomicAdd]
408            checkUOE(() -> {
409                $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
410            });
411
412            checkUOE(() -> {
413                $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1);
414            });
415#end[AtomicAdd]
416        }
417    }
418
419
420    static void testArrayIndexOutOfBounds(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
421        VarHandle vh = vhs.s;
422        byte[] array = bs.s;
423
424        int length = array.length - SIZE + 1;
425        for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
426            final int ci = i;
427
428            checkIOOBE(() -> {
429                $type$ x = ($type$) vh.get(array, ci);
430            });
431
432            checkIOOBE(() -> {
433                vh.set(array, ci, VALUE_1);
434            });
435
436            checkIOOBE(() -> {
437                $type$ x = ($type$) vh.getVolatile(array, ci);
438            });
439
440            checkIOOBE(() -> {
441                $type$ x = ($type$) vh.getAcquire(array, ci);
442            });
443
444            checkIOOBE(() -> {
445                $type$ x = ($type$) vh.getOpaque(array, ci);
446            });
447
448            checkIOOBE(() -> {
449                vh.setVolatile(array, ci, VALUE_1);
450            });
451
452            checkIOOBE(() -> {
453                vh.setRelease(array, ci, VALUE_1);
454            });
455
456            checkIOOBE(() -> {
457                vh.setOpaque(array, ci, VALUE_1);
458            });
459#if[CAS]
460
461            checkIOOBE(() -> {
462                boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
463            });
464
465            checkIOOBE(() -> {
466                $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
467            });
468
469            checkIOOBE(() -> {
470                $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
471            });
472
473            checkIOOBE(() -> {
474                $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
475            });
476
477            checkIOOBE(() -> {
478                boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
479            });
480
481            checkIOOBE(() -> {
482                boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
483            });
484
485            checkIOOBE(() -> {
486                boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
487            });
488
489            checkIOOBE(() -> {
490                boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
491            });
492
493            checkIOOBE(() -> {
494                $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
495            });
496#end[CAS]
497
498#if[AtomicAdd]
499            checkIOOBE(() -> {
500                $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
501            });
502
503            checkIOOBE(() -> {
504                $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1);
505            });
506#end[AtomicAdd]
507
508        }
509    }
510
511    static void testArrayIndexOutOfBounds(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
512        VarHandle vh = vhs.s;
513        ByteBuffer array = bs.s;
514
515        boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
516
517        int length = array.limit() - SIZE + 1;
518        for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
519            final int ci = i;
520
521            checkIOOBE(() -> {
522                $type$ x = ($type$) vh.get(array, ci);
523            });
524
525            if (!readOnly) {
526                checkIOOBE(() -> {
527                    vh.set(array, ci, VALUE_1);
528                });
529            }
530
531            checkIOOBE(() -> {
532                $type$ x = ($type$) vh.getVolatile(array, ci);
533            });
534
535            checkIOOBE(() -> {
536                $type$ x = ($type$) vh.getAcquire(array, ci);
537            });
538
539            checkIOOBE(() -> {
540                $type$ x = ($type$) vh.getOpaque(array, ci);
541            });
542
543            if (!readOnly) {
544                checkIOOBE(() -> {
545                    vh.setVolatile(array, ci, VALUE_1);
546                });
547
548                checkIOOBE(() -> {
549                    vh.setRelease(array, ci, VALUE_1);
550                });
551
552                checkIOOBE(() -> {
553                    vh.setOpaque(array, ci, VALUE_1);
554                });
555
556#if[CAS]
557                checkIOOBE(() -> {
558                    boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
559                });
560
561                checkIOOBE(() -> {
562                    $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
563                });
564
565                checkIOOBE(() -> {
566                    $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
567                });
568
569                checkIOOBE(() -> {
570                    $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
571                });
572
573                checkIOOBE(() -> {
574                    boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
575                });
576
577                checkIOOBE(() -> {
578                    boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
579                });
580
581                checkIOOBE(() -> {
582                    boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
583                });
584
585                checkIOOBE(() -> {
586                    boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
587                });
588
589                checkIOOBE(() -> {
590                    $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
591                });
592#end[CAS]
593
594#if[AtomicAdd]
595                checkIOOBE(() -> {
596                    $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
597                });
598
599                checkIOOBE(() -> {
600                    $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1);
601                });
602#end[AtomicAdd]
603            }
604        }
605    }
606
607    static void testArrayMisalignedAccess(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
608        VarHandle vh = vhs.s;
609        byte[] array = bs.s;
610
611        int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
612
613        int length = array.length - SIZE + 1;
614        for (int i = 0; i < length; i++) {
615            boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
616            final int ci = i;
617
618            if (!iAligned) {
619                checkISE(() -> {
620                    $type$ x = ($type$) vh.getVolatile(array, ci);
621                });
622
623                checkISE(() -> {
624                    $type$ x = ($type$) vh.getAcquire(array, ci);
625                });
626
627                checkISE(() -> {
628                    $type$ x = ($type$) vh.getOpaque(array, ci);
629                });
630
631                checkISE(() -> {
632                    vh.setVolatile(array, ci, VALUE_1);
633                });
634
635                checkISE(() -> {
636                    vh.setRelease(array, ci, VALUE_1);
637                });
638
639                checkISE(() -> {
640                    vh.setOpaque(array, ci, VALUE_1);
641                });
642#if[CAS]
643
644                checkISE(() -> {
645                    boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
646                });
647
648                checkISE(() -> {
649                    $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
650                });
651
652                checkISE(() -> {
653                    $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
654                });
655
656                checkISE(() -> {
657                    $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
658                });
659
660                checkISE(() -> {
661                    boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
662                });
663
664                checkISE(() -> {
665                    boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
666                });
667
668                checkISE(() -> {
669                    boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
670                });
671
672                checkISE(() -> {
673                    boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
674                });
675
676                checkISE(() -> {
677                    $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
678                });
679#end[CAS]
680
681#if[AtomicAdd]
682                checkISE(() -> {
683                    $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
684                });
685
686                checkISE(() -> {
687                    $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1);
688                });
689#end[AtomicAdd]
690
691            }
692        }
693    }
694
695    static void testArrayMisalignedAccess(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
696        VarHandle vh = vhs.s;
697        ByteBuffer array = bs.s;
698
699        boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
700        int misalignmentAtZero = array.alignmentOffset(0, SIZE);
701
702        int length = array.limit() - SIZE + 1;
703        for (int i = 0; i < length; i++) {
704            boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
705            final int ci = i;
706
707            if (!iAligned) {
708                checkISE(() -> {
709                    $type$ x = ($type$) vh.getVolatile(array, ci);
710                });
711
712                checkISE(() -> {
713                    $type$ x = ($type$) vh.getAcquire(array, ci);
714                });
715
716                checkISE(() -> {
717                    $type$ x = ($type$) vh.getOpaque(array, ci);
718                });
719
720                if (!readOnly) {
721                    checkISE(() -> {
722                        vh.setVolatile(array, ci, VALUE_1);
723                    });
724
725                    checkISE(() -> {
726                        vh.setRelease(array, ci, VALUE_1);
727                    });
728
729                    checkISE(() -> {
730                        vh.setOpaque(array, ci, VALUE_1);
731                    });
732
733#if[CAS]
734                    checkISE(() -> {
735                        boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
736                    });
737
738                    checkISE(() -> {
739                        $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
740                    });
741
742                    checkISE(() -> {
743                        $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
744                    });
745
746                    checkISE(() -> {
747                        $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
748                    });
749
750                    checkISE(() -> {
751                        boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
752                    });
753
754                    checkISE(() -> {
755                        boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
756                    });
757
758                    checkISE(() -> {
759                        boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
760                    });
761
762                    checkISE(() -> {
763                        boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
764                    });
765
766                    checkISE(() -> {
767                        $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
768                    });
769#end[CAS]
770
771#if[AtomicAdd]
772                    checkISE(() -> {
773                        $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
774                    });
775
776                    checkISE(() -> {
777                        $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1);
778                    });
779#end[AtomicAdd]
780                }
781            }
782        }
783    }
784
785    static void testArrayReadWrite(ByteArraySource bs, VarHandleSource vhs) {
786        VarHandle vh = vhs.s;
787        byte[] array = bs.s;
788
789        int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
790
791        bs.fill((byte) 0xff);
792        int length = array.length - SIZE + 1;
793        for (int i = 0; i < length; i++) {
794            boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
795
796            // Plain
797            {
798                vh.set(array, i, VALUE_1);
799                $type$ x = ($type$) vh.get(array, i);
800                assertEquals(x, VALUE_1, "get $type$ value");
801            }
802
803
804            if (iAligned) {
805                // Volatile
806                {
807                    vh.setVolatile(array, i, VALUE_2);
808                    $type$ x = ($type$) vh.getVolatile(array, i);
809                    assertEquals(x, VALUE_2, "setVolatile $type$ value");
810                }
811
812                // Lazy
813                {
814                    vh.setRelease(array, i, VALUE_1);
815                    $type$ x = ($type$) vh.getAcquire(array, i);
816                    assertEquals(x, VALUE_1, "setRelease $type$ value");
817                }
818
819                // Opaque
820                {
821                    vh.setOpaque(array, i, VALUE_2);
822                    $type$ x = ($type$) vh.getOpaque(array, i);
823                    assertEquals(x, VALUE_2, "setOpaque $type$ value");
824                }
825#if[CAS]
826
827                vh.set(array, i, VALUE_1);
828
829                // Compare
830                {
831                    boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2);
832                    assertEquals(r, true, "success compareAndSet $type$");
833                    $type$ x = ($type$) vh.get(array, i);
834                    assertEquals(x, VALUE_2, "success compareAndSet $type$ value");
835                }
836
837                {
838                    boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3);
839                    assertEquals(r, false, "failing compareAndSet $type$");
840                    $type$ x = ($type$) vh.get(array, i);
841                    assertEquals(x, VALUE_2, "failing compareAndSet $type$ value");
842                }
843
844                {
845                    $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1);
846                    assertEquals(r, VALUE_2, "success compareAndExchangeVolatile $type$");
847                    $type$ x = ($type$) vh.get(array, i);
848                    assertEquals(x, VALUE_1, "success compareAndExchangeVolatile $type$ value");
849                }
850
851                {
852                    $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3);
853                    assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile $type$");
854                    $type$ x = ($type$) vh.get(array, i);
855                    assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile $type$ value");
856                }
857
858                {
859                    $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2);
860                    assertEquals(r, VALUE_1, "success compareAndExchangeAcquire $type$");
861                    $type$ x = ($type$) vh.get(array, i);
862                    assertEquals(x, VALUE_2, "success compareAndExchangeAcquire $type$ value");
863                }
864
865                {
866                    $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3);
867                    assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire $type$");
868                    $type$ x = ($type$) vh.get(array, i);
869                    assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire $type$ value");
870                }
871
872                {
873                    $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1);
874                    assertEquals(r, VALUE_2, "success compareAndExchangeRelease $type$");
875                    $type$ x = ($type$) vh.get(array, i);
876                    assertEquals(x, VALUE_1, "success compareAndExchangeRelease $type$ value");
877                }
878
879                {
880                    $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3);
881                    assertEquals(r, VALUE_1, "failing compareAndExchangeRelease $type$");
882                    $type$ x = ($type$) vh.get(array, i);
883                    assertEquals(x, VALUE_1, "failing compareAndExchangeRelease $type$ value");
884                }
885
886                {
887                    boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2);
888                    assertEquals(r, true, "weakCompareAndSet $type$");
889                    $type$ x = ($type$) vh.get(array, i);
890                    assertEquals(x, VALUE_2, "weakCompareAndSet $type$ value");
891                }
892
893                {
894                    boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1);
895                    assertEquals(r, true, "weakCompareAndSetAcquire $type$");
896                    $type$ x = ($type$) vh.get(array, i);
897                    assertEquals(x, VALUE_1, "weakCompareAndSetAcquire $type$");
898                }
899
900                {
901                    boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2);
902                    assertEquals(r, true, "weakCompareAndSetRelease $type$");
903                    $type$ x = ($type$) vh.get(array, i);
904                    assertEquals(x, VALUE_2, "weakCompareAndSetRelease $type$");
905                }
906
907                {
908                    boolean r = vh.weakCompareAndSetVolatile(array, i, VALUE_2, VALUE_1);
909                    assertEquals(r, true, "weakCompareAndSetVolatile $type$");
910                    $type$ x = ($type$) vh.get(array, i);
911                    assertEquals(x, VALUE_1, "weakCompareAndSetVolatile $type$ value");
912                }
913
914                // Compare set and get
915                {
916                    $type$ o = ($type$) vh.getAndSet(array, i, VALUE_2);
917                    assertEquals(o, VALUE_1, "getAndSet $type$");
918                    $type$ x = ($type$) vh.get(array, i);
919                    assertEquals(x, VALUE_2, "getAndSet $type$ value");
920                }
921#end[CAS]
922
923#if[AtomicAdd]
924                vh.set(array, i, VALUE_1);
925
926                // get and add, add and get
927                {
928                    $type$ o = ($type$) vh.getAndAdd(array, i, VALUE_3);
929                    assertEquals(o, VALUE_1, "getAndAdd $type$");
930                    $type$ c = ($type$) vh.addAndGet(array, i, VALUE_3);
931                    assertEquals(c, VALUE_1 + VALUE_3 + VALUE_3, "getAndAdd $type$ value");
932                }
933#end[AtomicAdd]
934            }
935        }
936    }
937
938
939    static void testArrayReadWrite(ByteBufferSource bs, VarHandleSource vhs) {
940        VarHandle vh = vhs.s;
941        ByteBuffer array = bs.s;
942
943        int misalignmentAtZero = array.alignmentOffset(0, SIZE);
944
945        bs.fill((byte) 0xff);
946        int length = array.limit() - SIZE + 1;
947        for (int i = 0; i < length; i++) {
948            boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
949
950            // Plain
951            {
952                vh.set(array, i, VALUE_1);
953                $type$ x = ($type$) vh.get(array, i);
954                assertEquals(x, VALUE_1, "get $type$ value");
955            }
956
957            if (iAligned) {
958                // Volatile
959                {
960                    vh.setVolatile(array, i, VALUE_2);
961                    $type$ x = ($type$) vh.getVolatile(array, i);
962                    assertEquals(x, VALUE_2, "setVolatile $type$ value");
963                }
964
965                // Lazy
966                {
967                    vh.setRelease(array, i, VALUE_1);
968                    $type$ x = ($type$) vh.getAcquire(array, i);
969                    assertEquals(x, VALUE_1, "setRelease $type$ value");
970                }
971
972                // Opaque
973                {
974                    vh.setOpaque(array, i, VALUE_2);
975                    $type$ x = ($type$) vh.getOpaque(array, i);
976                    assertEquals(x, VALUE_2, "setOpaque $type$ value");
977                }
978#if[CAS]
979
980                vh.set(array, i, VALUE_1);
981
982                // Compare
983                {
984                    boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2);
985                    assertEquals(r, true, "success compareAndSet $type$");
986                    $type$ x = ($type$) vh.get(array, i);
987                    assertEquals(x, VALUE_2, "success compareAndSet $type$ value");
988                }
989
990                {
991                    boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3);
992                    assertEquals(r, false, "failing compareAndSet $type$");
993                    $type$ x = ($type$) vh.get(array, i);
994                    assertEquals(x, VALUE_2, "failing compareAndSet $type$ value");
995                }
996
997                {
998                    $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1);
999                    assertEquals(r, VALUE_2, "success compareAndExchangeVolatile $type$");
1000                    $type$ x = ($type$) vh.get(array, i);
1001                    assertEquals(x, VALUE_1, "success compareAndExchangeVolatile $type$ value");
1002                }
1003
1004                {
1005                    $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3);
1006                    assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile $type$");
1007                    $type$ x = ($type$) vh.get(array, i);
1008                    assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile $type$ value");
1009                }
1010
1011                {
1012                    $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2);
1013                    assertEquals(r, VALUE_1, "success compareAndExchangeAcquire $type$");
1014                    $type$ x = ($type$) vh.get(array, i);
1015                    assertEquals(x, VALUE_2, "success compareAndExchangeAcquire $type$ value");
1016                }
1017
1018                {
1019                    $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3);
1020                    assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire $type$");
1021                    $type$ x = ($type$) vh.get(array, i);
1022                    assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire $type$ value");
1023                }
1024
1025                {
1026                    $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1);
1027                    assertEquals(r, VALUE_2, "success compareAndExchangeRelease $type$");
1028                    $type$ x = ($type$) vh.get(array, i);
1029                    assertEquals(x, VALUE_1, "success compareAndExchangeRelease $type$ value");
1030                }
1031
1032                {
1033                    $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3);
1034                    assertEquals(r, VALUE_1, "failing compareAndExchangeRelease $type$");
1035                    $type$ x = ($type$) vh.get(array, i);
1036                    assertEquals(x, VALUE_1, "failing compareAndExchangeRelease $type$ value");
1037                }
1038
1039                {
1040                    boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2);
1041                    assertEquals(r, true, "weakCompareAndSet $type$");
1042                    $type$ x = ($type$) vh.get(array, i);
1043                    assertEquals(x, VALUE_2, "weakCompareAndSet $type$ value");
1044                }
1045
1046                {
1047                    boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1);
1048                    assertEquals(r, true, "weakCompareAndSetAcquire $type$");
1049                    $type$ x = ($type$) vh.get(array, i);
1050                    assertEquals(x, VALUE_1, "weakCompareAndSetAcquire $type$");
1051                }
1052
1053                {
1054                    boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2);
1055                    assertEquals(r, true, "weakCompareAndSetRelease $type$");
1056                    $type$ x = ($type$) vh.get(array, i);
1057                    assertEquals(x, VALUE_2, "weakCompareAndSetRelease $type$");
1058                }
1059
1060                {
1061                    boolean r = vh.weakCompareAndSetVolatile(array, i, VALUE_2, VALUE_1);
1062                    assertEquals(r, true, "weakCompareAndSetVolatile $type$");
1063                    $type$ x = ($type$) vh.get(array, i);
1064                    assertEquals(x, VALUE_1, "weakCompareAndSetVolatile $type$ value");
1065                }
1066
1067                // Compare set and get
1068                {
1069                    $type$ o = ($type$) vh.getAndSet(array, i, VALUE_2);
1070                    assertEquals(o, VALUE_1, "getAndSet $type$");
1071                    $type$ x = ($type$) vh.get(array, i);
1072                    assertEquals(x, VALUE_2, "getAndSet $type$ value");
1073                }
1074#end[CAS]
1075
1076#if[AtomicAdd]
1077                vh.set(array, i, VALUE_1);
1078
1079                // get and add, add and get
1080                {
1081                    $type$ o = ($type$) vh.getAndAdd(array, i, VALUE_3);
1082                    assertEquals(o, VALUE_1, "getAndAdd $type$");
1083                    $type$ c = ($type$) vh.addAndGet(array, i, VALUE_3);
1084                    assertEquals(c, VALUE_1 + VALUE_3 + VALUE_3, "getAndAdd $type$ value");
1085                }
1086#end[AtomicAdd]
1087            }
1088        }
1089    }
1090
1091    static void testArrayReadOnly(ByteBufferSource bs, VarHandleSource vhs) {
1092        VarHandle vh = vhs.s;
1093        ByteBuffer array = bs.s;
1094
1095        int misalignmentAtZero = array.alignmentOffset(0, SIZE);
1096
1097        ByteBuffer bb = ByteBuffer.allocate(SIZE);
1098        bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN);
1099        bs.fill(bb.put$Type$(0, VALUE_2).array());
1100
1101        int length = array.limit() - SIZE + 1;
1102        for (int i = 0; i < length; i++) {
1103            boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
1104
1105            $type$ v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes)
1106                    ? rotateLeft(VALUE_2, (i % SIZE) << 3)
1107                    : rotateRight(VALUE_2, (i % SIZE) << 3);
1108            // Plain
1109            {
1110                $type$ x = ($type$) vh.get(array, i);
1111                assertEquals(x, v, "get $type$ value");
1112            }
1113
1114            if (iAligned) {
1115                // Volatile
1116                {
1117                    $type$ x = ($type$) vh.getVolatile(array, i);
1118                    assertEquals(x, v, "getVolatile $type$ value");
1119                }
1120
1121                // Lazy
1122                {
1123                    $type$ x = ($type$) vh.getAcquire(array, i);
1124                    assertEquals(x, v, "getRelease $type$ value");
1125                }
1126
1127                // Opaque
1128                {
1129                    $type$ x = ($type$) vh.getOpaque(array, i);
1130                    assertEquals(x, v, "getOpaque $type$ value");
1131                }
1132            }
1133        }
1134    }
1135
1136}
1137
1138