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 import jdk.internal.misc.PreviewFeatures;
 25 import jdk.internal.value.ValueClass;
 26 import jdk.internal.vm.annotation.NullRestricted;
 27 
 28 // Test app for flat arrays in the AOT map
 29 public class AOTMapTestApp {
 30 
 31     public static value class Wrapper implements Comparable<Wrapper> {
 32         Integer i;
 33 
 34         public String toString() {
 35             return i.toString();
 36         }
 37 
 38         public int compareTo(Wrapper o) {
 39             return i - o.i;
 40         }
 41 
 42         Wrapper(int i) {
 43             this.i = new Integer(i);
 44         }
 45     }
 46 
 47     public static value class WrapperWrapper {
 48         Wrapper w;
 49 
 50         WrapperWrapper(int i) {
 51             this.w = new Wrapper(i);
 52         }
 53     }
 54 
 55     // Check that arrays of both migrated value
 56     // classes and custom value classes are archived
 57     public static class ArchivedData {
 58         Integer[] boxArray;
 59         Integer[] nullFreeBoxArray;
 60         Wrapper[] wrapperArray;
 61         WrapperWrapper[] wrapperWrapperArray;
 62         Object[] objArray;
 63         Wrapper wrapper;
 64         @NullRestricted
 65         WrapperWrapper wrapperWrapper;
 66         int a;
 67         Object b;
 68 
 69         ArchivedData() {
 70             boxArray = new Integer[3];  // flattened
 71             boxArray[0] = new Integer(0xaaaa);
 72             boxArray[1] = new Integer(0xbbbb);
 73             boxArray[2] = null;
 74 
 75             nullFreeBoxArray = (Integer[])ValueClass.newNullRestrictedAtomicArray(Integer.class, 3, new Integer(0));
 76             nullFreeBoxArray[0] = new Integer(0xaaaa);
 77             nullFreeBoxArray[1] = new Integer(0xbbbb);
 78             nullFreeBoxArray[2] = new Integer(0xcccc);
 79 
 80             wrapperArray = new Wrapper[3]; // flattened
 81             wrapperArray[0] = new Wrapper(0xaaaa);
 82             wrapperArray[1] = new Wrapper(0xbbbb);
 83             wrapperArray[2] = new Wrapper(0xcccc);
 84 
 85             wrapperWrapperArray = new WrapperWrapper[3];
 86             wrapperWrapperArray[0] = new WrapperWrapper(0xaaaa);
 87             wrapperWrapperArray[1] = new WrapperWrapper(0xbbbb);
 88             wrapperWrapperArray[2] = new WrapperWrapper(0xcccc);
 89 
 90             objArray = new Object[3]; // not flattened
 91             objArray[0] = new Integer(0xaaaa);
 92             objArray[1] = new Integer(0xbbbb);
 93             objArray[2] = new Integer(0xcccc);
 94 
 95             wrapper = new Wrapper(0xaaaa5555);
 96             wrapperWrapper = new WrapperWrapper(0xbbbb6666);
 97             a = 0x7788;
 98             b = new Integer(0x8899);
 99         }
100     }
101 
102     static ArchivedData archivedObjects;
103     static {
104         if (archivedObjects == null) {
105             archivedObjects = new ArchivedData();
106         } else {
107             System.out.println("Initialized from CDS");
108             System.out.println("boxArray " + archivedObjects.boxArray);
109             System.out.println("wrapperArray " + archivedObjects.wrapperArray);
110             System.out.println("wrapperWrapperArray " + archivedObjects.wrapperWrapperArray);
111             System.out.println("objArray " + archivedObjects.objArray);
112             System.out.println("wrapper " + archivedObjects.wrapper);
113             System.out.println("wrapperWrapper " + archivedObjects.wrapperWrapper);
114             System.out.println("a " + archivedObjects.a);
115             System.out.println("b " + archivedObjects.b);
116         }
117     }
118 
119     public static void main(String[] args) throws Exception {
120         System.out.println("Hello FlatAOTMapTestApp");
121         Class.forName("Hello");
122 
123         if (PreviewFeatures.isEnabled() && !ValueClass.isFlatArray(archivedObjects.boxArray)) {
124             throw new RuntimeException("Boxing class array should be flat");
125         }
126 
127         if (PreviewFeatures.isEnabled() && (!ValueClass.isNullRestrictedArray(archivedObjects.nullFreeBoxArray) ||
128             !ValueClass.isFlatArray(archivedObjects.nullFreeBoxArray))) {
129             throw new RuntimeException("Boxing class array should be null-free and flat");
130         }
131 
132         if (PreviewFeatures.isEnabled() && !ValueClass.isFlatArray(archivedObjects.wrapperArray)) {
133             throw new RuntimeException("Wrapper array should be flat");
134         }
135 
136         if (PreviewFeatures.isEnabled() && !ValueClass.isFlatArray(archivedObjects.wrapperWrapperArray)) {
137             throw new RuntimeException("WrapperWrapper array should be flat");
138         }
139 
140         if (PreviewFeatures.isEnabled() && ValueClass.isFlatArray(archivedObjects.objArray)) {
141             throw new RuntimeException("Object array should not be flat");
142         }
143     }
144 }