--- old/test/hotspot/jtreg/runtime/valhalla/valuetypes/ValueTypeArray.java 2019-03-27 16:10:53.859425851 +0100 +++ new/test/hotspot/jtreg/runtime/valhalla/valuetypes/ValueTypeArray.java 2019-03-27 16:10:53.563420954 +0100 @@ -58,24 +58,37 @@ testObjectArrayOfValues(); testReflectArray(); - // testUtilArrays(); + testUtilArrays(); } void testClassForName() { String arrayClsName = "[Lruntime.valhalla.valuetypes.Point;"; + String qarrayClsName = "[Qruntime.valhalla.valuetypes.Point;"; try { + // L-type.. Class arrayCls = Class.forName(arrayClsName); assertTrue(arrayCls.isArray(), "Expected an array class"); - // array-of-L-type not supported yet - // the component type of a flattened value array is of the value type - // the component type of a non-flattened array is of the box type - assertTrue(arrayCls.getComponentType().asBoxType() == Point.class, + + assertTrue(arrayCls.getComponentType() == Point.class.asBoxType(), "Expected component type of Point.class got: " + arrayCls.getComponentType()); arrayClsName = "[" + arrayClsName; Class mulArrayCls = Class.forName(arrayClsName); assertTrue(mulArrayCls.isArray()); assertTrue(mulArrayCls.getComponentType() == arrayCls); + + // Q-type... + arrayCls = Class.forName(qarrayClsName); + assertTrue(arrayCls.isArray(), "Expected an array class"); + + assertTrue(arrayCls.getComponentType() == Point.class.asValueType(), + arrayCls + + " Expected component type of Point.class got: " + arrayCls.getComponentType()); + + qarrayClsName = "[" + qarrayClsName; + mulArrayCls = Class.forName(qarrayClsName); + assertTrue(mulArrayCls.isArray()); + assertTrue(mulArrayCls.getComponentType() == arrayCls); } catch (ClassNotFoundException cnfe) { fail("Class.forName(" + arrayClsName + ") failed", cnfe); @@ -187,13 +200,14 @@ assertTrue(array3[0][0] == null, "Expected NULL"); // Now create ObjArrays of ValueArray... - cls = (Class) Point.class; - array = (Point[][]) Array.newInstance(cls, 1, 2); - assertEquals(array.length, 1, "Incorrect length"); - assertEquals(array[0].length, 2, "Incorrect length"); - Point p = array[0][1]; - int x = p.x; - assertEquals(x, 0, "Bad Point Value"); + cls = (Class) Point.class.asBoxType(); + Point.box[][] barray = (Point.box[][]) Array.newInstance(cls, 1, 2); + assertEquals(barray.length, 1, "Incorrect length"); + assertEquals(barray[0].length, 2, "Incorrect length"); + barray[0][1] = Point.createPoint(1, 2); + Point.box pb = barray[0][1]; + int x = pb.getX(); + assertEquals(x, 1, "Bad Point Value"); } static final value class MyInt implements Comparable { @@ -221,6 +235,10 @@ public static final MyInt.box MAX = MyInt.create(Integer.MAX_VALUE); } + static MyInt staticMyInt = MyInt.create(-1); + static MyInt[] staticMyIntArray = new MyInt[] { staticMyInt }; + static MyInt[][] staticMyIntArrayArray = new MyInt[][] { staticMyIntArray, staticMyIntArray }; + static interface SomeSecondaryType { default String hi() { return "Hi"; } } @@ -231,14 +249,13 @@ } void testSanityCheckcasts() { -// TODO Re-enable if value type arrays become covariant with object arrays -/* - MyInt[] myInts = new MyInt[1]; assertTrue(myInts instanceof Object[]); assertTrue(myInts instanceof Comparable[]); - Object arrObj = Array.newInstance(MyInt.class, 1); + Class cls = MyInt.class.asValueType(); + assertTrue(cls.isValue()); + Object arrObj = Array.newInstance(cls, 1); assertTrue(arrObj instanceof Object[], "Not Object array"); assertTrue(arrObj instanceof Comparable[], "Not Comparable array"); assertTrue(arrObj instanceof MyInt[], "Not MyInt array"); @@ -253,13 +270,15 @@ MyOtherInt[][] matrix = new MyOtherInt[1][1]; assertTrue(matrix[0] instanceof MyOtherInt[]); assertTrue(matrix[0] instanceof SomeSecondaryType[]); -*/ + + // Box types vs Value... + MyInt.box[] myValueRefs = new MyInt.box[1]; + assertTrue(myValueRefs instanceof MyInt.box[]); + assertTrue(myValueRefs instanceof Object[]); + assertTrue(myValueRefs instanceof Comparable[]); } -/* - * Comment out this test because value type arrays are not assignable to the array - * parameter types used by the methods in class java.util.Arrays. - * + void testUtilArrays() { // Sanity check j.u.Arrays MyInt[] myInts = new MyInt[] { MyInt.MAX, MyInt.MIN }; @@ -283,16 +302,8 @@ aList.remove(2); aList.add(MyInt.create(5)); - - // Interesting: - //aList.add((MyInt)getNull()); - - // javac currently generating "java/util/Objects.requireNonNull - // should checkcast treat null against Value class as CCE ? - // Then in the end, ArrayList.elementData is Object[], (that's why remove works) - // why can't I write add(null) then ? } -*/ + void testObjectArrayOfValues() { testSanityObjectArrays(); @@ -330,6 +341,10 @@ comparables[0] = null; comparables[1] = null; assertTrue(comparables[0] == null && comparables[1] == null, "Not null ?"); + + MyInt.box[] myIntRefArray = new MyInt.box[1]; + assertTrue(myIntRefArray[0] == null, "Got: " + myIntRefArray[0]); + myIntRefArray[0] = null; } void testMixedLayoutArrays() { @@ -365,6 +380,16 @@ System.arraycopy(objArray, 0, valArray, 0, 3); throw new RuntimeException("Expected ArrayStoreException"); } catch (ArrayStoreException ase) {} + + MyInt.box[] myIntRefArray = new MyInt.box[3]; + System.arraycopy(valArray, 0, myIntRefArray, 0, 3); + checkArrayElementsEqual(valArray, myIntRefArray); + + myIntRefArray[0] = null; + try { + System.arraycopy(myIntRefArray, 0, valArray, 0, 3); + throw new RuntimeException("Expected NullPointerException"); + } catch (NullPointerException npe) {} } static final value class MyPoint {