1 /*
2 * Copyright (c) 2026, 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 import java.util.Arrays;
26 import jdk.internal.value.ValueClass;
27
28 public class ArchivedArrayLayoutsApp {
29
30 public static class ArchivedData {
31 Point[] pointArray;
32 Point[] nullRestrictedArray;
33 Point[] nullableAtomicArray;
34 }
35
36 public static value class Point implements Comparable<Point> {
37 int x, y;
38
39 public int compareTo(Point p) {
40 return (x - p.x) - (y - p.y);
41 }
42
43 public String toString() {
44 return "(" + x + ", " + y + ")";
45 }
46
47 public Point(int x, int y) {
48 this.x = x;
49 this.y = y;
50 }
51 }
52
53 static ArchivedData archivedObjects;
54 static boolean restored;
55 static {
56 if (archivedObjects == null) {
57 restored = false;
58 System.out.println("Not archived");
59 archivedObjects = new ArchivedData();
60
61 // Point cannot be flattened and so will create a RefArrayKlass
62 archivedObjects.pointArray = new Point[3];
63 archivedObjects.pointArray[0] = new Point(0, 1);
64 archivedObjects.pointArray[1] = new Point(1, 0);
65 archivedObjects.pointArray[2] = new Point(1, 1);
66
67
68 // An array of null-restricted Point can be flattened
69 archivedObjects.nullRestrictedArray = (Point[])ValueClass.newNullRestrictedAtomicArray(Point.class, 3, new Point(0, 0));
70 archivedObjects.nullRestrictedArray[0] = new Point(0, 1);
71 archivedObjects.nullRestrictedArray[1] = new Point(1, 0);
72 archivedObjects.nullRestrictedArray[2] = new Point(1, 1);
73
74 // A nullable array of Point cannot be flattened so it will a RefArrayKlass with a different layout
75 archivedObjects.nullableAtomicArray = (Point[])ValueClass.newNullableAtomicArray(Point.class, 3);
76 archivedObjects.nullableAtomicArray[0] = new Point(0, 1);
77 archivedObjects.nullableAtomicArray[1] = new Point(1, 0);
78 archivedObjects.nullableAtomicArray[2] = new Point(1, 1);
79 } else {
80 restored = true;
81 System.out.println("Initialized from CDS");
82 }
83 }
84
85
86 public static void checkFlat(Point[] p, boolean shouldBe) throws Exception {
87 boolean isFlat = ValueClass.isFlatArray(p);
88 if (isFlat && !shouldBe) {
89 throw new RuntimeException("Should not be flat");
90 }
91 if (!isFlat && shouldBe) {
92 throw new RuntimeException("Should be flat");
93 }
94 }
95
96 public static void checkArray(Point[] p0, Point[] p1) {
97 if (Arrays.compare(p0, p1) != 0) {
98 for (Point i : p0) {
99 System.out.println(i);
100 }
101 System.out.println("vs");
102 for (Point i : p1) {
103 System.out.println(i);
104 }
105 System.out.println();
106 throw new RuntimeException("Array not restored correctly");
107 }
108 }
109
110 public static void main(String[] args) throws Exception {
111
112 checkFlat(archivedObjects.pointArray, false);
113 checkFlat(archivedObjects.nullRestrictedArray, true);
114 checkFlat(archivedObjects.nullableAtomicArray, false);
115
116 if (restored) {
117 Point[] runtimeArray = new Point[3];
118 runtimeArray[0] = new Point(0, 1);
119 runtimeArray[1] = new Point(1, 0);
120 runtimeArray[2] = new Point(1, 2);
121
122 checkArray(archivedObjects.pointArray, runtimeArray);
123 checkArray(archivedObjects.nullRestrictedArray, runtimeArray);
124 checkArray(archivedObjects.nullableAtomicArray, runtimeArray);
125 }
126
127 System.out.println("PASSED");
128 }
129 }