1 /*
  2  * Copyright (c) 2018, 2025, 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 /*
 26  * @test
 27  * @summary Test primitive box caches integrity in various scenarios (IntegerCache etc)
 28  * @requires !java.enablePreview
 29  * @requires vm.cds.write.archived.java.heap
 30  * @library /test/jdk/lib/testlibrary /test/lib /test/hotspot/jtreg/runtime/cds/appcds
 31  * @compile --add-exports java.base/jdk.internal.misc=ALL-UNNAMED CheckIntegerCacheApp.java ArchivedIntegerHolder.java
 32  * @build jdk.test.whitebox.WhiteBox
 33  * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar WhiteBox.jar jdk.test.whitebox.WhiteBox
 34  * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar boxCache.jar CheckIntegerCacheApp
 35  * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar boxCache-boot.jar ArchivedIntegerHolder
 36  * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:./WhiteBox.jar ArchivedIntegerCacheTest
 37  */
 38 
 39 import java.nio.file.Files;
 40 import java.nio.file.Path;
 41 import java.nio.file.Paths;
 42 import jdk.test.lib.cds.CDSTestUtils;
 43 import jdk.test.lib.process.OutputAnalyzer;
 44 import jdk.test.lib.helpers.ClassFileInstaller;
 45 import jdk.test.whitebox.WhiteBox;
 46 
 47 public class ArchivedIntegerCacheTest {
 48     private static WhiteBox WB = WhiteBox.getWhiteBox();
 49 
 50     public static String[] mixArgs(String... args) {
 51         String bootJar = ClassFileInstaller.getJarPath("boxCache-boot.jar");
 52 
 53         String[] newArgs = new String[args.length + 5];
 54         newArgs[0] = "--add-exports";
 55         newArgs[1] = "java.base/jdk.internal.misc=ALL-UNNAMED";
 56         newArgs[2] = "-Xbootclasspath/a:" + bootJar;
 57         newArgs[3] = "-XX:+IgnoreUnrecognizedVMOptions";
 58         newArgs[4] = "-XX:ArchiveHeapTestClass=ArchivedIntegerHolder";
 59         System.arraycopy(args, 0, newArgs, 5, args.length);
 60         return newArgs;
 61     }
 62 
 63     public static void main(String[] args) throws Exception {
 64         String appJar = ClassFileInstaller.getJarPath("boxCache.jar");
 65 
 66         Path userDir = Paths.get(CDSTestUtils.getOutputDir());
 67         Path moduleDir = Files.createTempDirectory(userDir, "mods");
 68 
 69         //
 70         // Dump default archive
 71         //
 72         OutputAnalyzer output = TestCommon.dump(appJar,
 73                 TestCommon.list("CheckIntegerCacheApp"),
 74                 mixArgs());
 75         TestCommon.checkDump(output);
 76 
 77         // Test case 1)
 78         // - Default options
 79         System.out.println("----------------------- Test case 1 ----------------------");
 80         output = TestCommon.exec(appJar,
 81                 mixArgs("CheckIntegerCacheApp", "127"));
 82         TestCommon.checkExec(output);
 83 
 84         // Test case 2)
 85         // - Default archive
 86         // - Larger -XX:AutoBoxCacheMax
 87         System.out.println("----------------------- Test case 2 ----------------------");
 88         output = TestCommon.exec(appJar,
 89                 mixArgs("-XX:AutoBoxCacheMax=20000",
 90                         "CheckIntegerCacheApp", "20000"));
 91         TestCommon.checkExec(output);
 92 
 93         //
 94         // Dump with -XX:AutoBoxCacheMax specified
 95         //
 96         output = TestCommon.dump(appJar,
 97                 TestCommon.list("CheckIntegerCacheApp"),
 98                 mixArgs("-XX:AutoBoxCacheMax=20000"));
 99         TestCommon.checkDump(output);
100 
101         // Test case 3)
102         // - Large archived cache
103         // - Default options
104         System.out.println("----------------------- Test case 3 ----------------------");
105         output = TestCommon.exec(appJar,
106                 mixArgs("--module-path", moduleDir.toString(),
107                         "CheckIntegerCacheApp", "127"));
108         TestCommon.checkExec(output);
109 
110 
111         // Test case 4)
112         // - Large archived cache
113         // - Matching options
114         System.out.println("----------------------- Test case 4 ----------------------");
115         output = TestCommon.exec(appJar,
116                 mixArgs("--module-path", moduleDir.toString(),
117                         "-XX:AutoBoxCacheMax=20000",
118                         "CheckIntegerCacheApp", "20000"));
119         TestCommon.checkExec(output);
120 
121         // Test case 5)
122         // - Large archived cache
123         // - Larger requested cache
124         System.out.println("----------------------- Test case 5 ----------------------");
125         output = TestCommon.exec(appJar,
126                 mixArgs("--module-path", moduleDir.toString(),
127                         "-XX:AutoBoxCacheMax=30000",
128                         "CheckIntegerCacheApp", "30000"));
129         TestCommon.checkExec(output);
130 
131         // Test case 6)
132         // - Cache is too large to archive
133         output = TestCommon.dump(appJar,
134                 TestCommon.list("CheckIntegerCacheApp"),
135                 mixArgs("-XX:AutoBoxCacheMax=2000000",
136                         "-Xmx1g",
137                         "-XX:NewSize=1g",
138                         "-Xlog:cds+heap=info",
139                         "-Xlog:gc+region+cds",
140                         "-Xlog:gc+region=trace"));
141         if (WB.canWriteMappedJavaHeapArchive()) {
142             // The mapping AOT heap archiving mechanism is unable to cache larger objects.
143             TestCommon.checkDump(output, "Cannot archive the sub-graph referenced from [Ljava.lang.Integer; object");
144         }
145     }
146 }