blob: f9c9d4fc31ea488ee55901c1f6b1f69e008ad988 [file] [log] [blame]
Paul Sandoz9fb30a32016-03-24 11:21:21 +01001/*
2 * Copyright (c) 2015, 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 * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessByte
27 * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessByte
28 * @run testng/othervm -Diters=20000 VarHandleTestAccessByte
29 * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccessByte
30 */
31
32import org.testng.annotations.BeforeClass;
33import org.testng.annotations.DataProvider;
34import org.testng.annotations.Test;
35
36import java.lang.invoke.MethodHandles;
37import java.lang.invoke.VarHandle;
38import java.util.ArrayList;
39import java.util.Arrays;
40import java.util.List;
41
42import static org.testng.Assert.*;
43
44public class VarHandleTestAccessByte extends VarHandleBaseTest {
45 static final byte static_final_v = (byte)1;
46
47 static byte static_v;
48
49 final byte final_v = (byte)1;
50
51 byte v;
52
53 VarHandle vhFinalField;
54
55 VarHandle vhField;
56
57 VarHandle vhStaticField;
58
59 VarHandle vhStaticFinalField;
60
61 VarHandle vhArray;
62
63 @BeforeClass
64 public void setup() throws Exception {
65 vhFinalField = MethodHandles.lookup().findVarHandle(
66 VarHandleTestAccessByte.class, "final_v", byte.class);
67
68 vhField = MethodHandles.lookup().findVarHandle(
69 VarHandleTestAccessByte.class, "v", byte.class);
70
71 vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
72 VarHandleTestAccessByte.class, "static_final_v", byte.class);
73
74 vhStaticField = MethodHandles.lookup().findStaticVarHandle(
75 VarHandleTestAccessByte.class, "static_v", byte.class);
76
77 vhArray = MethodHandles.arrayElementVarHandle(byte[].class);
78 }
79
80
81 @DataProvider
82 public Object[][] varHandlesProvider() throws Exception {
83 List<VarHandle> vhs = new ArrayList<>();
84 vhs.add(vhField);
85 vhs.add(vhStaticField);
86 vhs.add(vhArray);
87
88 return vhs.stream().map(tc -> new Object[]{tc}).toArray(Object[][]::new);
89 }
90
91 @Test(dataProvider = "varHandlesProvider")
92 public void testIsAccessModeSupported(VarHandle vh) {
Paul Sandoza7aff442016-04-13 15:05:48 +020093 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET));
94 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET));
95 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_VOLATILE));
96 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_VOLATILE));
97 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_ACQUIRE));
98 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_RELEASE));
99 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_OPAQUE));
100 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_OPAQUE));
Paul Sandoz9fb30a32016-03-24 11:21:21 +0100101
Paul Sandoza7aff442016-04-13 15:05:48 +0200102 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_ACQUIRE));
108 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
109 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
110 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
Paul Sandoz9fb30a32016-03-24 11:21:21 +0100111
Paul Sandoza7aff442016-04-13 15:05:48 +0200112 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
113 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.ADD_AND_GET));
Paul Sandoz9fb30a32016-03-24 11:21:21 +0100114 }
115
116
117 @DataProvider
118 public Object[][] typesProvider() throws Exception {
119 List<Object[]> types = new ArrayList<>();
120 types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccessByte.class)});
121 types.add(new Object[] {vhStaticField, Arrays.asList()});
122 types.add(new Object[] {vhArray, Arrays.asList(byte[].class, int.class)});
123
124 return types.stream().toArray(Object[][]::new);
125 }
126
127 @Test(dataProvider = "typesProvider")
128 public void testTypes(VarHandle vh, List<Class<?>> pts) {
129 assertEquals(vh.varType(), byte.class);
130
131 assertEquals(vh.coordinateTypes(), pts);
132
133 testTypes(vh);
134 }
135
136
137 @Test
138 public void testLookupInstanceToStatic() {
139 checkIAE("Lookup of static final field to instance final field", () -> {
140 MethodHandles.lookup().findStaticVarHandle(
141 VarHandleTestAccessByte.class, "final_v", byte.class);
142 });
143
144 checkIAE("Lookup of static field to instance field", () -> {
145 MethodHandles.lookup().findStaticVarHandle(
146 VarHandleTestAccessByte.class, "v", byte.class);
147 });
148 }
149
150 @Test
151 public void testLookupStaticToInstance() {
152 checkIAE("Lookup of instance final field to static final field", () -> {
153 MethodHandles.lookup().findVarHandle(
154 VarHandleTestAccessByte.class, "static_final_v", byte.class);
155 });
156
157 checkIAE("Lookup of instance field to static field", () -> {
158 vhStaticField = MethodHandles.lookup().findVarHandle(
159 VarHandleTestAccessByte.class, "static_v", byte.class);
160 });
161 }
162
163
164 @DataProvider
165 public Object[][] accessTestCaseProvider() throws Exception {
166 List<AccessTestCase<?>> cases = new ArrayList<>();
167
168 cases.add(new VarHandleAccessTestCase("Instance final field",
169 vhFinalField, vh -> testInstanceFinalField(this, vh)));
170 cases.add(new VarHandleAccessTestCase("Instance final field unsupported",
171 vhFinalField, vh -> testInstanceFinalFieldUnsupported(this, vh),
172 false));
173
174 cases.add(new VarHandleAccessTestCase("Static final field",
175 vhStaticFinalField, VarHandleTestAccessByte::testStaticFinalField));
176 cases.add(new VarHandleAccessTestCase("Static final field unsupported",
177 vhStaticFinalField, VarHandleTestAccessByte::testStaticFinalFieldUnsupported,
178 false));
179
180 cases.add(new VarHandleAccessTestCase("Instance field",
181 vhField, vh -> testInstanceField(this, vh)));
182 cases.add(new VarHandleAccessTestCase("Instance field unsupported",
183 vhField, vh -> testInstanceFieldUnsupported(this, vh),
184 false));
185
186 cases.add(new VarHandleAccessTestCase("Static field",
187 vhStaticField, VarHandleTestAccessByte::testStaticField));
188 cases.add(new VarHandleAccessTestCase("Static field unsupported",
189 vhStaticField, VarHandleTestAccessByte::testStaticFieldUnsupported,
190 false));
191
192 cases.add(new VarHandleAccessTestCase("Array",
193 vhArray, VarHandleTestAccessByte::testArray));
194 cases.add(new VarHandleAccessTestCase("Array unsupported",
195 vhArray, VarHandleTestAccessByte::testArrayUnsupported,
196 false));
197 cases.add(new VarHandleAccessTestCase("Array index out of bounds",
198 vhArray, VarHandleTestAccessByte::testArrayIndexOutOfBounds,
199 false));
200
201 // Work around issue with jtreg summary reporting which truncates
202 // the String result of Object.toString to 30 characters, hence
203 // the first dummy argument
204 return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
205 }
206
207 @Test(dataProvider = "accessTestCaseProvider")
208 public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
209 T t = atc.get();
210 int iters = atc.requiresLoop() ? ITERS : 1;
211 for (int c = 0; c < iters; c++) {
212 atc.testAccess(t);
213 }
214 }
215
216
217
218
219 static void testInstanceFinalField(VarHandleTestAccessByte recv, VarHandle vh) {
220 // Plain
221 {
222 byte x = (byte) vh.get(recv);
223 assertEquals(x, (byte)1, "get byte value");
224 }
225
226
227 // Volatile
228 {
229 byte x = (byte) vh.getVolatile(recv);
230 assertEquals(x, (byte)1, "getVolatile byte value");
231 }
232
233 // Lazy
234 {
235 byte x = (byte) vh.getAcquire(recv);
236 assertEquals(x, (byte)1, "getRelease byte value");
237 }
238
239 // Opaque
240 {
241 byte x = (byte) vh.getOpaque(recv);
242 assertEquals(x, (byte)1, "getOpaque byte value");
243 }
244 }
245
246 static void testInstanceFinalFieldUnsupported(VarHandleTestAccessByte recv, VarHandle vh) {
247 checkUOE(() -> {
248 vh.set(recv, (byte)2);
249 });
250
251 checkUOE(() -> {
252 vh.setVolatile(recv, (byte)2);
253 });
254
255 checkUOE(() -> {
256 vh.setRelease(recv, (byte)2);
257 });
258
259 checkUOE(() -> {
260 vh.setOpaque(recv, (byte)2);
261 });
262
263 checkUOE(() -> {
264 boolean r = vh.compareAndSet(recv, (byte)1, (byte)2);
265 });
266
267 checkUOE(() -> {
268 byte r = (byte) vh.compareAndExchangeVolatile(recv, (byte)1, (byte)2);
269 });
270
271 checkUOE(() -> {
272 byte r = (byte) vh.compareAndExchangeAcquire(recv, (byte)1, (byte)2);
273 });
274
275 checkUOE(() -> {
276 byte r = (byte) vh.compareAndExchangeRelease(recv, (byte)1, (byte)2);
277 });
278
279 checkUOE(() -> {
280 boolean r = vh.weakCompareAndSet(recv, (byte)1, (byte)2);
281 });
282
283 checkUOE(() -> {
284 boolean r = vh.weakCompareAndSetAcquire(recv, (byte)1, (byte)2);
285 });
286
287 checkUOE(() -> {
288 boolean r = vh.weakCompareAndSetRelease(recv, (byte)1, (byte)2);
289 });
290
291 checkUOE(() -> {
292 byte o = (byte) vh.getAndAdd(recv, (byte)1);
293 });
294
295 checkUOE(() -> {
296 byte o = (byte) vh.addAndGet(recv, (byte)1);
297 });
298 }
299
300
301 static void testStaticFinalField(VarHandle vh) {
302 // Plain
303 {
304 byte x = (byte) vh.get();
305 assertEquals(x, (byte)1, "get byte value");
306 }
307
308
309 // Volatile
310 {
311 byte x = (byte) vh.getVolatile();
312 assertEquals(x, (byte)1, "getVolatile byte value");
313 }
314
315 // Lazy
316 {
317 byte x = (byte) vh.getAcquire();
318 assertEquals(x, (byte)1, "getRelease byte value");
319 }
320
321 // Opaque
322 {
323 byte x = (byte) vh.getOpaque();
324 assertEquals(x, (byte)1, "getOpaque byte value");
325 }
326 }
327
328 static void testStaticFinalFieldUnsupported(VarHandle vh) {
329 checkUOE(() -> {
330 vh.set((byte)2);
331 });
332
333 checkUOE(() -> {
334 vh.setVolatile((byte)2);
335 });
336
337 checkUOE(() -> {
338 vh.setRelease((byte)2);
339 });
340
341 checkUOE(() -> {
342 vh.setOpaque((byte)2);
343 });
344
345 checkUOE(() -> {
346 boolean r = vh.compareAndSet((byte)1, (byte)2);
347 });
348
349 checkUOE(() -> {
350 byte r = (byte) vh.compareAndExchangeVolatile((byte)1, (byte)2);
351 });
352
353 checkUOE(() -> {
354 byte r = (byte) vh.compareAndExchangeAcquire((byte)1, (byte)2);
355 });
356
357 checkUOE(() -> {
358 byte r = (byte) vh.compareAndExchangeRelease((byte)1, (byte)2);
359 });
360
361 checkUOE(() -> {
362 boolean r = vh.weakCompareAndSet((byte)1, (byte)2);
363 });
364
365 checkUOE(() -> {
366 boolean r = vh.weakCompareAndSetAcquire((byte)1, (byte)2);
367 });
368
369 checkUOE(() -> {
370 boolean r = vh.weakCompareAndSetRelease((byte)1, (byte)2);
371 });
372
373 checkUOE(() -> {
374 byte o = (byte) vh.getAndAdd((byte)1);
375 });
376
377 checkUOE(() -> {
378 byte o = (byte) vh.addAndGet((byte)1);
379 });
380 }
381
382
383 static void testInstanceField(VarHandleTestAccessByte recv, VarHandle vh) {
384 // Plain
385 {
386 vh.set(recv, (byte)1);
387 byte x = (byte) vh.get(recv);
388 assertEquals(x, (byte)1, "set byte value");
389 }
390
391
392 // Volatile
393 {
394 vh.setVolatile(recv, (byte)2);
395 byte x = (byte) vh.getVolatile(recv);
396 assertEquals(x, (byte)2, "setVolatile byte value");
397 }
398
399 // Lazy
400 {
401 vh.setRelease(recv, (byte)1);
402 byte x = (byte) vh.getAcquire(recv);
403 assertEquals(x, (byte)1, "setRelease byte value");
404 }
405
406 // Opaque
407 {
408 vh.setOpaque(recv, (byte)2);
409 byte x = (byte) vh.getOpaque(recv);
410 assertEquals(x, (byte)2, "setOpaque byte value");
411 }
412
413
414 }
415
416 static void testInstanceFieldUnsupported(VarHandleTestAccessByte recv, VarHandle vh) {
417 checkUOE(() -> {
418 boolean r = vh.compareAndSet(recv, (byte)1, (byte)2);
419 });
420
421 checkUOE(() -> {
422 byte r = (byte) vh.compareAndExchangeVolatile(recv, (byte)1, (byte)2);
423 });
424
425 checkUOE(() -> {
426 byte r = (byte) vh.compareAndExchangeAcquire(recv, (byte)1, (byte)2);
427 });
428
429 checkUOE(() -> {
430 byte r = (byte) vh.compareAndExchangeRelease(recv, (byte)1, (byte)2);
431 });
432
433 checkUOE(() -> {
434 boolean r = vh.weakCompareAndSet(recv, (byte)1, (byte)2);
435 });
436
437 checkUOE(() -> {
438 boolean r = vh.weakCompareAndSetAcquire(recv, (byte)1, (byte)2);
439 });
440
441 checkUOE(() -> {
442 boolean r = vh.weakCompareAndSetRelease(recv, (byte)1, (byte)2);
443 });
444
445 checkUOE(() -> {
446 byte o = (byte) vh.getAndAdd(recv, (byte)1);
447 });
448
449 checkUOE(() -> {
450 byte o = (byte) vh.addAndGet(recv, (byte)1);
451 });
452 }
453
454
455 static void testStaticField(VarHandle vh) {
456 // Plain
457 {
458 vh.set((byte)1);
459 byte x = (byte) vh.get();
460 assertEquals(x, (byte)1, "set byte value");
461 }
462
463
464 // Volatile
465 {
466 vh.setVolatile((byte)2);
467 byte x = (byte) vh.getVolatile();
468 assertEquals(x, (byte)2, "setVolatile byte value");
469 }
470
471 // Lazy
472 {
473 vh.setRelease((byte)1);
474 byte x = (byte) vh.getAcquire();
475 assertEquals(x, (byte)1, "setRelease byte value");
476 }
477
478 // Opaque
479 {
480 vh.setOpaque((byte)2);
481 byte x = (byte) vh.getOpaque();
482 assertEquals(x, (byte)2, "setOpaque byte value");
483 }
484
485
486 }
487
488 static void testStaticFieldUnsupported(VarHandle vh) {
489 checkUOE(() -> {
490 boolean r = vh.compareAndSet((byte)1, (byte)2);
491 });
492
493 checkUOE(() -> {
494 byte r = (byte) vh.compareAndExchangeVolatile((byte)1, (byte)2);
495 });
496
497 checkUOE(() -> {
498 byte r = (byte) vh.compareAndExchangeAcquire((byte)1, (byte)2);
499 });
500
501 checkUOE(() -> {
502 byte r = (byte) vh.compareAndExchangeRelease((byte)1, (byte)2);
503 });
504
505 checkUOE(() -> {
506 boolean r = vh.weakCompareAndSet((byte)1, (byte)2);
507 });
508
509 checkUOE(() -> {
510 boolean r = vh.weakCompareAndSetAcquire((byte)1, (byte)2);
511 });
512
513 checkUOE(() -> {
514 boolean r = vh.weakCompareAndSetRelease((byte)1, (byte)2);
515 });
516
517 checkUOE(() -> {
518 byte o = (byte) vh.getAndAdd((byte)1);
519 });
520
521 checkUOE(() -> {
522 byte o = (byte) vh.addAndGet((byte)1);
523 });
524 }
525
526
527 static void testArray(VarHandle vh) {
528 byte[] array = new byte[10];
529
530 for (int i = 0; i < array.length; i++) {
531 // Plain
532 {
533 vh.set(array, i, (byte)1);
534 byte x = (byte) vh.get(array, i);
535 assertEquals(x, (byte)1, "get byte value");
536 }
537
538
539 // Volatile
540 {
541 vh.setVolatile(array, i, (byte)2);
542 byte x = (byte) vh.getVolatile(array, i);
543 assertEquals(x, (byte)2, "setVolatile byte value");
544 }
545
546 // Lazy
547 {
548 vh.setRelease(array, i, (byte)1);
549 byte x = (byte) vh.getAcquire(array, i);
550 assertEquals(x, (byte)1, "setRelease byte value");
551 }
552
553 // Opaque
554 {
555 vh.setOpaque(array, i, (byte)2);
556 byte x = (byte) vh.getOpaque(array, i);
557 assertEquals(x, (byte)2, "setOpaque byte value");
558 }
559
560
561 }
562 }
563
564 static void testArrayUnsupported(VarHandle vh) {
565 byte[] array = new byte[10];
566
567 int i = 0;
568 checkUOE(() -> {
569 boolean r = vh.compareAndSet(array, i, (byte)1, (byte)2);
570 });
571
572 checkUOE(() -> {
573 byte r = (byte) vh.compareAndExchangeVolatile(array, i, (byte)1, (byte)2);
574 });
575
576 checkUOE(() -> {
577 byte r = (byte) vh.compareAndExchangeAcquire(array, i, (byte)1, (byte)2);
578 });
579
580 checkUOE(() -> {
581 byte r = (byte) vh.compareAndExchangeRelease(array, i, (byte)1, (byte)2);
582 });
583
584 checkUOE(() -> {
585 boolean r = vh.weakCompareAndSet(array, i, (byte)1, (byte)2);
586 });
587
588 checkUOE(() -> {
589 boolean r = vh.weakCompareAndSetAcquire(array, i, (byte)1, (byte)2);
590 });
591
592 checkUOE(() -> {
593 boolean r = vh.weakCompareAndSetRelease(array, i, (byte)1, (byte)2);
594 });
595
596 checkUOE(() -> {
597 byte o = (byte) vh.getAndAdd(array, i, (byte)1);
598 });
599
600 checkUOE(() -> {
601 byte o = (byte) vh.addAndGet(array, i, (byte)1);
602 });
603 }
604
605 static void testArrayIndexOutOfBounds(VarHandle vh) throws Throwable {
606 byte[] array = new byte[10];
607
608 for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
609 final int ci = i;
610
611 checkIOOBE(() -> {
612 byte x = (byte) vh.get(array, ci);
613 });
614
615 checkIOOBE(() -> {
616 vh.set(array, ci, (byte)1);
617 });
618
619 checkIOOBE(() -> {
620 byte x = (byte) vh.getVolatile(array, ci);
621 });
622
623 checkIOOBE(() -> {
624 vh.setVolatile(array, ci, (byte)1);
625 });
626
627 checkIOOBE(() -> {
628 byte x = (byte) vh.getAcquire(array, ci);
629 });
630
631 checkIOOBE(() -> {
632 vh.setRelease(array, ci, (byte)1);
633 });
634
635 checkIOOBE(() -> {
636 byte x = (byte) vh.getOpaque(array, ci);
637 });
638
639 checkIOOBE(() -> {
640 vh.setOpaque(array, ci, (byte)1);
641 });
642
643
644 }
645 }
646}
647