|
23 | 23 |
|
24 | 24 | package runtime.valhalla.inlinetypes;
|
25 | 25 |
|
| 26 | +import jdk.internal.misc.Unsafe; |
26 | 27 | import jdk.internal.value.ValueClass;
|
27 | 28 | import jdk.internal.vm.annotation.ImplicitlyConstructible;
|
28 | 29 | import jdk.internal.vm.annotation.LooselyConsistentValue;
|
29 | 30 | import jdk.internal.vm.annotation.NullRestricted;
|
30 | 31 | import java.lang.management.ManagementFactory;
|
31 | 32 | import java.lang.management.RuntimeMXBean;
|
32 | 33 | import java.lang.reflect.Array;
|
| 34 | +import java.lang.reflect.Field; |
33 | 35 | import java.lang.reflect.InvocationTargetException;
|
34 | 36 | import java.lang.reflect.Method;
|
35 | 37 | import java.util.Arrays;
|
|
43 | 45 | /*
|
44 | 46 | * @test FlatArraysTest
|
45 | 47 | * @summary Plain array test for Inline Types
|
| 48 | + * @requires vm.flagless |
46 | 49 | * @modules java.base/jdk.internal.value
|
47 | 50 | * java.base/jdk.internal.vm.annotation
|
| 51 | + * java.base/jdk.internal.misc |
48 | 52 | * @library /test/lib
|
49 | 53 | * @enablePreview
|
50 | 54 | * @compile --source 25 FlatArraysTest.java
|
|
54 | 58 |
|
55 | 59 | public class FlatArraysTest {
|
56 | 60 | static final int ARRAY_SIZE = 100;
|
| 61 | + static final Unsafe UNSAFE = Unsafe.getUnsafe(); |
57 | 62 |
|
58 | 63 | @ImplicitlyConstructible
|
59 | 64 | @LooselyConsistentValue
|
@@ -451,10 +456,103 @@ static void testArrayAccesses() throws NoSuchMethodException, InstantiationExcep
|
451 | 456 | }
|
452 | 457 | }
|
453 | 458 |
|
| 459 | + @ImplicitlyConstructible |
| 460 | + static value class AtomicValue { |
| 461 | + int i = 0; |
| 462 | + } |
| 463 | + |
| 464 | + static value class FieldsHolder { |
| 465 | + @NullRestricted |
| 466 | + SmallValue sv = new SmallValue(); |
| 467 | + |
| 468 | + @NullRestricted |
| 469 | + AtomicValue av = new AtomicValue(); |
| 470 | + |
| 471 | + AtomicValue nav = new AtomicValue(); |
| 472 | + } |
| 473 | + |
| 474 | + static void testSpecialArrayLayoutFromArray(Object[] array, boolean expectException) { |
| 475 | + int lk = UNSAFE.arrayLayout(array.getClass()); |
| 476 | + boolean exception = false; |
| 477 | + try { |
| 478 | + Object[] newArray = UNSAFE.newSpecialArray(array.getClass().getComponentType(), 10, lk); |
| 479 | + int newLk = UNSAFE.arrayLayout(newArray.getClass()); |
| 480 | + assertEquals(newLk, lk); |
| 481 | + } catch(IllegalArgumentException e) { |
| 482 | + e.printStackTrace(); |
| 483 | + exception = true; |
| 484 | + } |
| 485 | + assertEquals(exception, expectException, "Exception not matching expectations"); |
| 486 | + } |
| 487 | + |
| 488 | + static void testSpecialArrayFromFieldLayout(Class c, int layout, boolean expectException) { |
| 489 | + boolean exception = false; |
| 490 | + try { |
| 491 | + Object[] array = UNSAFE.newSpecialArray(c, 10, layout); |
| 492 | + int lk = UNSAFE.arrayLayout(array.getClass()); |
| 493 | + assertEquals(lk, layout); |
| 494 | + } catch (IllegalArgumentException e) { |
| 495 | + e.printStackTrace(); |
| 496 | + throw new RuntimeException(e); |
| 497 | + } catch (UnsupportedOperationException e) { |
| 498 | + e.printStackTrace(); |
| 499 | + exception = true; |
| 500 | + } |
| 501 | + assertEquals(exception, expectException, "Exception not matching expectations"); |
| 502 | + } |
| 503 | + |
| 504 | + static void testSpecialArrayCreation() { |
| 505 | + RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean(); |
| 506 | + List<String> jvmArgs = runtimeMXBean.getInputArguments(); |
| 507 | + boolean arrayFlatteningEnabled = true; |
| 508 | + for (String s : jvmArgs) { |
| 509 | + if (s.compareTo("-XX:-UseArrayFlattening") == 0) arrayFlatteningEnabled = false; |
| 510 | + } |
| 511 | + |
| 512 | + // Test array creation from another array |
| 513 | + Object[] array0 = new SmallValue[10]; |
| 514 | + testSpecialArrayLayoutFromArray(array0, true); |
| 515 | + if (arrayFlatteningEnabled) { |
| 516 | + Object[] array1 = ValueClass.newNullRestrictedArray(SmallValue.class, 10); |
| 517 | + testSpecialArrayLayoutFromArray(array1, false); |
| 518 | + Object[] array2 = ValueClass.newNullRestrictedAtomicArray(SmallValue.class, 10); |
| 519 | + testSpecialArrayLayoutFromArray(array2, false); |
| 520 | + Object[] array3 = ValueClass.newNullableAtomicArray(SmallValue.class, 10); |
| 521 | + testSpecialArrayLayoutFromArray(array3, false); |
| 522 | + } |
| 523 | + |
| 524 | + // Test array creation from a field layout |
| 525 | + try { |
| 526 | + Class c = FieldsHolder.class; |
| 527 | + Field f0 = c.getDeclaredField("sv"); |
| 528 | + int layout0 = UNSAFE.fieldLayout(f0); |
| 529 | + testSpecialArrayFromFieldLayout(f0.getType(), layout0, !arrayFlatteningEnabled); |
| 530 | + Field f1 = c.getDeclaredField("av"); |
| 531 | + int layout1 = UNSAFE.fieldLayout(f1); |
| 532 | + testSpecialArrayFromFieldLayout(f1.getType(), layout1, !arrayFlatteningEnabled); |
| 533 | + Field f2 = c.getDeclaredField("nav"); |
| 534 | + int layout2 = UNSAFE.fieldLayout(f2); |
| 535 | + testSpecialArrayFromFieldLayout(f2.getType(), layout2, !arrayFlatteningEnabled); |
| 536 | + } catch(NoSuchFieldException e) { |
| 537 | + e.printStackTrace(); |
| 538 | + } |
| 539 | + |
| 540 | + // Testing an invalid layout value |
| 541 | + boolean exception = false; |
| 542 | + try { |
| 543 | + UNSAFE.newSpecialArray(SmallValue.class, 10, 100); |
| 544 | + } catch(IllegalArgumentException e) { |
| 545 | + e.printStackTrace(); |
| 546 | + exception = true; |
| 547 | + } |
| 548 | + assertEquals(exception, true, "Exception not received"); |
| 549 | + } |
| 550 | + |
454 | 551 | public static void main(String[] args) throws NoSuchMethodException, InstantiationException,
|
455 | 552 | IllegalAccessException, InvocationTargetException {
|
456 | 553 | testArrayAccesses();
|
457 | 554 | testArrayCopy();
|
| 555 | + testSpecialArrayCreation(); |
458 | 556 | }
|
459 | 557 |
|
460 | 558 | }
|
0 commit comments