1 /* 2 * Copyright (c) 2018, 2019, 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 * @summary Basic test for Array::get, Array::set, Arrays::setAll on inline class array 27 * @compile -XDallowWithFieldOperator Point.java NonFlattenValue.java 28 * @compile -XDallowWithFieldOperator ValueArray.java 29 * @run testng/othervm -XX:+EnableValhalla -XX:ValueArrayElemMaxFlatSize=-1 ValueArray 30 * @run testng/othervm -XX:+EnableValhalla -XX:ValueArrayElemMaxFlatSize=0 ValueArray 31 */ 32 33 import java.lang.reflect.Array; 34 import java.util.Arrays; 35 36 import org.testng.annotations.BeforeTest; 37 import org.testng.annotations.DataProvider; 38 import org.testng.annotations.Test; 39 import static org.testng.Assert.*; 40 41 public class ValueArray { 42 private static Class<?> nullablePointArrayClass() { 43 Object a = new Point?[0]; 44 return a.getClass(); 45 } 46 47 @DataProvider(name="arrayTypes") 48 static Object[][] arrayTypes() { 49 return new Object[][] { 50 new Object[] { Object[].class, 51 new Object[] { new Object(), new Object()}}, 52 new Object[] { Point[].class, 53 new Point[] { Point.makePoint(1, 2), 54 Point.makePoint(10, 20), 55 Point.makePoint(100, 200)}}, 56 new Object[] { Point[][].class, 57 new Point[][] { new Point[] { Point.makePoint(1, 2), 58 Point.makePoint(10, 20)}}}, 59 new Object[] { nullablePointArrayClass(), 60 new Point?[] { Point.makePoint(11, 22), 61 Point.makePoint(110, 220), 62 null}}, 63 new Object[] { NonFlattenValue[].class, 64 new NonFlattenValue[] { NonFlattenValue.make(1, 2), 65 NonFlattenValue.make(10, 20), 66 NonFlattenValue.make(100, 200)}}, 67 }; 68 } 69 70 71 @Test(dataProvider="arrayTypes") 72 public static void test(Class<?> c, Object[] elements) { 73 ValueArray test = new ValueArray(c, elements.length); 74 test.run(elements); 75 Class<?> compType = c.getComponentType(); 76 if (compType.isInlineClass()) { 77 test.testSetNullElement(compType == compType.asNullableType()); 78 } 79 } 80 81 @Test 82 public static void testPointArray() { 83 PointArray array = PointArray.makeArray(Point.makePoint(1, 2), Point.makePoint(10, 20)); 84 ValueArray test = new ValueArray(array.points); 85 test.run(Point.makePoint(3, 4), Point.makePoint(30, 40)); 86 } 87 88 @Test 89 public static void testNullablePointArray() { 90 Point ?[]array = new Point ?[3]; 91 array[0] = Point.makePoint(1, 2); 92 array[1] = null; 93 array[2] = Point.makePoint(3, 4); 94 95 ValueArray test = new ValueArray(array); 96 test.run(null, Point.makePoint(3, 4), null); 97 } 98 99 @Test 100 public static void testIntArray() { 101 int[] array = new int[] { 1, 2, 3}; 102 for (int i=0; i < array.length; i++) { 103 Array.set(array, i, Integer.valueOf(i*10)); 104 } 105 106 for (int i=0; i < array.length; i++) { 107 Integer o = (Integer) Array.get(array, i); 108 assertTrue(o.intValue() == i*10); 109 } 110 Arrays.setAll(array, i -> array[i]); 111 } 112 113 @Test 114 public static void testNonArrayObject() { 115 Object o = new Object(); 116 try { 117 Array.get(o, 0); 118 throw new AssertionError("IAE not thrown"); 119 } catch (IllegalArgumentException e) {} 120 121 try { 122 Array.set(o, 0, o); 123 throw new AssertionError("IAE not thrown"); 124 } catch (IllegalArgumentException e) {} 125 126 } 127 128 @Test() 129 static void testArrayCovariance() { 130 Point[] qArray = new Point[0]; 131 Point?[] lArray = new Point?[0]; 132 133 // language instanceof 134 assertTrue(qArray instanceof Point[]); 135 assertTrue(lArray instanceof Point?[]); 136 137 // Class.instanceOf (self) 138 assertTrue(qArray.getClass().isInstance(qArray)); 139 assertTrue(lArray.getClass().isInstance(lArray)); 140 141 // Class.instanceof inline vs indirect 142 assertFalse(qArray.getClass().isInstance(lArray)); 143 assertTrue(lArray.getClass().isInstance(qArray)); 144 145 // Class.isAssignableFrom (self) 146 assertTrue(qArray.getClass().isAssignableFrom(qArray.getClass())); 147 assertTrue(lArray.getClass().isAssignableFrom(lArray.getClass())); 148 149 // Class.isAssignableFrom inline vs indirect 150 assertTrue(lArray.getClass().isAssignableFrom(qArray.getClass())); 151 assertFalse(qArray.getClass().isAssignableFrom(lArray.getClass())); 152 153 // Class.cast (self) 154 qArray.getClass().cast(qArray); 155 lArray.getClass().cast(lArray); 156 157 // Class.cast inline vs indirect 158 lArray.getClass().cast(qArray); 159 try { 160 qArray.getClass().cast(lArray); 161 fail("cast of Point? to Point should not succeed"); 162 } catch (ClassCastException cce) { 163 // expected 164 } 165 } 166 167 private final Object[] array; 168 169 ValueArray(Class<?> arrayClass, int len) { 170 this((Object[])Array.newInstance(arrayClass.getComponentType(), len)); 171 assertTrue(array.getClass() == arrayClass); 172 } 173 174 ValueArray(Object[] array) { 175 this.array = array; 176 } 177 178 void run(Object... elements) { 179 for (int i=0; i < elements.length; i++) { 180 Array.set(array, i, elements[i]); 181 } 182 183 for (int i=0; i < elements.length; i++) { 184 Object o = Array.get(array, i); 185 assertEquals(o, elements[i]); 186 } 187 188 Arrays.setAll(array, i -> elements[i]); 189 } 190 191 void testSetNullElement(boolean nullable) { 192 assert(array.getClass().getComponentType().isInlineClass()); 193 for (int i=0; i < array.length; i++) { 194 try { 195 Array.set(array, i, null); 196 if (!nullable) 197 throw new AssertionError("NPE not thrown"); 198 } catch (NullPointerException e) { 199 assertFalse(nullable); 200 } 201 } 202 } 203 204 static inline class PointArray { 205 public Point[] points; 206 PointArray() { 207 points = new Point[0]; 208 } 209 public static PointArray makeArray(Point... points) { 210 PointArray a = PointArray.default; 211 Point[] array = new Point[points.length]; 212 for (int i=0; i < points.length; i++) { 213 array[i] = points[i]; 214 } 215 a = __WithField(a.points, array); 216 return a; 217 } 218 } 219 }