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