1 /*
2 * Copyright (c) 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 Sanity test of combinations of the AOT Code Caching diagnostic flags
28 * @requires vm.cds.supports.aot.code.caching
29 * @requires vm.compiler1.enabled & vm.compiler2.enabled
30 * @comment Both C1 and C2 JIT compilers are required because the test verifies
31 * compiler's runtime blobs generation.
32 * @requires vm.opt.VerifyOops == null | vm.opt.VerifyOops == false
33 * @comment VerifyOops flag switch off AOT code generation. Skip it.
34 * @library /test/lib /test/setup_aot
35 * @build AOTCodeFlags JavacBenchApp
36 * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar
37 * JavacBenchApp
38 * JavacBenchApp$ClassFile
39 * JavacBenchApp$FileManager
40 * JavacBenchApp$SourceFile
41 * @run driver AOTCodeFlags
42 */
43
44 import java.util.ArrayList;
45 import java.util.List;
46
47 import jdk.test.lib.cds.CDSAppTester;
48 import jdk.test.lib.process.OutputAnalyzer;
49
50 public class AOTCodeFlags {
51 public static void main(String... args) throws Exception {
52 Tester t = new Tester();
53 for (int mode = 0; mode < 4; mode++) {
54 if (mode == 2) continue; // Skip stubs until JDK-8357398 is fixed
55 t.setTestMode(mode);
56 t.run(new String[] {"AOT", "--two-step-training"});
57 }
58 }
59 static class Tester extends CDSAppTester {
60 private int testMode;
61
62 public Tester() {
63 super("AOTCodeFlags");
64 testMode = 0;
65 }
66
67 boolean isAdapterCachingOn() {
68 return (testMode == 1);
69 }
70
71 boolean isStubCachingOn() {
72 return (testMode == 2);
73 }
74
75 boolean isCodeCachingOn() {
76 return (testMode == 3);
77 }
78
79 public void setTestMode(int mode) {
80 testMode = mode;
81 }
82
83 public List<String> getVMArgsForTestMode() {
84 List<String> list = new ArrayList<String>();
85 list.add("-XX:+UnlockDiagnosticVMOptions");
86 list.add(isAdapterCachingOn() ? "-XX:+AOTAdapterCaching" : "-XX:-AOTAdapterCaching");
87 list.add(isStubCachingOn() ? "-XX:+AOTStubCaching" : "-XX:-AOTStubCaching");
88 list.add(isCodeCachingOn() ? "-XX:+AOTCodeCaching" : "-XX:-AOTCodeCaching");
89 return list;
90 }
91
92 @Override
93 public String classpath(RunMode runMode) {
94 return "app.jar";
95 }
96
97 @Override
98 public String[] vmArgs(RunMode runMode) {
99 switch (runMode) {
100 case RunMode.ASSEMBLY:
101 case RunMode.PRODUCTION: {
102 List<String> args = getVMArgsForTestMode();
103 args.addAll(List.of("-Xlog:aot+codecache+init=debug",
104 "-Xlog:aot+codecache+exit=debug"));
105 return args.toArray(new String[0]);
106 }
107 }
108 return new String[] {};
109 }
110
111 @Override
112 public String[] appCommandLine(RunMode runMode) {
113 return new String[] {
114 "JavacBenchApp", "10"
115 };
116 }
117
118 @Override
119 public void checkExecution(OutputAnalyzer out, RunMode runMode) throws Exception {
120 if (!isAdapterCachingOn() && !isStubCachingOn() && !isCodeCachingOn()) { // this is equivalent to completely disable AOT code cache
121 switch (runMode) {
122 case RunMode.ASSEMBLY:
123 case RunMode.PRODUCTION:
124 out.shouldNotMatch("Adapter:\\s+total");
125 out.shouldNotMatch("SharedBlob:\\s+total");
126 out.shouldNotMatch("C1Blob:\\s+total");
127 out.shouldNotMatch("C2Blob:\\s+total");
128 out.shouldNotMatch("Stub:\\s+total");
129 out.shouldNotMatch("Nmethod:\\s+total");
130 break;
131 }
132 } else {
133 if (isAdapterCachingOn()) {
134 switch (runMode) {
135 case RunMode.ASSEMBLY:
136 case RunMode.PRODUCTION:
137 // AOTAdapterCaching is on, non-zero adapters should be stored/loaded
138 out.shouldMatch("Adapter:\\s+total=[1-9][0-9]+");
139 break;
140 }
141 } else {
142 switch (runMode) {
143 case RunMode.ASSEMBLY:
144 case RunMode.PRODUCTION:
145 // AOTAdapterCaching is off, no adapters should be stored/loaded
146 out.shouldMatch("Adapter:\\s+total=0");
147 break;
148 }
149 }
150 if (isStubCachingOn()) {
151 switch (runMode) {
152 case RunMode.ASSEMBLY:
153 case RunMode.PRODUCTION:
154 // AOTStubCaching is on, non-zero stubs should be stored/loaded
155 out.shouldMatch("SharedBlob:\\s+total=[1-9][0-9]+");
156 out.shouldMatch("C1Blob:\\s+total=[1-9][0-9]+");
157 out.shouldMatch("C2Blob:\\s+total=[1-9][0-9]+");
158 out.shouldMatch("Stub:\\s+total=[1-9]+");
159 break;
160 }
161 } else {
162 switch (runMode) {
163 case RunMode.ASSEMBLY:
164 case RunMode.PRODUCTION:
165 // AOTStubCaching is off, no stubs should be stored/loaded
166 out.shouldMatch("SharedBlob:\\s+total=0");
167 out.shouldMatch("C1Blob:\\s+total=0");
168 out.shouldMatch("C2Blob:\\s+total=0");
169 out.shouldMatch("Stub:\\s+total=0");
170 break;
171 }
172 }
173 if (isCodeCachingOn()) {
174 switch (runMode) {
175 case RunMode.ASSEMBLY:
176 case RunMode.PRODUCTION:
177 // AOTAdapterCaching is on, non-zero adapters should be stored/loaded
178 out.shouldMatch("Nmethod:\\s+total=[1-9]+");
179 break;
180 }
181 } else {
182 switch (runMode) {
183 case RunMode.ASSEMBLY:
184 case RunMode.PRODUCTION:
185 // AOTAdapterCaching is off, no adapters should be stored/loaded
186 out.shouldMatch("Nmethod:\\s+total=0");
187 break;
188 }
189 }
190 }
191 }
192 }
193 }