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