blob: 88bf198272b4e5ca3a983f939273e6ab8bbab0ee [file] [log] [blame]
Paul Sandoz9fb30a32016-03-24 11:21:21 +01001/*
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
Paul Sandoz1af28062016-04-26 18:30:00 -070026 * @bug 8154556
Paul Sandoz9fb30a32016-03-24 11:21:21 +010027 * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsLong
28 * @run testng/othervm -Diters=20000 VarHandleTestByteArrayAsLong
29 * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAsLong
Paul Sandoz44afe202016-05-17 12:06:41 +020030 * @run testng/othervm -Diters=20000 -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestByteArrayAsLong
Paul Sandoz9fb30a32016-03-24 11:21:21 +010031 */
32
33import org.testng.annotations.DataProvider;
34import org.testng.annotations.Test;
35
36import java.lang.invoke.MethodHandles;
37import java.lang.invoke.VarHandle;
38import java.nio.ByteBuffer;
39import java.nio.ByteOrder;
40import java.util.ArrayList;
41import java.util.Arrays;
42import java.util.EnumSet;
43import java.util.List;
44
45import static org.testng.Assert.*;
46
47public class VarHandleTestByteArrayAsLong extends VarHandleBaseByteArrayTest {
48 static final int SIZE = Long.BYTES;
49
50 static final long VALUE_1 = 0x0102030405060708L;
51
52 static final long VALUE_2 = 0x1112131415161718L;
53
Paul Sandoz0bad4452016-05-18 18:46:14 +020054 static final long VALUE_3 = 0xFFFEFDFCFBFAF9F8L;
Paul Sandoz9fb30a32016-03-24 11:21:21 +010055
56
57 @Override
58 public void setupVarHandleSources() {
59 // Combinations of VarHandle byte[] or ByteBuffer
60 vhss = new ArrayList<>();
61 for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) {
Paul Sandoz1af28062016-04-26 18:30:00 -070062
63 ByteOrder bo = endianess == MemoryMode.BIG_ENDIAN
64 ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
Paul Sandoz9fb30a32016-03-24 11:21:21 +010065 VarHandleSource aeh = new VarHandleSource(
Paul Sandoz1af28062016-04-26 18:30:00 -070066 MethodHandles.byteArrayViewVarHandle(long[].class, bo),
Paul Sandoz9fb30a32016-03-24 11:21:21 +010067 endianess, MemoryMode.READ_WRITE);
68 vhss.add(aeh);
69
70 VarHandleSource bbh = new VarHandleSource(
Paul Sandoz1af28062016-04-26 18:30:00 -070071 MethodHandles.byteBufferViewVarHandle(long[].class, bo),
Paul Sandoz9fb30a32016-03-24 11:21:21 +010072 endianess, MemoryMode.READ_WRITE);
73 vhss.add(bbh);
74 }
75 }
76
77
78 @Test(dataProvider = "varHandlesProvider")
79 public void testIsAccessModeSupported(VarHandleSource vhs) {
80 VarHandle vh = vhs.s;
81
Paul Sandoza7aff442016-04-13 15:05:48 +020082 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET));
83 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET));
Paul Sandoz9fb30a32016-03-24 11:21:21 +010084
Paul Sandoza7aff442016-04-13 15:05:48 +020085 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_VOLATILE));
86 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_VOLATILE));
87 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_ACQUIRE));
88 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_RELEASE));
89 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_OPAQUE));
90 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_OPAQUE));
Paul Sandoz9fb30a32016-03-24 11:21:21 +010091
Paul Sandoza7aff442016-04-13 15:05:48 +020092 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));
Paul Sandoze9556602016-04-29 13:46:19 -070097 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE));
Paul Sandoza7aff442016-04-13 15:05:48 +020098 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
99 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
Paul Sandoza7aff442016-04-13 15:05:48 +0200100 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
Paul Sandoz9fb30a32016-03-24 11:21:21 +0100101
Paul Sandoza7aff442016-04-13 15:05:48 +0200102 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
103 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.ADD_AND_GET));
Paul Sandoz9fb30a32016-03-24 11:21:21 +0100104 }
105
106 @Test(dataProvider = "typesProvider")
107 public void testTypes(VarHandle vh, List<java.lang.Class<?>> pts) {
108 assertEquals(vh.varType(), long.class);
109
110 assertEquals(vh.coordinateTypes(), pts);
111
112 testTypes(vh);
113 }
114
115
116 @DataProvider
117 public Object[][] accessTestCaseProvider() throws Exception {
118 List<AccessTestCase<?>> cases = new ArrayList<>();
119
120 for (ByteArrayViewSource<?> bav : bavss) {
121 for (VarHandleSource vh : vhss) {
122 if (vh.matches(bav)) {
123 if (bav instanceof ByteArraySource) {
124 ByteArraySource bas = (ByteArraySource) bav;
125
126 cases.add(new VarHandleSourceAccessTestCase(
127 "read write", bav, vh, h -> testArrayReadWrite(bas, h),
128 true));
129 cases.add(new VarHandleSourceAccessTestCase(
130 "unsupported", bav, vh, h -> testArrayUnsupported(bas, h),
131 false));
132 cases.add(new VarHandleSourceAccessTestCase(
133 "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bas, h),
134 false));
135 cases.add(new VarHandleSourceAccessTestCase(
136 "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bas, h),
137 false));
138 }
139 else {
140 ByteBufferSource bbs = (ByteBufferSource) bav;
141
142 if (MemoryMode.READ_WRITE.isSet(bav.memoryModes)) {
143 cases.add(new VarHandleSourceAccessTestCase(
144 "read write", bav, vh, h -> testArrayReadWrite(bbs, h),
145 true));
146 }
147 else {
148 cases.add(new VarHandleSourceAccessTestCase(
149 "read only", bav, vh, h -> testArrayReadOnly(bbs, h),
150 true));
151 }
152
153 cases.add(new VarHandleSourceAccessTestCase(
154 "unsupported", bav, vh, h -> testArrayUnsupported(bbs, h),
155 false));
156 cases.add(new VarHandleSourceAccessTestCase(
157 "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bbs, h),
158 false));
159 cases.add(new VarHandleSourceAccessTestCase(
160 "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bbs, h),
161 false));
162 }
163 }
164 }
165 }
166
167 // Work around issue with jtreg summary reporting which truncates
168 // the String result of Object.toString to 30 characters, hence
169 // the first dummy argument
170 return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
171 }
172
173 @Test(dataProvider = "accessTestCaseProvider")
174 public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
175 T t = atc.get();
176 int iters = atc.requiresLoop() ? ITERS : 1;
177 for (int c = 0; c < iters; c++) {
178 atc.testAccess(t);
179 }
180 }
181
182
183 static void testArrayUnsupported(ByteArraySource bs, VarHandleSource vhs) {
184 VarHandle vh = vhs.s;
185 byte[] array = bs.s;
186 int ci = 1;
187
188
189 }
190
191 static void testArrayUnsupported(ByteBufferSource bs, VarHandleSource vhs) {
192 VarHandle vh = vhs.s;
193 ByteBuffer array = bs.s;
194 int ci = 0;
195 boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
196
197 if (readOnly) {
198 checkROBE(() -> {
199 vh.set(array, ci, VALUE_1);
200 });
201 }
202
203 if (readOnly) {
204 checkROBE(() -> {
205 vh.setVolatile(array, ci, VALUE_1);
206 });
207
208 checkROBE(() -> {
209 vh.setRelease(array, ci, VALUE_1);
210 });
211
212 checkROBE(() -> {
213 vh.setOpaque(array, ci, VALUE_1);
214 });
215
216 checkROBE(() -> {
217 boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
218 });
219
220 checkROBE(() -> {
221 long r = (long) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
222 });
223
224 checkROBE(() -> {
225 long r = (long) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
226 });
227
228 checkROBE(() -> {
229 long r = (long) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
230 });
231
232 checkROBE(() -> {
233 boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
234 });
235
236 checkROBE(() -> {
Paul Sandoze9556602016-04-29 13:46:19 -0700237 boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
238 });
239
240 checkROBE(() -> {
Paul Sandoz9fb30a32016-03-24 11:21:21 +0100241 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
242 });
243
244 checkROBE(() -> {
245 boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
246 });
247
248 checkROBE(() -> {
249 long o = (long) vh.getAndSet(array, ci, VALUE_1);
250 });
Paul Sandoz44afe202016-05-17 12:06:41 +0200251
Paul Sandoz9fb30a32016-03-24 11:21:21 +0100252
253 checkROBE(() -> {
254 long o = (long) vh.getAndAdd(array, ci, VALUE_1);
255 });
256
257 checkROBE(() -> {
258 long o = (long) vh.addAndGet(array, ci, VALUE_1);
259 });
260 }
261 else {
262 }
263 }
264
265
266 static void testArrayIndexOutOfBounds(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
267 VarHandle vh = vhs.s;
268 byte[] array = bs.s;
269
270 int length = array.length - SIZE + 1;
271 for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
272 final int ci = i;
273
274 checkIOOBE(() -> {
275 long x = (long) vh.get(array, ci);
276 });
277
278 checkIOOBE(() -> {
279 vh.set(array, ci, VALUE_1);
280 });
281
282 checkIOOBE(() -> {
283 long x = (long) vh.getVolatile(array, ci);
284 });
285
286 checkIOOBE(() -> {
287 long x = (long) vh.getAcquire(array, ci);
288 });
289
290 checkIOOBE(() -> {
291 long x = (long) vh.getOpaque(array, ci);
292 });
293
294 checkIOOBE(() -> {
295 vh.setVolatile(array, ci, VALUE_1);
296 });
297
298 checkIOOBE(() -> {
299 vh.setRelease(array, ci, VALUE_1);
300 });
301
302 checkIOOBE(() -> {
303 vh.setOpaque(array, ci, VALUE_1);
304 });
305
306 checkIOOBE(() -> {
307 boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
308 });
309
310 checkIOOBE(() -> {
311 long r = (long) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
312 });
313
314 checkIOOBE(() -> {
315 long r = (long) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
316 });
317
318 checkIOOBE(() -> {
319 long r = (long) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
320 });
321
322 checkIOOBE(() -> {
323 boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
324 });
325
326 checkIOOBE(() -> {
Paul Sandoze9556602016-04-29 13:46:19 -0700327 boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
328 });
329
330 checkIOOBE(() -> {
Paul Sandoz9fb30a32016-03-24 11:21:21 +0100331 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
332 });
333
334 checkIOOBE(() -> {
335 boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
336 });
337
338 checkIOOBE(() -> {
339 long o = (long) vh.getAndSet(array, ci, VALUE_1);
340 });
341
342 checkIOOBE(() -> {
343 long o = (long) vh.getAndAdd(array, ci, VALUE_1);
344 });
345
346 checkIOOBE(() -> {
347 long o = (long) vh.addAndGet(array, ci, VALUE_1);
348 });
349
350 }
351 }
352
353 static void testArrayIndexOutOfBounds(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
354 VarHandle vh = vhs.s;
355 ByteBuffer array = bs.s;
356
357 boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
358
359 int length = array.limit() - SIZE + 1;
360 for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
361 final int ci = i;
362
363 checkIOOBE(() -> {
364 long x = (long) vh.get(array, ci);
365 });
366
367 if (!readOnly) {
368 checkIOOBE(() -> {
369 vh.set(array, ci, VALUE_1);
370 });
371 }
372
373 checkIOOBE(() -> {
374 long x = (long) vh.getVolatile(array, ci);
375 });
376
377 checkIOOBE(() -> {
378 long x = (long) vh.getAcquire(array, ci);
379 });
380
381 checkIOOBE(() -> {
382 long x = (long) vh.getOpaque(array, ci);
383 });
384
385 if (!readOnly) {
386 checkIOOBE(() -> {
387 vh.setVolatile(array, ci, VALUE_1);
388 });
389
390 checkIOOBE(() -> {
391 vh.setRelease(array, ci, VALUE_1);
392 });
393
394 checkIOOBE(() -> {
395 vh.setOpaque(array, ci, VALUE_1);
396 });
397
398 checkIOOBE(() -> {
399 boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
400 });
401
402 checkIOOBE(() -> {
403 long r = (long) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
404 });
405
406 checkIOOBE(() -> {
407 long r = (long) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
408 });
409
410 checkIOOBE(() -> {
411 long r = (long) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
412 });
413
414 checkIOOBE(() -> {
415 boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
416 });
417
418 checkIOOBE(() -> {
Paul Sandoze9556602016-04-29 13:46:19 -0700419 boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
420 });
421
422 checkIOOBE(() -> {
Paul Sandoz9fb30a32016-03-24 11:21:21 +0100423 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
424 });
425
426 checkIOOBE(() -> {
427 boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
428 });
429
430 checkIOOBE(() -> {
431 long o = (long) vh.getAndSet(array, ci, VALUE_1);
432 });
433
434 checkIOOBE(() -> {
435 long o = (long) vh.getAndAdd(array, ci, VALUE_1);
436 });
437
438 checkIOOBE(() -> {
439 long o = (long) vh.addAndGet(array, ci, VALUE_1);
440 });
441 }
442 }
443 }
444
445 static void testArrayMisalignedAccess(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
446 VarHandle vh = vhs.s;
447 byte[] array = bs.s;
448
449 int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
450
451 int length = array.length - SIZE + 1;
452 for (int i = 0; i < length; i++) {
453 boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
454 final int ci = i;
455
456 if (!iAligned) {
457 checkISE(() -> {
458 long x = (long) vh.getVolatile(array, ci);
459 });
460
461 checkISE(() -> {
462 long x = (long) vh.getAcquire(array, ci);
463 });
464
465 checkISE(() -> {
466 long x = (long) vh.getOpaque(array, ci);
467 });
468
469 checkISE(() -> {
470 vh.setVolatile(array, ci, VALUE_1);
471 });
472
473 checkISE(() -> {
474 vh.setRelease(array, ci, VALUE_1);
475 });
476
477 checkISE(() -> {
478 vh.setOpaque(array, ci, VALUE_1);
479 });
480
481 checkISE(() -> {
482 boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
483 });
484
485 checkISE(() -> {
486 long r = (long) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
487 });
488
489 checkISE(() -> {
490 long r = (long) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
491 });
492
493 checkISE(() -> {
494 long r = (long) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
495 });
496
497 checkISE(() -> {
498 boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
499 });
500
501 checkISE(() -> {
Paul Sandoze9556602016-04-29 13:46:19 -0700502 boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
503 });
504
505 checkISE(() -> {
Paul Sandoz9fb30a32016-03-24 11:21:21 +0100506 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
507 });
508
509 checkISE(() -> {
510 boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
511 });
512
513 checkISE(() -> {
514 long o = (long) vh.getAndSet(array, ci, VALUE_1);
515 });
516
517 checkISE(() -> {
518 long o = (long) vh.getAndAdd(array, ci, VALUE_1);
519 });
520
521 checkISE(() -> {
522 long o = (long) vh.addAndGet(array, ci, VALUE_1);
523 });
524
525 }
526 }
527 }
528
529 static void testArrayMisalignedAccess(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
530 VarHandle vh = vhs.s;
531 ByteBuffer array = bs.s;
532
533 boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
534 int misalignmentAtZero = array.alignmentOffset(0, SIZE);
535
536 int length = array.limit() - SIZE + 1;
537 for (int i = 0; i < length; i++) {
538 boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
539 final int ci = i;
540
541 if (!iAligned) {
542 checkISE(() -> {
543 long x = (long) vh.getVolatile(array, ci);
544 });
545
546 checkISE(() -> {
547 long x = (long) vh.getAcquire(array, ci);
548 });
549
550 checkISE(() -> {
551 long x = (long) vh.getOpaque(array, ci);
552 });
553
554 if (!readOnly) {
555 checkISE(() -> {
556 vh.setVolatile(array, ci, VALUE_1);
557 });
558
559 checkISE(() -> {
560 vh.setRelease(array, ci, VALUE_1);
561 });
562
563 checkISE(() -> {
564 vh.setOpaque(array, ci, VALUE_1);
565 });
566
567 checkISE(() -> {
568 boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
569 });
570
571 checkISE(() -> {
572 long r = (long) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
573 });
574
575 checkISE(() -> {
576 long r = (long) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
577 });
578
579 checkISE(() -> {
580 long r = (long) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
581 });
582
583 checkISE(() -> {
584 boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
585 });
586
587 checkISE(() -> {
Paul Sandoze9556602016-04-29 13:46:19 -0700588 boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
589 });
590
591 checkISE(() -> {
Paul Sandoz9fb30a32016-03-24 11:21:21 +0100592 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
593 });
594
595 checkISE(() -> {
596 boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
597 });
598
599 checkISE(() -> {
600 long o = (long) vh.getAndSet(array, ci, VALUE_1);
601 });
602
603 checkISE(() -> {
604 long o = (long) vh.getAndAdd(array, ci, VALUE_1);
605 });
606
607 checkISE(() -> {
608 long o = (long) vh.addAndGet(array, ci, VALUE_1);
609 });
610 }
611 }
612 }
613 }
614
615 static void testArrayReadWrite(ByteArraySource bs, VarHandleSource vhs) {
616 VarHandle vh = vhs.s;
617 byte[] array = bs.s;
618
619 int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
620
621 bs.fill((byte) 0xff);
622 int length = array.length - SIZE + 1;
623 for (int i = 0; i < length; i++) {
624 boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
625
626 // Plain
627 {
628 vh.set(array, i, VALUE_1);
629 long x = (long) vh.get(array, i);
630 assertEquals(x, VALUE_1, "get long value");
631 }
632
633
634 if (iAligned) {
635 // Volatile
636 {
637 vh.setVolatile(array, i, VALUE_2);
638 long x = (long) vh.getVolatile(array, i);
639 assertEquals(x, VALUE_2, "setVolatile long value");
640 }
641
642 // Lazy
643 {
644 vh.setRelease(array, i, VALUE_1);
645 long x = (long) vh.getAcquire(array, i);
646 assertEquals(x, VALUE_1, "setRelease long value");
647 }
648
649 // Opaque
650 {
651 vh.setOpaque(array, i, VALUE_2);
652 long x = (long) vh.getOpaque(array, i);
653 assertEquals(x, VALUE_2, "setOpaque long value");
654 }
655
656 vh.set(array, i, VALUE_1);
657
658 // Compare
659 {
660 boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2);
661 assertEquals(r, true, "success compareAndSet long");
662 long x = (long) vh.get(array, i);
663 assertEquals(x, VALUE_2, "success compareAndSet long value");
664 }
665
666 {
667 boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3);
668 assertEquals(r, false, "failing compareAndSet long");
669 long x = (long) vh.get(array, i);
670 assertEquals(x, VALUE_2, "failing compareAndSet long value");
671 }
672
673 {
674 long r = (long) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1);
675 assertEquals(r, VALUE_2, "success compareAndExchangeVolatile long");
676 long x = (long) vh.get(array, i);
677 assertEquals(x, VALUE_1, "success compareAndExchangeVolatile long value");
678 }
679
680 {
681 long r = (long) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3);
682 assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile long");
683 long x = (long) vh.get(array, i);
684 assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile long value");
685 }
686
687 {
688 long r = (long) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2);
689 assertEquals(r, VALUE_1, "success compareAndExchangeAcquire long");
690 long x = (long) vh.get(array, i);
691 assertEquals(x, VALUE_2, "success compareAndExchangeAcquire long value");
692 }
693
694 {
695 long r = (long) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3);
696 assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire long");
697 long x = (long) vh.get(array, i);
698 assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire long value");
699 }
700
701 {
702 long r = (long) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1);
703 assertEquals(r, VALUE_2, "success compareAndExchangeRelease long");
704 long x = (long) vh.get(array, i);
705 assertEquals(x, VALUE_1, "success compareAndExchangeRelease long value");
706 }
707
708 {
709 long r = (long) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3);
710 assertEquals(r, VALUE_1, "failing compareAndExchangeRelease long");
711 long x = (long) vh.get(array, i);
712 assertEquals(x, VALUE_1, "failing compareAndExchangeRelease long value");
713 }
714
715 {
Aleksey Shipilev4f538852016-05-04 17:17:28 +0300716 boolean success = false;
717 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
718 success = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2);
719 }
720 assertEquals(success, true, "weakCompareAndSet long");
Paul Sandoz9fb30a32016-03-24 11:21:21 +0100721 long x = (long) vh.get(array, i);
722 assertEquals(x, VALUE_2, "weakCompareAndSet long value");
723 }
724
725 {
Aleksey Shipilev4f538852016-05-04 17:17:28 +0300726 boolean success = false;
727 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
728 success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1);
729 }
730 assertEquals(success, true, "weakCompareAndSetAcquire long");
Paul Sandoz9fb30a32016-03-24 11:21:21 +0100731 long x = (long) vh.get(array, i);
732 assertEquals(x, VALUE_1, "weakCompareAndSetAcquire long");
733 }
734
735 {
Aleksey Shipilev4f538852016-05-04 17:17:28 +0300736 boolean success = false;
737 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
738 success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2);
739 }
740 assertEquals(success, true, "weakCompareAndSetRelease long");
Paul Sandoz9fb30a32016-03-24 11:21:21 +0100741 long x = (long) vh.get(array, i);
742 assertEquals(x, VALUE_2, "weakCompareAndSetRelease long");
743 }
744
Paul Sandoze9556602016-04-29 13:46:19 -0700745 {
746 boolean r = vh.weakCompareAndSetVolatile(array, i, VALUE_2, VALUE_1);
747 assertEquals(r, true, "weakCompareAndSetVolatile long");
748 long x = (long) vh.get(array, i);
749 assertEquals(x, VALUE_1, "weakCompareAndSetVolatile long value");
750 }
751
Paul Sandoz9fb30a32016-03-24 11:21:21 +0100752 // Compare set and get
753 {
Paul Sandoze9556602016-04-29 13:46:19 -0700754 long o = (long) vh.getAndSet(array, i, VALUE_2);
755 assertEquals(o, VALUE_1, "getAndSet long");
Paul Sandoz9fb30a32016-03-24 11:21:21 +0100756 long x = (long) vh.get(array, i);
Paul Sandoze9556602016-04-29 13:46:19 -0700757 assertEquals(x, VALUE_2, "getAndSet long value");
Paul Sandoz9fb30a32016-03-24 11:21:21 +0100758 }
759
760 vh.set(array, i, VALUE_1);
761
762 // get and add, add and get
763 {
764 long o = (long) vh.getAndAdd(array, i, VALUE_3);
765 assertEquals(o, VALUE_1, "getAndAdd long");
766 long c = (long) vh.addAndGet(array, i, VALUE_3);
767 assertEquals(c, VALUE_1 + VALUE_3 + VALUE_3, "getAndAdd long value");
768 }
769 }
770 }
771 }
772
773
774 static void testArrayReadWrite(ByteBufferSource bs, VarHandleSource vhs) {
775 VarHandle vh = vhs.s;
776 ByteBuffer array = bs.s;
777
778 int misalignmentAtZero = array.alignmentOffset(0, SIZE);
779
780 bs.fill((byte) 0xff);
781 int length = array.limit() - SIZE + 1;
782 for (int i = 0; i < length; i++) {
783 boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
784
785 // Plain
786 {
787 vh.set(array, i, VALUE_1);
788 long x = (long) vh.get(array, i);
789 assertEquals(x, VALUE_1, "get long value");
790 }
791
792 if (iAligned) {
793 // Volatile
794 {
795 vh.setVolatile(array, i, VALUE_2);
796 long x = (long) vh.getVolatile(array, i);
797 assertEquals(x, VALUE_2, "setVolatile long value");
798 }
799
800 // Lazy
801 {
802 vh.setRelease(array, i, VALUE_1);
803 long x = (long) vh.getAcquire(array, i);
804 assertEquals(x, VALUE_1, "setRelease long value");
805 }
806
807 // Opaque
808 {
809 vh.setOpaque(array, i, VALUE_2);
810 long x = (long) vh.getOpaque(array, i);
811 assertEquals(x, VALUE_2, "setOpaque long value");
812 }
813
814 vh.set(array, i, VALUE_1);
815
816 // Compare
817 {
818 boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2);
819 assertEquals(r, true, "success compareAndSet long");
820 long x = (long) vh.get(array, i);
821 assertEquals(x, VALUE_2, "success compareAndSet long value");
822 }
823
824 {
825 boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3);
826 assertEquals(r, false, "failing compareAndSet long");
827 long x = (long) vh.get(array, i);
828 assertEquals(x, VALUE_2, "failing compareAndSet long value");
829 }
830
831 {
832 long r = (long) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1);
833 assertEquals(r, VALUE_2, "success compareAndExchangeVolatile long");
834 long x = (long) vh.get(array, i);
835 assertEquals(x, VALUE_1, "success compareAndExchangeVolatile long value");
836 }
837
838 {
839 long r = (long) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3);
840 assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile long");
841 long x = (long) vh.get(array, i);
842 assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile long value");
843 }
844
845 {
846 long r = (long) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2);
847 assertEquals(r, VALUE_1, "success compareAndExchangeAcquire long");
848 long x = (long) vh.get(array, i);
849 assertEquals(x, VALUE_2, "success compareAndExchangeAcquire long value");
850 }
851
852 {
853 long r = (long) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3);
854 assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire long");
855 long x = (long) vh.get(array, i);
856 assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire long value");
857 }
858
859 {
860 long r = (long) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1);
861 assertEquals(r, VALUE_2, "success compareAndExchangeRelease long");
862 long x = (long) vh.get(array, i);
863 assertEquals(x, VALUE_1, "success compareAndExchangeRelease long value");
864 }
865
866 {
867 long r = (long) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3);
868 assertEquals(r, VALUE_1, "failing compareAndExchangeRelease long");
869 long x = (long) vh.get(array, i);
870 assertEquals(x, VALUE_1, "failing compareAndExchangeRelease long value");
871 }
872
873 {
Aleksey Shipilev4f538852016-05-04 17:17:28 +0300874 boolean success = false;
875 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
876 success = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2);
877 }
878 assertEquals(success, true, "weakCompareAndSet long");
Paul Sandoz9fb30a32016-03-24 11:21:21 +0100879 long x = (long) vh.get(array, i);
880 assertEquals(x, VALUE_2, "weakCompareAndSet long value");
881 }
882
883 {
Aleksey Shipilev4f538852016-05-04 17:17:28 +0300884 boolean success = false;
885 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
886 success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1);
887 }
888 assertEquals(success, true, "weakCompareAndSetAcquire long");
Paul Sandoz9fb30a32016-03-24 11:21:21 +0100889 long x = (long) vh.get(array, i);
890 assertEquals(x, VALUE_1, "weakCompareAndSetAcquire long");
891 }
892
893 {
Aleksey Shipilev4f538852016-05-04 17:17:28 +0300894 boolean success = false;
895 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
896 success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2);
897 }
898 assertEquals(success, true, "weakCompareAndSetRelease long");
Paul Sandoz9fb30a32016-03-24 11:21:21 +0100899 long x = (long) vh.get(array, i);
900 assertEquals(x, VALUE_2, "weakCompareAndSetRelease long");
901 }
902
Paul Sandoze9556602016-04-29 13:46:19 -0700903 {
904 boolean r = vh.weakCompareAndSetVolatile(array, i, VALUE_2, VALUE_1);
905 assertEquals(r, true, "weakCompareAndSetVolatile long");
906 long x = (long) vh.get(array, i);
907 assertEquals(x, VALUE_1, "weakCompareAndSetVolatile long value");
908 }
909
Paul Sandoz9fb30a32016-03-24 11:21:21 +0100910 // Compare set and get
911 {
Paul Sandoze9556602016-04-29 13:46:19 -0700912 long o = (long) vh.getAndSet(array, i, VALUE_2);
913 assertEquals(o, VALUE_1, "getAndSet long");
Paul Sandoz9fb30a32016-03-24 11:21:21 +0100914 long x = (long) vh.get(array, i);
Paul Sandoze9556602016-04-29 13:46:19 -0700915 assertEquals(x, VALUE_2, "getAndSet long value");
Paul Sandoz9fb30a32016-03-24 11:21:21 +0100916 }
917
918 vh.set(array, i, VALUE_1);
919
920 // get and add, add and get
921 {
922 long o = (long) vh.getAndAdd(array, i, VALUE_3);
923 assertEquals(o, VALUE_1, "getAndAdd long");
924 long c = (long) vh.addAndGet(array, i, VALUE_3);
925 assertEquals(c, VALUE_1 + VALUE_3 + VALUE_3, "getAndAdd long value");
926 }
927 }
928 }
929 }
930
931 static void testArrayReadOnly(ByteBufferSource bs, VarHandleSource vhs) {
932 VarHandle vh = vhs.s;
933 ByteBuffer array = bs.s;
934
935 int misalignmentAtZero = array.alignmentOffset(0, SIZE);
936
937 ByteBuffer bb = ByteBuffer.allocate(SIZE);
938 bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN);
939 bs.fill(bb.putLong(0, VALUE_2).array());
940
941 int length = array.limit() - SIZE + 1;
942 for (int i = 0; i < length; i++) {
943 boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
944
945 long v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes)
946 ? rotateLeft(VALUE_2, (i % SIZE) << 3)
947 : rotateRight(VALUE_2, (i % SIZE) << 3);
948 // Plain
949 {
950 long x = (long) vh.get(array, i);
951 assertEquals(x, v, "get long value");
952 }
953
954 if (iAligned) {
955 // Volatile
956 {
957 long x = (long) vh.getVolatile(array, i);
958 assertEquals(x, v, "getVolatile long value");
959 }
960
961 // Lazy
962 {
963 long x = (long) vh.getAcquire(array, i);
964 assertEquals(x, v, "getRelease long value");
965 }
966
967 // Opaque
968 {
969 long x = (long) vh.getOpaque(array, i);
970 assertEquals(x, v, "getOpaque long value");
971 }
972 }
973 }
974 }
975
976}
977