X-VarHandleTestByteArrayView.java.template revision 14549:099857ef9d0c
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
315#else[CAS]
316            checkUOE(() -> {
317                boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
318            });
319
320            checkUOE(() -> {
321                $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
322            });
323
324            checkUOE(() -> {
325                $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
326            });
327
328            checkUOE(() -> {
329                $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
330            });
331
332            checkUOE(() -> {
333                boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
334            });
335
336            checkUOE(() -> {
337                boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
338            });
339
340            checkUOE(() -> {
341                boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
342            });
343
344            checkUOE(() -> {
345                boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
346            });
347
348            checkUOE(() -> {
349                $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
350            });
351#end[CAS]
352
353#if[AtomicAdd]
354            checkROBE(() -> {
355                $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
356            });
357
358            checkROBE(() -> {
359                $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1);
360            });
361#else[AtomicAdd]
362            checkUOE(() -> {
363                $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
364            });
365
366            checkUOE(() -> {
367                $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1);
368            });
369#end[AtomicAdd]
370        }
371        else {
372#if[!CAS]
373            checkUOE(() -> {
374                boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
375            });
376
377            checkUOE(() -> {
378                $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
379            });
380
381            checkUOE(() -> {
382                $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
383            });
384
385            checkUOE(() -> {
386                $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
387            });
388
389            checkUOE(() -> {
390                boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
391            });
392
393            checkUOE(() -> {
394                boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
395            });
396
397            checkUOE(() -> {
398                boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
399            });
400
401            checkUOE(() -> {
402                boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
403            });
404
405            checkUOE(() -> {
406                $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
407            });
408#end[CAS]
409#if[!AtomicAdd]
410            checkUOE(() -> {
411                $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
412            });
413
414            checkUOE(() -> {
415                $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1);
416            });
417#end[AtomicAdd]
418        }
419    }
420
421
422    static void testArrayIndexOutOfBounds(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
423        VarHandle vh = vhs.s;
424        byte[] array = bs.s;
425
426        int length = array.length - SIZE + 1;
427        for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
428            final int ci = i;
429
430            checkIOOBE(() -> {
431                $type$ x = ($type$) vh.get(array, ci);
432            });
433
434            checkIOOBE(() -> {
435                vh.set(array, ci, VALUE_1);
436            });
437
438            checkIOOBE(() -> {
439                $type$ x = ($type$) vh.getVolatile(array, ci);
440            });
441
442            checkIOOBE(() -> {
443                $type$ x = ($type$) vh.getAcquire(array, ci);
444            });
445
446            checkIOOBE(() -> {
447                $type$ x = ($type$) vh.getOpaque(array, ci);
448            });
449
450            checkIOOBE(() -> {
451                vh.setVolatile(array, ci, VALUE_1);
452            });
453
454            checkIOOBE(() -> {
455                vh.setRelease(array, ci, VALUE_1);
456            });
457
458            checkIOOBE(() -> {
459                vh.setOpaque(array, ci, VALUE_1);
460            });
461#if[CAS]
462
463            checkIOOBE(() -> {
464                boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
465            });
466
467            checkIOOBE(() -> {
468                $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
469            });
470
471            checkIOOBE(() -> {
472                $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
473            });
474
475            checkIOOBE(() -> {
476                $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
477            });
478
479            checkIOOBE(() -> {
480                boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
481            });
482
483            checkIOOBE(() -> {
484                boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
485            });
486
487            checkIOOBE(() -> {
488                boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
489            });
490
491            checkIOOBE(() -> {
492                boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
493            });
494
495            checkIOOBE(() -> {
496                $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
497            });
498#end[CAS]
499
500#if[AtomicAdd]
501            checkIOOBE(() -> {
502                $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
503            });
504
505            checkIOOBE(() -> {
506                $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1);
507            });
508#end[AtomicAdd]
509
510        }
511    }
512
513    static void testArrayIndexOutOfBounds(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
514        VarHandle vh = vhs.s;
515        ByteBuffer array = bs.s;
516
517        boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
518
519        int length = array.limit() - SIZE + 1;
520        for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
521            final int ci = i;
522
523            checkIOOBE(() -> {
524                $type$ x = ($type$) vh.get(array, ci);
525            });
526
527            if (!readOnly) {
528                checkIOOBE(() -> {
529                    vh.set(array, ci, VALUE_1);
530                });
531            }
532
533            checkIOOBE(() -> {
534                $type$ x = ($type$) vh.getVolatile(array, ci);
535            });
536
537            checkIOOBE(() -> {
538                $type$ x = ($type$) vh.getAcquire(array, ci);
539            });
540
541            checkIOOBE(() -> {
542                $type$ x = ($type$) vh.getOpaque(array, ci);
543            });
544
545            if (!readOnly) {
546                checkIOOBE(() -> {
547                    vh.setVolatile(array, ci, VALUE_1);
548                });
549
550                checkIOOBE(() -> {
551                    vh.setRelease(array, ci, VALUE_1);
552                });
553
554                checkIOOBE(() -> {
555                    vh.setOpaque(array, ci, VALUE_1);
556                });
557
558#if[CAS]
559                checkIOOBE(() -> {
560                    boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
561                });
562
563                checkIOOBE(() -> {
564                    $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
565                });
566
567                checkIOOBE(() -> {
568                    $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
569                });
570
571                checkIOOBE(() -> {
572                    $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
573                });
574
575                checkIOOBE(() -> {
576                    boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
577                });
578
579                checkIOOBE(() -> {
580                    boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
581                });
582
583                checkIOOBE(() -> {
584                    boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
585                });
586
587                checkIOOBE(() -> {
588                    boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
589                });
590
591                checkIOOBE(() -> {
592                    $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
593                });
594#end[CAS]
595
596#if[AtomicAdd]
597                checkIOOBE(() -> {
598                    $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
599                });
600
601                checkIOOBE(() -> {
602                    $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1);
603                });
604#end[AtomicAdd]
605            }
606        }
607    }
608
609    static void testArrayMisalignedAccess(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
610        VarHandle vh = vhs.s;
611        byte[] array = bs.s;
612
613        int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
614
615        int length = array.length - SIZE + 1;
616        for (int i = 0; i < length; i++) {
617            boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
618            final int ci = i;
619
620            if (!iAligned) {
621                checkISE(() -> {
622                    $type$ x = ($type$) vh.getVolatile(array, ci);
623                });
624
625                checkISE(() -> {
626                    $type$ x = ($type$) vh.getAcquire(array, ci);
627                });
628
629                checkISE(() -> {
630                    $type$ x = ($type$) vh.getOpaque(array, ci);
631                });
632
633                checkISE(() -> {
634                    vh.setVolatile(array, ci, VALUE_1);
635                });
636
637                checkISE(() -> {
638                    vh.setRelease(array, ci, VALUE_1);
639                });
640
641                checkISE(() -> {
642                    vh.setOpaque(array, ci, VALUE_1);
643                });
644#if[CAS]
645
646                checkISE(() -> {
647                    boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
648                });
649
650                checkISE(() -> {
651                    $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
652                });
653
654                checkISE(() -> {
655                    $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
656                });
657
658                checkISE(() -> {
659                    $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
660                });
661
662                checkISE(() -> {
663                    boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
664                });
665
666                checkISE(() -> {
667                    boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
668                });
669
670                checkISE(() -> {
671                    boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
672                });
673
674                checkISE(() -> {
675                    boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
676                });
677
678                checkISE(() -> {
679                    $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
680                });
681#end[CAS]
682
683#if[AtomicAdd]
684                checkISE(() -> {
685                    $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
686                });
687
688                checkISE(() -> {
689                    $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1);
690                });
691#end[AtomicAdd]
692
693            }
694        }
695    }
696
697    static void testArrayMisalignedAccess(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
698        VarHandle vh = vhs.s;
699        ByteBuffer array = bs.s;
700
701        boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
702        int misalignmentAtZero = array.alignmentOffset(0, SIZE);
703
704        int length = array.limit() - SIZE + 1;
705        for (int i = 0; i < length; i++) {
706            boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
707            final int ci = i;
708
709            if (!iAligned) {
710                checkISE(() -> {
711                    $type$ x = ($type$) vh.getVolatile(array, ci);
712                });
713
714                checkISE(() -> {
715                    $type$ x = ($type$) vh.getAcquire(array, ci);
716                });
717
718                checkISE(() -> {
719                    $type$ x = ($type$) vh.getOpaque(array, ci);
720                });
721
722                if (!readOnly) {
723                    checkISE(() -> {
724                        vh.setVolatile(array, ci, VALUE_1);
725                    });
726
727                    checkISE(() -> {
728                        vh.setRelease(array, ci, VALUE_1);
729                    });
730
731                    checkISE(() -> {
732                        vh.setOpaque(array, ci, VALUE_1);
733                    });
734
735#if[CAS]
736                    checkISE(() -> {
737                        boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
738                    });
739
740                    checkISE(() -> {
741                        $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
742                    });
743
744                    checkISE(() -> {
745                        $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
746                    });
747
748                    checkISE(() -> {
749                        $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
750                    });
751
752                    checkISE(() -> {
753                        boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
754                    });
755
756                    checkISE(() -> {
757                        boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
758                    });
759
760                    checkISE(() -> {
761                        boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
762                    });
763
764                    checkISE(() -> {
765                        boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
766                    });
767
768                    checkISE(() -> {
769                        $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
770                    });
771#end[CAS]
772
773#if[AtomicAdd]
774                    checkISE(() -> {
775                        $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
776                    });
777
778                    checkISE(() -> {
779                        $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1);
780                    });
781#end[AtomicAdd]
782                }
783            }
784        }
785    }
786
787    static void testArrayReadWrite(ByteArraySource bs, VarHandleSource vhs) {
788        VarHandle vh = vhs.s;
789        byte[] array = bs.s;
790
791        int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
792
793        bs.fill((byte) 0xff);
794        int length = array.length - SIZE + 1;
795        for (int i = 0; i < length; i++) {
796            boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
797
798            // Plain
799            {
800                vh.set(array, i, VALUE_1);
801                $type$ x = ($type$) vh.get(array, i);
802                assertEquals(x, VALUE_1, "get $type$ value");
803            }
804
805
806            if (iAligned) {
807                // Volatile
808                {
809                    vh.setVolatile(array, i, VALUE_2);
810                    $type$ x = ($type$) vh.getVolatile(array, i);
811                    assertEquals(x, VALUE_2, "setVolatile $type$ value");
812                }
813
814                // Lazy
815                {
816                    vh.setRelease(array, i, VALUE_1);
817                    $type$ x = ($type$) vh.getAcquire(array, i);
818                    assertEquals(x, VALUE_1, "setRelease $type$ value");
819                }
820
821                // Opaque
822                {
823                    vh.setOpaque(array, i, VALUE_2);
824                    $type$ x = ($type$) vh.getOpaque(array, i);
825                    assertEquals(x, VALUE_2, "setOpaque $type$ value");
826                }
827#if[CAS]
828
829                vh.set(array, i, VALUE_1);
830
831                // Compare
832                {
833                    boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2);
834                    assertEquals(r, true, "success compareAndSet $type$");
835                    $type$ x = ($type$) vh.get(array, i);
836                    assertEquals(x, VALUE_2, "success compareAndSet $type$ value");
837                }
838
839                {
840                    boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3);
841                    assertEquals(r, false, "failing compareAndSet $type$");
842                    $type$ x = ($type$) vh.get(array, i);
843                    assertEquals(x, VALUE_2, "failing compareAndSet $type$ value");
844                }
845
846                {
847                    $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1);
848                    assertEquals(r, VALUE_2, "success compareAndExchangeVolatile $type$");
849                    $type$ x = ($type$) vh.get(array, i);
850                    assertEquals(x, VALUE_1, "success compareAndExchangeVolatile $type$ value");
851                }
852
853                {
854                    $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3);
855                    assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile $type$");
856                    $type$ x = ($type$) vh.get(array, i);
857                    assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile $type$ value");
858                }
859
860                {
861                    $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2);
862                    assertEquals(r, VALUE_1, "success compareAndExchangeAcquire $type$");
863                    $type$ x = ($type$) vh.get(array, i);
864                    assertEquals(x, VALUE_2, "success compareAndExchangeAcquire $type$ value");
865                }
866
867                {
868                    $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3);
869                    assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire $type$");
870                    $type$ x = ($type$) vh.get(array, i);
871                    assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire $type$ value");
872                }
873
874                {
875                    $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1);
876                    assertEquals(r, VALUE_2, "success compareAndExchangeRelease $type$");
877                    $type$ x = ($type$) vh.get(array, i);
878                    assertEquals(x, VALUE_1, "success compareAndExchangeRelease $type$ value");
879                }
880
881                {
882                    $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3);
883                    assertEquals(r, VALUE_1, "failing compareAndExchangeRelease $type$");
884                    $type$ x = ($type$) vh.get(array, i);
885                    assertEquals(x, VALUE_1, "failing compareAndExchangeRelease $type$ value");
886                }
887
888                {
889                    boolean success = false;
890                    for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
891                        success = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2);
892                    }
893                    assertEquals(success, true, "weakCompareAndSet $type$");
894                    $type$ x = ($type$) vh.get(array, i);
895                    assertEquals(x, VALUE_2, "weakCompareAndSet $type$ value");
896                }
897
898                {
899                    boolean success = false;
900                    for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
901                        success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1);
902                    }
903                    assertEquals(success, true, "weakCompareAndSetAcquire $type$");
904                    $type$ x = ($type$) vh.get(array, i);
905                    assertEquals(x, VALUE_1, "weakCompareAndSetAcquire $type$");
906                }
907
908                {
909                    boolean success = false;
910                    for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
911                        success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2);
912                    }
913                    assertEquals(success, true, "weakCompareAndSetRelease $type$");
914                    $type$ x = ($type$) vh.get(array, i);
915                    assertEquals(x, VALUE_2, "weakCompareAndSetRelease $type$");
916                }
917
918                {
919                    boolean r = vh.weakCompareAndSetVolatile(array, i, VALUE_2, VALUE_1);
920                    assertEquals(r, true, "weakCompareAndSetVolatile $type$");
921                    $type$ x = ($type$) vh.get(array, i);
922                    assertEquals(x, VALUE_1, "weakCompareAndSetVolatile $type$ value");
923                }
924
925                // Compare set and get
926                {
927                    $type$ o = ($type$) vh.getAndSet(array, i, VALUE_2);
928                    assertEquals(o, VALUE_1, "getAndSet $type$");
929                    $type$ x = ($type$) vh.get(array, i);
930                    assertEquals(x, VALUE_2, "getAndSet $type$ value");
931                }
932#end[CAS]
933
934#if[AtomicAdd]
935                vh.set(array, i, VALUE_1);
936
937                // get and add, add and get
938                {
939                    $type$ o = ($type$) vh.getAndAdd(array, i, VALUE_3);
940                    assertEquals(o, VALUE_1, "getAndAdd $type$");
941                    $type$ c = ($type$) vh.addAndGet(array, i, VALUE_3);
942                    assertEquals(c, VALUE_1 + VALUE_3 + VALUE_3, "getAndAdd $type$ value");
943                }
944#end[AtomicAdd]
945            }
946        }
947    }
948
949
950    static void testArrayReadWrite(ByteBufferSource bs, VarHandleSource vhs) {
951        VarHandle vh = vhs.s;
952        ByteBuffer array = bs.s;
953
954        int misalignmentAtZero = array.alignmentOffset(0, SIZE);
955
956        bs.fill((byte) 0xff);
957        int length = array.limit() - SIZE + 1;
958        for (int i = 0; i < length; i++) {
959            boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
960
961            // Plain
962            {
963                vh.set(array, i, VALUE_1);
964                $type$ x = ($type$) vh.get(array, i);
965                assertEquals(x, VALUE_1, "get $type$ value");
966            }
967
968            if (iAligned) {
969                // Volatile
970                {
971                    vh.setVolatile(array, i, VALUE_2);
972                    $type$ x = ($type$) vh.getVolatile(array, i);
973                    assertEquals(x, VALUE_2, "setVolatile $type$ value");
974                }
975
976                // Lazy
977                {
978                    vh.setRelease(array, i, VALUE_1);
979                    $type$ x = ($type$) vh.getAcquire(array, i);
980                    assertEquals(x, VALUE_1, "setRelease $type$ value");
981                }
982
983                // Opaque
984                {
985                    vh.setOpaque(array, i, VALUE_2);
986                    $type$ x = ($type$) vh.getOpaque(array, i);
987                    assertEquals(x, VALUE_2, "setOpaque $type$ value");
988                }
989#if[CAS]
990
991                vh.set(array, i, VALUE_1);
992
993                // Compare
994                {
995                    boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2);
996                    assertEquals(r, true, "success compareAndSet $type$");
997                    $type$ x = ($type$) vh.get(array, i);
998                    assertEquals(x, VALUE_2, "success compareAndSet $type$ value");
999                }
1000
1001                {
1002                    boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3);
1003                    assertEquals(r, false, "failing compareAndSet $type$");
1004                    $type$ x = ($type$) vh.get(array, i);
1005                    assertEquals(x, VALUE_2, "failing compareAndSet $type$ value");
1006                }
1007
1008                {
1009                    $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1);
1010                    assertEquals(r, VALUE_2, "success compareAndExchangeVolatile $type$");
1011                    $type$ x = ($type$) vh.get(array, i);
1012                    assertEquals(x, VALUE_1, "success compareAndExchangeVolatile $type$ value");
1013                }
1014
1015                {
1016                    $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3);
1017                    assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile $type$");
1018                    $type$ x = ($type$) vh.get(array, i);
1019                    assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile $type$ value");
1020                }
1021
1022                {
1023                    $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2);
1024                    assertEquals(r, VALUE_1, "success compareAndExchangeAcquire $type$");
1025                    $type$ x = ($type$) vh.get(array, i);
1026                    assertEquals(x, VALUE_2, "success compareAndExchangeAcquire $type$ value");
1027                }
1028
1029                {
1030                    $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3);
1031                    assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire $type$");
1032                    $type$ x = ($type$) vh.get(array, i);
1033                    assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire $type$ value");
1034                }
1035
1036                {
1037                    $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1);
1038                    assertEquals(r, VALUE_2, "success compareAndExchangeRelease $type$");
1039                    $type$ x = ($type$) vh.get(array, i);
1040                    assertEquals(x, VALUE_1, "success compareAndExchangeRelease $type$ value");
1041                }
1042
1043                {
1044                    $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3);
1045                    assertEquals(r, VALUE_1, "failing compareAndExchangeRelease $type$");
1046                    $type$ x = ($type$) vh.get(array, i);
1047                    assertEquals(x, VALUE_1, "failing compareAndExchangeRelease $type$ value");
1048                }
1049
1050                {
1051                    boolean success = false;
1052                    for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
1053                        success = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2);
1054                    }
1055                    assertEquals(success, true, "weakCompareAndSet $type$");
1056                    $type$ x = ($type$) vh.get(array, i);
1057                    assertEquals(x, VALUE_2, "weakCompareAndSet $type$ value");
1058                }
1059
1060                {
1061                    boolean success = false;
1062                    for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
1063                        success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1);
1064                    }
1065                    assertEquals(success, true, "weakCompareAndSetAcquire $type$");
1066                    $type$ x = ($type$) vh.get(array, i);
1067                    assertEquals(x, VALUE_1, "weakCompareAndSetAcquire $type$");
1068                }
1069
1070                {
1071                    boolean success = false;
1072                    for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
1073                        success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2);
1074                    }
1075                    assertEquals(success, true, "weakCompareAndSetRelease $type$");
1076                    $type$ x = ($type$) vh.get(array, i);
1077                    assertEquals(x, VALUE_2, "weakCompareAndSetRelease $type$");
1078                }
1079
1080                {
1081                    boolean r = vh.weakCompareAndSetVolatile(array, i, VALUE_2, VALUE_1);
1082                    assertEquals(r, true, "weakCompareAndSetVolatile $type$");
1083                    $type$ x = ($type$) vh.get(array, i);
1084                    assertEquals(x, VALUE_1, "weakCompareAndSetVolatile $type$ value");
1085                }
1086
1087                // Compare set and get
1088                {
1089                    $type$ o = ($type$) vh.getAndSet(array, i, VALUE_2);
1090                    assertEquals(o, VALUE_1, "getAndSet $type$");
1091                    $type$ x = ($type$) vh.get(array, i);
1092                    assertEquals(x, VALUE_2, "getAndSet $type$ value");
1093                }
1094#end[CAS]
1095
1096#if[AtomicAdd]
1097                vh.set(array, i, VALUE_1);
1098
1099                // get and add, add and get
1100                {
1101                    $type$ o = ($type$) vh.getAndAdd(array, i, VALUE_3);
1102                    assertEquals(o, VALUE_1, "getAndAdd $type$");
1103                    $type$ c = ($type$) vh.addAndGet(array, i, VALUE_3);
1104                    assertEquals(c, VALUE_1 + VALUE_3 + VALUE_3, "getAndAdd $type$ value");
1105                }
1106#end[AtomicAdd]
1107            }
1108        }
1109    }
1110
1111    static void testArrayReadOnly(ByteBufferSource bs, VarHandleSource vhs) {
1112        VarHandle vh = vhs.s;
1113        ByteBuffer array = bs.s;
1114
1115        int misalignmentAtZero = array.alignmentOffset(0, SIZE);
1116
1117        ByteBuffer bb = ByteBuffer.allocate(SIZE);
1118        bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN);
1119        bs.fill(bb.put$Type$(0, VALUE_2).array());
1120
1121        int length = array.limit() - SIZE + 1;
1122        for (int i = 0; i < length; i++) {
1123            boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
1124
1125            $type$ v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes)
1126                    ? rotateLeft(VALUE_2, (i % SIZE) << 3)
1127                    : rotateRight(VALUE_2, (i % SIZE) << 3);
1128            // Plain
1129            {
1130                $type$ x = ($type$) vh.get(array, i);
1131                assertEquals(x, v, "get $type$ value");
1132            }
1133
1134            if (iAligned) {
1135                // Volatile
1136                {
1137                    $type$ x = ($type$) vh.getVolatile(array, i);
1138                    assertEquals(x, v, "getVolatile $type$ value");
1139                }
1140
1141                // Lazy
1142                {
1143                    $type$ x = ($type$) vh.getAcquire(array, i);
1144                    assertEquals(x, v, "getRelease $type$ value");
1145                }
1146
1147                // Opaque
1148                {
1149                    $type$ x = ($type$) vh.getOpaque(array, i);
1150                    assertEquals(x, v, "getOpaque $type$ value");
1151                }
1152            }
1153        }
1154    }
1155
1156}
1157
1158