1 /*
  2  * Copyright (c) 2018, 2021, 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 package runtime.valhalla.inlinetypes;
 25 
 26 import java.lang.reflect.Array;
 27 import java.util.Arrays;
 28 import java.util.ArrayList;
 29 import java.util.List;
 30 
 31 import static jdk.test.lib.Asserts.*;
 32 
 33 /*
 34  * @test InlineTypeArray
 35  * @summary Plain array test for Inline Types
 36  * @library /test/lib
 37  * @compile InlineTypeArray.java Point.java Long8Inline.java Person.java
 38  * @run main/othervm -XX:FlatArrayElementMaxSize=-1 runtime.valhalla.inlinetypes.InlineTypeArray
 39  * @run main/othervm -XX:FlatArrayElementMaxSize=0  runtime.valhalla.inlinetypes.InlineTypeArray
 40  * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:ForceNonTearable=* runtime.valhalla.inlinetypes.InlineTypeArray
 41  */
 42 public class InlineTypeArray {
 43     public static void main(String[] args) {
 44         InlineTypeArray inlineTypeArray = new InlineTypeArray();
 45         inlineTypeArray.run();
 46     }
 47 
 48     public void run() {
 49         testClassForName();
 50         testSimplePointArray();
 51         testLong8Array();
 52         testMixedPersonArray();
 53         testMultiDimPointArray();
 54         testComposition();
 55 
 56         testSanityCheckcasts();
 57         testObjectArrayOfInlines();
 58 
 59         testReflectArray();
 60         testUtilArrays();
 61 
 62         testInlineArrayOom();
 63     }
 64 
 65     void testClassForName() {
 66         String arrayClsName = "[Lruntime.valhalla.inlinetypes.Point;";
 67         String qarrayClsName = "[Qruntime.valhalla.inlinetypes.Point;";
 68         try {
 69             // L-type..
 70             Class<?> arrayCls = Class.forName(arrayClsName);
 71             assertTrue(arrayCls.isArray(), "Expected an array class");
 72 
 73             arrayClsName = "[" + arrayClsName;
 74             Class<?> mulArrayCls = Class.forName(arrayClsName);
 75             assertTrue(mulArrayCls.isArray());
 76             assertTrue(mulArrayCls.getComponentType() == arrayCls);
 77 
 78             // Q-type...
 79             arrayCls = Class.forName(qarrayClsName);
 80             assertTrue(arrayCls.isArray(), "Expected an array class");
 81 
 82             assertTrue(arrayCls.getComponentType() == Point.class.asValueType(),
 83                        arrayCls +
 84                        " Expected component type of Point.class got: " + arrayCls.getComponentType());
 85 
 86             qarrayClsName = "[" + qarrayClsName;
 87             mulArrayCls = Class.forName(qarrayClsName);
 88             assertTrue(mulArrayCls.isArray());
 89             assertTrue(mulArrayCls.getComponentType() == arrayCls);
 90         }
 91         catch (ClassNotFoundException cnfe) {
 92             fail("Class.forName(" + arrayClsName + ") failed", cnfe);
 93         }
 94     }
 95 
 96     void testSimplePointArray() {
 97         Point[] defaultPoint = new Point[1];
 98         Point p = defaultPoint[0];
 99         assertEquals(p.x, 0, "invalid default loaded from array");
100         assertEquals(p.y, 0, "invalid default loaded from array");
101         boolean gotNpe = false;
102         try {
103             defaultPoint[0] = (Point) getNull();
104         } catch (NullPointerException npe) {
105             gotNpe = true;
106         }
107         assertTrue(gotNpe, "Expected NullPointerException");
108 
109         Point[] points = createSimplePointArray();
110         System.gc(); // check that VTs survive GC
111         checkSimplePointArray(points);
112         assertTrue(points instanceof Point[], "Instance of");
113 
114         testSimplePointArrayCopy();
115 
116         // Locked/unlocked flat array type checks
117         points = createSimplePointArray();
118         Point[] pointsCopy = new Point[points.length];
119         synchronized (points) {
120             assertTrue(points instanceof Point[], "Instance of");
121             checkSimplePointArray(points);
122             System.arraycopy(points, 0, pointsCopy, 0, points.length);
123             synchronized (pointsCopy) {
124                 assertTrue(pointsCopy instanceof Point[], "Instance of");
125                 checkSimplePointArray(pointsCopy);
126                 System.gc();
127             }
128             System.gc();
129         }
130         assertTrue(pointsCopy instanceof Point[], "Instance of");
131         checkSimplePointArray(pointsCopy);
132     }
133 
134     void testSimplePointArrayCopy() {
135         Point[] points = createSimplePointArray();
136         Point[] pointsCopy = new Point[points.length];
137         System.arraycopy(points, 0, pointsCopy, 0, points.length);
138         checkSimplePointArray(pointsCopy);
139 
140         // Conjoint, overlap...left
141         System.arraycopy(points, 0, points, 1, 2);
142         checkArrayElementsEqual(points, new Point[] { pointsCopy[0], pointsCopy[0], pointsCopy[1], pointsCopy[3] });
143 
144         // Conjoint, overlap...right
145         points = createSimplePointArray();
146         System.arraycopy(points, 2, points, 1, 2);
147         checkArrayElementsEqual(points, new Point[] { pointsCopy[0], pointsCopy[2], pointsCopy[3], pointsCopy[3] });
148     }
149 
150     static Point[] createSimplePointArray() {
151         Point[] ps = new Point[4];
152         assertEquals(ps.length, 4, "Length");
153         ps.toString();
154         ps[0] = Point.createPoint(1, 2);
155         ps[1] = Point.createPoint(3, 4);
156         ps[2] = Point.createPoint(5, 6);
157         ps[3] = Point.createPoint(7, 8);
158         boolean sawOob = false;
159         try {
160             ps[ps.length] = Point.createPoint(0, 0);
161         } catch (ArrayIndexOutOfBoundsException aioobe) { sawOob = true; }
162         assertTrue(sawOob, "Didn't see AIOOBE");
163         return ps;
164     }
165 
166     static void checkSimplePointArray(Point[] points) {
167         assertEquals(points[0].x, 1, "invalid 0 point x value");
168         assertEquals(points[0].y, 2, "invalid 0 point y value");
169         assertEquals(points[1].x, 3, "invalid 1 point x value");
170         assertEquals(points[1].y, 4, "invalid 1 point y value");
171         assertEquals(points[2].x, 5, "invalid 2 point x value");
172         assertEquals(points[2].y, 6, "invalid 2 point y value");
173         assertEquals(points[3].x, 7, "invalid 3 point x value");
174         assertEquals(points[3].y, 8, "invalid 3 point y value");
175     }
176 
177     void testLong8Array() {
178         Long8Inline[] values = new Long8Inline[3];
179         assertEquals(values.length, 3, "length");
180         values.toString();
181         Long8Inline value = values[1];
182         long zl = 0;
183         Long8Inline.check(value, zl, zl, zl, zl, zl, zl, zl, zl);
184         values[1] = Long8Inline.create(1, 2, 3, 4, 5, 6, 7, 8);
185         value = values[1];
186         Long8Inline.check(value, 1, 2, 3, 4, 5, 6, 7, 8);
187 
188         Long8Inline[] copy = new Long8Inline[values.length];
189         System.arraycopy(values, 0, copy, 0, values.length);
190         value = copy[1];
191         Long8Inline.check(value, 1, 2, 3, 4, 5, 6, 7, 8);
192     }
193 
194     void testMixedPersonArray() {
195         Person[] people = new Person[3];
196 
197         people[0] = Person.create(1, "First", "Last");
198         assertEquals(people[0].getId(), 1, "Invalid Id person");
199         assertEquals(people[0].getFirstName(), "First", "Invalid First Name");
200         assertEquals(people[0].getLastName(), "Last", "Invalid Last Name");
201 
202         people[1] = Person.create(2, "Jane", "Wayne");
203         people[2] = Person.create(3, "Bob", "Dobalina");
204 
205         Person[] peopleCopy = new Person[people.length];
206         System.arraycopy(people, 0, peopleCopy, 0, people.length);
207         assertEquals(peopleCopy[2].getId(), 3, "Invalid Id");
208         assertEquals(peopleCopy[2].getFirstName(), "Bob", "Invalid First Name");
209         assertEquals(peopleCopy[2].getLastName(), "Dobalina", "Invalid Last Name");
210     }
211 
212     void testMultiDimPointArray() {
213         Point[][][] multiPoints = new Point[2][3][4];
214         assertEquals(multiPoints.length, 2, "1st dim length");
215         assertEquals(multiPoints[0].length, 3, "2st dim length");
216         assertEquals(multiPoints[0][0].length, 4, "3rd dim length");
217 
218         Point defaultPoint = multiPoints[1][2][3];
219         assertEquals(defaultPoint.x, 0, "invalid point x value");
220         assertEquals(defaultPoint.y, 0, "invalid point x value");
221     }
222 
223     void testReflectArray() {
224         // Check the java.lang.reflect.Array.newInstance methods...
225         Class<?> cls = (Class<?>) Point[].class;
226         Point[][] array = (Point[][]) Array.newInstance(cls, 1);
227         assertEquals(array.length, 1, "Incorrect length");
228         assertTrue(array[0] == null, "Expected NULL");
229 
230         Point[][][] array3 = (Point[][][]) Array.newInstance(cls, 1, 2);
231         assertEquals(array3.length, 1, "Incorrect length");
232         assertEquals(array3[0].length, 2, "Incorrect length");
233         assertTrue(array3[0][0] == null, "Expected NULL");
234 
235         // Now create ObjArrays of InlineArray...
236         Point.ref[][] barray = (Point.ref[][]) Array.newInstance(Point.ref.class, 1, 2);
237         assertEquals(barray.length, 1, "Incorrect length");
238         assertEquals(barray[0].length, 2, "Incorrect length");
239         barray[0][1] = Point.createPoint(1, 2);
240         Point.ref pb = barray[0][1];
241         int x = pb.getX();
242         assertEquals(x, 1, "Bad Point Value");
243     }
244 
245     static final primitive class MyInt implements Comparable<MyInt.ref> {
246         final int value;
247 
248         private MyInt() { this(0); }
249         private MyInt(int v) { value = v; }
250         public int getValue() { return value; }
251         public String toString() { return "MyInt: " + getValue(); }
252         public int compareTo(MyInt.ref that) { return Integer.compare(this.getValue(), that.getValue()); }
253         public boolean equals(Object o) {
254             if (o instanceof MyInt) {
255                 return this.getValue() == ((MyInt) o).getValue();
256             }
257             return false;
258         }
259 
260         public static MyInt create(int v) {
261             return new MyInt(v);
262         }
263 
264         // Null-able fields here are a temp hack to avoid ClassCircularityError
265         public static final MyInt.ref MIN = MyInt.create(Integer.MIN_VALUE);
266         public static final MyInt.ref ZERO = MyInt.create(0);
267         public static final MyInt.ref MAX = MyInt.create(Integer.MAX_VALUE);
268     }
269 
270     static MyInt staticMyInt = MyInt.create(-1);
271     static MyInt[] staticMyIntArray = new MyInt[] { staticMyInt };
272     static MyInt[][] staticMyIntArrayArray = new MyInt[][] { staticMyIntArray, staticMyIntArray };
273 
274     static interface SomeSecondaryType {
275         default String hi() { return "Hi"; }
276     }
277 
278     static final primitive class MyOtherInt implements SomeSecondaryType {
279         final int value;
280         private MyOtherInt() { value = 0; }
281     }
282 
283     void testSanityCheckcasts() {
284         MyInt[] myInts = new MyInt[1];
285         assertTrue(myInts instanceof Object[]);
286         assertTrue(myInts instanceof Comparable[]);
287         assertTrue(myInts instanceof MyInt[]);
288 
289         Class<?> cls = MyInt.class.asValueType();
290         assertTrue(cls.isValueType());
291         Object arrObj = Array.newInstance(cls, 1);
292         assertTrue(arrObj instanceof Object[], "Not Object array");
293         assertTrue(arrObj instanceof Comparable[], "Not Comparable array");
294         assertTrue(arrObj instanceof MyInt[], "Not MyInt array");
295 
296         Object[] arr = (Object[]) arrObj;
297         assertTrue(arr instanceof Comparable[], "Not Comparable array");
298         assertTrue(arr instanceof MyInt[], "Not MyInt array");
299         Comparable[] comparables = (Comparable[])arr;
300         MyInt[] myIntArr = (MyInt[]) arr;
301 
302         // multi-dim, check secondary array types are setup...
303         MyOtherInt[][] matrix = new MyOtherInt[1][1];
304         assertTrue(matrix[0] instanceof MyOtherInt[]);
305         assertTrue(matrix[0] instanceof SomeSecondaryType[]);
306         assertTrue(matrix[0] instanceof MyOtherInt.ref[]);
307 
308         // Box types vs Inline...
309         MyInt.ref[] myValueRefs = new MyInt.ref[1];
310         assertTrue(myValueRefs instanceof MyInt.ref[]);
311         assertTrue(myValueRefs instanceof Object[]);
312         assertTrue(myValueRefs instanceof Comparable[]);
313         assertFalse(myValueRefs instanceof MyInt[]);
314 
315         MyInt.ref[][] myMdValueRefs = new MyInt.ref[1][1];
316         assertTrue(myMdValueRefs[0] instanceof MyInt.ref[]);
317         assertTrue(myMdValueRefs[0] instanceof Object[]);
318         assertTrue(myMdValueRefs[0] instanceof Comparable[]);
319         assertFalse(myMdValueRefs[0] instanceof MyInt[]);
320 
321         // Did we break checkcast...
322         MyInt.ref[]     va1 = (MyInt.ref[])null;
323         MyInt.ref[]     va2 = null;
324         MyInt.ref[][]   va3 = (MyInt.ref[][])null;
325         MyInt.ref[][][] va4 = (MyInt.ref[][][])null;
326         MyInt[]      va5 = null;
327         MyInt[]      va6 = (MyInt[])null;
328         MyInt[][]    va7 = (MyInt[][])null;
329         MyInt[][][]  va8 = (MyInt[][][])null;
330     }
331 
332 
333     void testUtilArrays() {
334         // Sanity check j.u.Arrays
335 
336         // cast to q-type temp effect of avoiding circularity error (decl static MyInt.ref)
337         MyInt[] myInts = new MyInt[] { (MyInt) MyInt.MAX, (MyInt) MyInt.MIN };
338         // Sanity sort another copy
339         MyInt[] copyMyInts = (MyInt[]) Arrays.copyOf(myInts, myInts.length + 1);
340         checkArrayElementsEqual(copyMyInts, new MyInt[] { myInts[0], myInts[1], (MyInt) MyInt.ZERO});
341 
342         Arrays.sort(copyMyInts);
343         checkArrayElementsEqual(copyMyInts, new MyInt[] { (MyInt) MyInt.MIN, (MyInt) MyInt.ZERO, (MyInt) MyInt.MAX });
344 
345         List myIntList = Arrays.asList(copyMyInts);
346         checkArrayElementsEqual(copyMyInts, myIntList.toArray(new MyInt[copyMyInts.length]));
347         // This next line needs testMixedLayoutArrays to work
348         checkArrayElementsEqual(copyMyInts, myIntList.toArray());
349 
350         // Sanity check j.u.ArrayList
351         ArrayList<MyInt.ref> aList = new ArrayList<MyInt.ref>(Arrays.asList(copyMyInts));
352         assertTrue(aList.indexOf(MyInt.MIN) == 0, "Bad Index");
353         assertTrue(aList.indexOf(MyInt.ZERO) == 1, "Bad Index");
354         assertTrue(aList.indexOf(MyInt.MAX) == 2, "Bad Index");
355 
356         aList.remove(2);
357         aList.add(MyInt.create(5));
358     }
359 
360 
361     void testObjectArrayOfInlines() {
362         testSanityObjectArrays();
363         testMixedLayoutArrays();
364     }
365 
366     void testSanityObjectArrays() {
367         Object[] objects = new Object[2];
368         assertTrue(objects[0] == null && objects[1] == null, "Not null ?");
369 
370         objects[0] = MyInt.create(1);
371         objects[1] = Integer.valueOf(2);
372         assertTrue(objects[0].equals(MyInt.create(1)), "Bad Value");
373         assertTrue(objects[1].equals(Integer.valueOf(2)), "Bad Object");
374 
375         Comparable[] copyComparables = new Comparable[objects.length];
376         System.arraycopy(objects, 0, copyComparables, 0, objects.length);
377         checkArrayElementsEqual(objects, copyComparables);
378 
379         objects[0] = null;
380         objects[1] = null;
381         assertTrue(objects[0] == null && objects[1] == null, "Not null ?");
382 
383         Comparable[] comparables = new Comparable[2];
384         assertTrue(comparables[0] == null && comparables[1] == null, "Not null ?");
385         comparables[0] = MyInt.create(3);
386         comparables[1] = Integer.valueOf(4);
387         assertTrue(comparables[0].equals(MyInt.create(3)), "Bad Value");
388         assertTrue(comparables[1].equals(Integer.valueOf(4)), "Bad Object");
389 
390         Object[] copyObjects = new Object[2];
391         System.arraycopy(comparables, 0, copyObjects, 0, comparables.length);
392         checkArrayElementsEqual(comparables, copyObjects);
393 
394         comparables[0] = null;
395         comparables[1] = null;
396         assertTrue(comparables[0] == null && comparables[1] == null, "Not null ?");
397 
398         MyInt.ref[] myIntRefArray = new MyInt.ref[1];
399         assertTrue(myIntRefArray[0] == null, "Got: " + myIntRefArray[0]);
400         myIntRefArray[0] = null;
401 
402         MyInt.ref[] srcNulls = new MyInt.ref[2];
403         MyInt.ref[] dstNulls = new MyInt.ref[2];
404         System.arraycopy(srcNulls, 0, dstNulls, 0, 2);
405         checkArrayElementsEqual(srcNulls, dstNulls);
406         srcNulls[1] = MyInt.create(1);
407         System.arraycopy(srcNulls, 0, dstNulls, 0, 2);
408         checkArrayElementsEqual(srcNulls, dstNulls);
409 
410 
411         // Locked/unlocked flat array type checks
412         synchronized (srcNulls) {
413             System.arraycopy(srcNulls, 0, dstNulls, 0, 2);
414             checkArrayElementsEqual(srcNulls, dstNulls);
415             System.gc();
416         }
417         System.gc();
418         checkArrayElementsEqual(srcNulls, dstNulls);
419     }
420 
421     void testMixedLayoutArrays() {
422         Object[] objArray = new Object[3];
423         Comparable[] compArray = new Comparable[3];
424         MyInt[] valArray = new MyInt[] { (MyInt) MyInt.MIN, (MyInt) MyInt.ZERO, (MyInt) MyInt.MAX };
425 
426         arrayCopy(valArray, 0, objArray, 0, 3);
427         checkArrayElementsEqual(valArray, objArray);
428         arrayCopy(valArray, 0, objArray, 0, 3);
429 
430         objArray = new Object[3];
431         System.arraycopy(valArray, 0, objArray, 0, 3);
432         checkArrayElementsEqual(valArray, objArray);
433 
434         System.arraycopy(valArray, 0, compArray, 0, 3);
435         checkArrayElementsEqual(valArray, compArray);
436 
437         valArray = new MyInt[] { (MyInt) MyInt.ZERO, (MyInt) MyInt.ZERO, (MyInt) MyInt.ZERO };
438         System.arraycopy(compArray, 0, valArray, 0, 3);
439         checkArrayElementsEqual(valArray, compArray);
440 
441         valArray = new MyInt[] { (MyInt) MyInt.ZERO, (MyInt) MyInt.ZERO, (MyInt) MyInt.ZERO };
442         System.arraycopy(objArray, 0, valArray, 0, 3);
443         checkArrayElementsEqual(valArray, objArray);
444 
445         // Sanity check dst == src
446         System.arraycopy(valArray, 0, valArray, 0, 3);
447         checkArrayElementsEqual(valArray, objArray);
448 
449         objArray[0] = "Not an inline object";
450         try {
451             System.arraycopy(objArray, 0, valArray, 0, 3);
452             throw new RuntimeException("Expected ArrayStoreException");
453         } catch (ArrayStoreException ase) {}
454 
455         MyInt.ref[] myIntRefArray = new MyInt.ref[3];
456         System.arraycopy(valArray, 0, myIntRefArray, 0, 3);
457         checkArrayElementsEqual(valArray, myIntRefArray);
458 
459         myIntRefArray[0] = null;
460         try {
461             System.arraycopy(myIntRefArray, 0, valArray, 0, 3);
462             throw new RuntimeException("Expected NullPointerException");
463         } catch (NullPointerException npe) {}
464     }
465 
466     static final primitive class MyPoint {
467         final               MyInt x;
468         final               MyInt y;
469 
470         private MyPoint() { this(0, 0); }
471         private MyPoint(int x, int y) {
472             this.x = new MyInt(x);
473             this.y = new MyInt(y);
474         }
475         public boolean equals(Object that) {
476             if (that instanceof MyPoint) {
477                 MyPoint thatPoint = (MyPoint) that;
478                 return x.equals(thatPoint.x) && java.util.Objects.equals(y, thatPoint.y);
479             }
480             return false;
481         }
482         static MyPoint create(int x) {
483             return new MyPoint(x, x);
484         }
485         static MyPoint create(int x, int y) {
486             return new MyPoint(x, y);
487         }
488         static final MyPoint.ref ORIGIN = create(0);
489     }
490 
491     void testComposition() {
492         // Test array operations with compostion of inline types, check element payload is correct...
493         MyPoint a = MyPoint.create(1, 2);
494         MyPoint b = MyPoint.create(7, 21);
495         MyPoint c = MyPoint.create(Integer.MAX_VALUE, Integer.MIN_VALUE);
496 
497         MyPoint[] pts = new MyPoint[3];
498         if (!pts[0].equals(MyPoint.ORIGIN)) {
499             throw new RuntimeException("Equals failed: " + pts[0] + " vs " + MyPoint.ORIGIN);
500         }
501         pts = new MyPoint[] { a, b, c };
502         checkArrayElementsEqual(pts, new Object[] { a, b, c});
503         Object[] oarr = new Object[3];
504 
505         arrayCopy(pts, 0, oarr, 0, 3);
506         checkArrayElementsEqual(pts, oarr);
507 
508         oarr = new Object[3];
509         System.arraycopy(pts, 0, oarr, 0, 3);
510         checkArrayElementsEqual(pts, oarr);
511 
512         System.arraycopy(oarr, 0, pts, 0, 3);
513         checkArrayElementsEqual(pts, oarr);
514 
515         oarr = new Object[3];
516         try {
517             System.arraycopy(oarr, 0, pts, 0, 3);
518             throw new RuntimeException("Expected NPE");
519         }
520         catch (NullPointerException npe) {}
521 
522         oarr = new Object[3];
523         oarr[0] = new Object();
524         try {
525             System.arraycopy(oarr, 0, pts, 0, 3);
526             throw new RuntimeException("Expected ASE");
527         }
528         catch (ArrayStoreException ase) {}
529     }
530 
531     void checkArrayElementsEqual(MyInt[] arr1, Object[] arr2) {
532         assertTrue(arr1.length == arr2.length, "Bad length");
533         for (int i = 0; i < arr1.length; i++) {
534             assertTrue(java.util.Objects.equals(arr1[i], arr2[i]), "Element " + i + " not equal");
535         }
536     }
537 
538     void checkArrayElementsEqual(MyPoint[] arr1, Object[] arr2) {
539         assertTrue(arr1.length == arr2.length, "Bad length");
540         for (int i = 0; i < arr1.length; i++) {
541             assertTrue(java.util.Objects.equals(arr1[i], arr2[i]), "Element " + i + " not equal");
542         }
543     }
544 
545     void checkArrayElementsEqual(Object[] arr1, Object[] arr2) {
546         assertTrue(arr1.length == arr2.length, "Bad length");
547         for (int i = 0; i < arr1.length; i++) {
548             assertTrue(java.util.Objects.equals(arr1[i], arr2[i]), "Element " + i + " not equal");
549         }
550     }
551 
552     void arrayCopy(MyInt[] src, int srcPos, Object[] dst, int dstPos, int length) {
553         for (int i = 0; i < length ; i++) {
554             dst[dstPos++] = src[srcPos++];
555         }
556     }
557     void arrayCopy(MyPoint[] src, int srcPos, Object[] dst, int dstPos, int length) {
558         for (int i = 0; i < length ; i++) {
559             dst[dstPos++] = src[srcPos++];
560         }
561     }
562 
563     Object getNull() { return null; }
564 
565 
566     void testInlineArrayOom() {
567         int size = Integer.MAX_VALUE;
568         try {
569             MyPoint[] pts = new MyPoint[size];
570             throw new RuntimeException("Excepted OOM");
571         } catch (OutOfMemoryError oom) {}
572     }
573 
574 }