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