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 package jdk.test.lib.cds;
25
26 import java.io.File;
27 import jdk.test.lib.cds.CDSTestUtils;
28 import jdk.test.lib.process.ProcessTools;
29 import jdk.test.lib.process.OutputAnalyzer;
30 import jdk.test.lib.StringArrayUtils;
31 import jdk.test.whitebox.WhiteBox;
32 import jtreg.SkippedException;
33
34 /*
35 * This is a base class used for testing CDS functionalities with complex applications.
36 * You can define the application by overridding the vmArgs(), classpath() and appCommandLine()
37 * methods. Application-specific validation checks can be implemented with checkExecution().
38 */
39 abstract public class CDSAppTester {
40 private final String name;
41 private final String classListFile;
42 private final String classListFileLog;
43 private final String aotConfigurationFile;
44 private final String aotConfigurationFileLog;
45 private final String staticArchiveFile;
46 private final String staticArchiveFileLog;
47 private final String aotCacheFile;
48 private final String aotCacheFileLog;
49 private final String dynamicArchiveFile;
50 private final String dynamicArchiveFileLog;
51 private final String tempBaseArchiveFile;
52 private int numProductionRuns = 0;
53
54 public CDSAppTester(String name) {
55 if (CDSTestUtils.DYNAMIC_DUMP) {
56 throw new SkippedException("Tests based on CDSAppTester should be excluded when -Dtest.dynamic.cds.archive is specified");
57 }
58
59 // Old workflow
60 this.name = name;
61 classListFile = name() + ".classlist";
62 classListFileLog = classListFile + ".log";
63 aotConfigurationFile = name() + ".aotconfig";
64 aotConfigurationFileLog = aotConfigurationFile + ".log";
65 staticArchiveFile = name() + ".static.jsa";
66 staticArchiveFileLog = staticArchiveFile + ".log";
67 aotCacheFile = name() + ".aot";
68 aotCacheFileLog = aotCacheFile + ".log";
69 dynamicArchiveFile = name() + ".dynamic.jsa";
70 dynamicArchiveFileLog = dynamicArchiveFile + ".log";
71 tempBaseArchiveFile = name() + ".temp-base.jsa";
72 }
73
74 private String productionRunLog() {
75 if (numProductionRuns == 0) {
76 return name() + ".production.log";
77 } else {
78 return name() + ".production." + numProductionRuns + ".log";
79 }
80 }
81
82 private enum Workflow {
83 STATIC, // classic -Xshare:dump workflow
84 DYNAMIC, // classic -XX:ArchiveClassesAtExit
85 AOT, // JEP 483 Ahead-of-Time Class Loading & Linking
86 }
87
88 public enum RunMode {
89 TRAINING, // -XX:DumpLoadedClassList OR {-XX:AOTMode=create -XX:AOTConfiguration}
90 DUMP_STATIC, // -Xshare:dump
91 DUMP_DYNAMIC, // -XX:ArchiveClassesArExit
92 ASSEMBLY, // JEP 483
93 PRODUCTION; // Running with the CDS archive produced from the above steps
94
95 public boolean isStaticDump() {
96 return this == DUMP_STATIC;
97 }
98 public boolean isProductionRun() {
99 return this == PRODUCTION;
100 }
101 }
102
103 public final String name() {
104 return this.name;
105 }
106
107 // optional
108 public String[] vmArgs(RunMode runMode) {
109 return new String[0];
110 }
111
112 // optional
113 public String classpath(RunMode runMode) {
114 return null;
115 }
116
117 // must override
118 // main class, followed by arguments to the main class
119 abstract public String[] appCommandLine(RunMode runMode);
120
123
124 private Workflow workflow;
125 private boolean checkExitValue = true;
126
127 public final void setCheckExitValue(boolean b) {
128 checkExitValue = b;
129 }
130
131 public final boolean isStaticWorkflow() {
132 return workflow == Workflow.STATIC;
133 }
134
135 public final boolean isDynamicWorkflow() {
136 return workflow == Workflow.DYNAMIC;
137 }
138
139 public final boolean isAOTWorkflow() {
140 return workflow == Workflow.AOT;
141 }
142
143 private String logToFile(String logFile, String... logTags) {
144 StringBuilder sb = new StringBuilder("-Xlog:");
145 String prefix = "";
146 for (String tag : logTags) {
147 sb.append(prefix);
148 sb.append(tag);
149 prefix = ",";
150 }
151 sb.append(":file=" + logFile + "::filesize=0");
152 return sb.toString();
153 }
154
155 private void listOutputFile(String file) {
156 File f = new File(file);
157 if (f.exists()) {
158 System.out.println("[output file: " + file + " " + f.length() + " bytes]");
159 } else {
160 System.out.println("[output file: " + file + " does not exist]");
161 }
162 }
163
164 private OutputAnalyzer executeAndCheck(String[] cmdLine, RunMode runMode, String... logFiles) throws Exception {
165 ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder(cmdLine);
166 Process process = pb.start();
167 OutputAnalyzer output = CDSTestUtils.executeAndLog(process, runMode.toString());
168 for (String logFile : logFiles) {
169 listOutputFile(logFile);
170 }
171 if (checkExitValue) {
172 output.shouldHaveExitValue(0);
173 }
174 output.shouldNotContain(CDSTestUtils.MSG_STATIC_FIELD_MAY_HOLD_DIFFERENT_VALUE);
175 CDSTestUtils.checkCommonExecExceptions(output);
176 checkExecution(output, runMode);
177 return output;
178 }
179
180 private OutputAnalyzer recordAOTConfiguration() throws Exception {
181 RunMode runMode = RunMode.TRAINING;
182 String[] cmdLine = StringArrayUtils.concat(vmArgs(runMode),
183 "-XX:AOTMode=record",
184 "-XX:AOTConfiguration=" + aotConfigurationFile,
185 "-cp", classpath(runMode),
186 logToFile(aotConfigurationFileLog,
187 "class+load=debug"));
188 cmdLine = StringArrayUtils.concat(cmdLine, appCommandLine(runMode));
189 return executeAndCheck(cmdLine, runMode, aotConfigurationFile, aotConfigurationFileLog);
190 }
191
192 private OutputAnalyzer createClassList() throws Exception {
193 RunMode runMode = RunMode.TRAINING;
194 String[] cmdLine = StringArrayUtils.concat(vmArgs(runMode),
195 "-Xshare:off",
196 "-XX:DumpLoadedClassList=" + classListFile,
197 "-cp", classpath(runMode),
198 logToFile(classListFileLog,
199 "class+load=debug"));
200 cmdLine = StringArrayUtils.concat(cmdLine, appCommandLine(runMode));
201 return executeAndCheck(cmdLine, runMode, classListFile, classListFileLog);
202 }
203
204 private OutputAnalyzer dumpStaticArchive() throws Exception {
205 RunMode runMode = RunMode.DUMP_STATIC;
206 String[] cmdLine = StringArrayUtils.concat(vmArgs(runMode),
207 "-Xlog:cds",
268 String baseArchive = getBaseArchiveForDynamicArchive();
269 if (isDynamicWorkflow()) {
270 // "classic" dynamic archive
271 cmdLine = StringArrayUtils.concat(vmArgs(runMode),
272 "-Xlog:cds",
273 "-XX:ArchiveClassesAtExit=" + dynamicArchiveFile,
274 "-cp", classpath(runMode),
275 logToFile(dynamicArchiveFileLog,
276 "cds=debug",
277 "cds+class=debug",
278 "cds+resolve=debug",
279 "class+load=debug"));
280 }
281 if (baseArchive != null) {
282 cmdLine = StringArrayUtils.concat(cmdLine, "-XX:SharedArchiveFile=" + baseArchive);
283 }
284 cmdLine = StringArrayUtils.concat(cmdLine, appCommandLine(runMode));
285 return executeAndCheck(cmdLine, runMode, dynamicArchiveFile, dynamicArchiveFileLog);
286 }
287
288 private OutputAnalyzer productionRun() throws Exception {
289 return productionRun(null, null);
290 }
291
292 public OutputAnalyzer productionRun(String[] extraVmArgs) throws Exception {
293 return productionRun(extraVmArgs, null);
294 }
295
296 // After calling run(String[]), you can call this method to run the app again, with the AOTCache
297 // using different args to the VM and application.
298 public OutputAnalyzer productionRun(String[] extraVmArgs, String[] extraAppArgs) throws Exception {
299 RunMode runMode = RunMode.PRODUCTION;
300 String[] cmdLine = StringArrayUtils.concat(vmArgs(runMode),
301 "-XX:+UnlockDiagnosticVMOptions",
302 "-XX:VerifyArchivedFields=2", // make sure archived heap objects are good.
303 "-cp", classpath(runMode),
304 logToFile(productionRunLog(), "cds"));
305
306 if (isStaticWorkflow()) {
307 cmdLine = StringArrayUtils.concat(cmdLine, "-Xshare:on", "-XX:SharedArchiveFile=" + staticArchiveFile);
308 } else if (isDynamicWorkflow()) {
309 cmdLine = StringArrayUtils.concat(cmdLine, "-Xshare:on", "-XX:SharedArchiveFile=" + dynamicArchiveFile);
310 } else if (isAOTWorkflow()) {
311 cmdLine = StringArrayUtils.concat(cmdLine, "-XX:AOTMode=on", "-XX:AOTCache=" + aotCacheFile);
312 }
313
314 if (extraVmArgs != null) {
315 cmdLine = StringArrayUtils.concat(cmdLine, extraVmArgs);
316 }
317
318 cmdLine = StringArrayUtils.concat(cmdLine, appCommandLine(runMode));
319
320 if (extraAppArgs != null) {
321 cmdLine = StringArrayUtils.concat(cmdLine, extraAppArgs);
322 }
323
324 OutputAnalyzer out = executeAndCheck(cmdLine, runMode, productionRunLog());
325 numProductionRuns ++;
326 return out;
327 }
328
329 public void run(String args[]) throws Exception {
330 String err = "Must have exactly one command line argument of the following: ";
331 String prefix = "";
332 for (Workflow wf : Workflow.values()) {
333 err += prefix;
334 err += wf;
335 prefix = ", ";
336 }
337 if (args.length != 1) {
338 throw new RuntimeException(err);
339 } else {
340 if (args[0].equals("STATIC")) {
341 runStaticWorkflow();
342 } else if (args[0].equals("DYNAMIC")) {
343 runDynamicWorkflow();
344 } else if (args[0].equals("AOT")) {
345 runAOTWorkflow();
346 } else {
347 throw new RuntimeException(err);
348 }
349 }
350 }
351
352 private void runStaticWorkflow() throws Exception {
353 this.workflow = Workflow.STATIC;
354 createClassList();
355 dumpStaticArchive();
356 productionRun();
357 }
358
359 private void runDynamicWorkflow() throws Exception {
360 this.workflow = Workflow.DYNAMIC;
361 dumpDynamicArchive();
362 productionRun();
363 }
364
365 // See JEP 485
366 private void runAOTWorkflow() throws Exception {
367 this.workflow = Workflow.AOT;
368 recordAOTConfiguration();
369 createAOTCache();
370 productionRun();
371 }
372 }
|
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 package jdk.test.lib.cds;
25
26 import java.io.File;
27 import jdk.test.lib.cds.CDSTestUtils;
28 import jdk.test.lib.process.ProcessTools;
29 import jdk.test.lib.process.OutputAnalyzer;
30 import jdk.test.lib.StringArrayUtils;
31 import jdk.test.whitebox.WhiteBox;
32 import jtreg.SkippedException;
33
34 /*
35 * This is a base class used for testing CDS functionalities with complex applications.
36 * You can define the application by overridding the vmArgs(), classpath() and appCommandLine()
37 * methods. Application-specific validation checks can be implemented with checkExecution().
38 *
39 * Note: to debug the new workflow, run jtreg with -vmoption:-DCDSAppTester.split.new.workflow=true
40 * This will run the new workflow in two separate processes that you can rerun easily inside a debugger.
41 * Also, the log files are easier to read.
42 */
43 abstract public class CDSAppTester {
44 private final String name;
45 private final String classListFile;
46 private final String classListFileLog;
47 private final String aotConfigurationFile;
48 private final String aotConfigurationFileLog;
49 private final String staticArchiveFile;
50 private final String staticArchiveFileLog;
51 private final String aotCacheFile;
52 private final String aotCacheFileLog;
53 private final String dynamicArchiveFile;
54 private final String dynamicArchiveFileLog;
55 private final String cdsFile; // new workflow: -XX:CacheDataStore=<foo>.cds
56 private final String cdsFileLog;
57 private final String cdsFilePreImage; // new workflow: -XX:CacheDataStore=<foo>.cds
58 private final String cdsFilePreImageLog;
59 private final String tempBaseArchiveFile;
60 private int numProductionRuns = 0;
61
62 public CDSAppTester(String name) {
63 if (CDSTestUtils.DYNAMIC_DUMP) {
64 throw new SkippedException("Tests based on CDSAppTester should be excluded when -Dtest.dynamic.cds.archive is specified");
65 }
66
67 this.name = name;
68 classListFile = name() + ".classlist";
69 classListFileLog = classListFile + ".log";
70 aotConfigurationFile = name() + ".aotconfig";
71 aotConfigurationFileLog = aotConfigurationFile + ".log";
72 staticArchiveFile = name() + ".static.jsa";
73 staticArchiveFileLog = staticArchiveFile + ".log";
74 aotCacheFile = name() + ".aot";
75 aotCacheFileLog = aotCacheFile + ".log";
76 dynamicArchiveFile = name() + ".dynamic.jsa";
77 dynamicArchiveFileLog = dynamicArchiveFile + ".log";
78 cdsFile = name() + ".cds";
79 cdsFileLog = cdsFile + ".log";
80 cdsFilePreImage = cdsFile + ".preimage";
81 cdsFilePreImageLog = cdsFilePreImage + ".log";
82 tempBaseArchiveFile = name() + ".temp-base.jsa";
83 }
84
85 private String productionRunLog() {
86 if (numProductionRuns == 0) {
87 return name() + ".production.log";
88 } else {
89 return name() + ".production." + numProductionRuns + ".log";
90 }
91 }
92
93 private enum Workflow {
94 STATIC, // classic -Xshare:dump workflow
95 DYNAMIC, // classic -XX:ArchiveClassesAtExit
96 AOT, // JEP 483 Ahead-of-Time Class Loading & Linking
97 LEYDEN, // The new "one step training workflow" -- see JDK-8320264
98 }
99
100 public enum RunMode {
101 TRAINING, // -XX:DumpLoadedClassList OR {-XX:AOTMode=create -XX:AOTConfiguration}
102 TRAINING0, // LEYDEN only
103 TRAINING1, // LEYDEN only (assembly phase, app logic not executed)
104 DUMP_STATIC, // -Xshare:dump
105 DUMP_DYNAMIC, // -XX:ArchiveClassesArExit
106 ASSEMBLY, // JEP 483 (assembly phase, app logic not executed)
107 PRODUCTION; // Running with the CDS archive produced from the above steps
108
109 public boolean isStaticDump() {
110 return this == DUMP_STATIC;
111 }
112 public boolean isProductionRun() {
113 return this == PRODUCTION;
114 }
115
116 // When <code>CDSAppTester::checkExecution(out, runMode)</code> is called, has the application been
117 // executed? If so, <code>out</code> should contain logs printed by the application's own logic.
118 public boolean isApplicationExecuted() {
119 return (this != TRAINING1) && (this != ASSEMBLY) && (this != DUMP_STATIC);
120 }
121 }
122
123 public boolean isDumping(RunMode runMode) {
124 if (isStaticWorkflow()) {
125 return runMode == RunMode.DUMP_STATIC;
126 } else if (isDynamicWorkflow()) {
127 return runMode == RunMode.DUMP_DYNAMIC;
128 } else if (isAOTWorkflow()) {
129 return runMode == RunMode.TRAINING || runMode == RunMode.ASSEMBLY;
130 } else {
131 return runMode == RunMode.TRAINING || runMode == RunMode.TRAINING0 || runMode == RunMode.TRAINING1;
132 }
133 }
134
135 public final String name() {
136 return this.name;
137 }
138
139 // optional
140 public String[] vmArgs(RunMode runMode) {
141 return new String[0];
142 }
143
144 // optional
145 public String classpath(RunMode runMode) {
146 return null;
147 }
148
149 // must override
150 // main class, followed by arguments to the main class
151 abstract public String[] appCommandLine(RunMode runMode);
152
155
156 private Workflow workflow;
157 private boolean checkExitValue = true;
158
159 public final void setCheckExitValue(boolean b) {
160 checkExitValue = b;
161 }
162
163 public final boolean isStaticWorkflow() {
164 return workflow == Workflow.STATIC;
165 }
166
167 public final boolean isDynamicWorkflow() {
168 return workflow == Workflow.DYNAMIC;
169 }
170
171 public final boolean isAOTWorkflow() {
172 return workflow == Workflow.AOT;
173 }
174
175 public final boolean isLeydenWorkflow() {
176 return workflow == Workflow.LEYDEN;
177 }
178
179 private String logToFile(String logFile, String... logTags) {
180 StringBuilder sb = new StringBuilder("-Xlog:");
181 String prefix = "";
182 for (String tag : logTags) {
183 sb.append(prefix);
184 sb.append(tag);
185 prefix = ",";
186 }
187 sb.append(":file=" + logFile + "::filesize=0");
188 return sb.toString();
189 }
190
191 private void listOutputFile(String file) {
192 File f = new File(file);
193 if (f.exists()) {
194 System.out.println("[output file: " + file + " " + f.length() + " bytes]");
195 } else {
196 System.out.println("[output file: " + file + " does not exist]");
197 }
198 }
199
200 private OutputAnalyzer executeAndCheck(String[] cmdLine, RunMode runMode, String... logFiles) throws Exception {
201 ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder(cmdLine);
202 Process process = pb.start();
203 OutputAnalyzer output = CDSTestUtils.executeAndLog(process, runMode.toString());
204 for (String logFile : logFiles) {
205 listOutputFile(logFile);
206 }
207 if (checkExitValue) {
208 output.shouldHaveExitValue(0);
209 }
210 //output.shouldNotContain(CDSTestUtils.MSG_STATIC_FIELD_MAY_HOLD_DIFFERENT_VALUE); // FIXME -- leyden+JEP483 merge
211 CDSTestUtils.checkCommonExecExceptions(output);
212 checkExecution(output, runMode);
213 return output;
214 }
215
216 private OutputAnalyzer recordAOTConfiguration() throws Exception {
217 RunMode runMode = RunMode.TRAINING;
218 String[] cmdLine = StringArrayUtils.concat(vmArgs(runMode),
219 "-XX:AOTMode=record",
220 "-XX:AOTConfiguration=" + aotConfigurationFile,
221 "-cp", classpath(runMode),
222 logToFile(aotConfigurationFileLog,
223 "class+load=debug",
224 "cds=debug",
225 "cds+class=debug"));
226 cmdLine = StringArrayUtils.concat(cmdLine, appCommandLine(runMode));
227 return executeAndCheck(cmdLine, runMode, aotConfigurationFile, aotConfigurationFileLog);
228 }
229
230 private OutputAnalyzer createClassList() throws Exception {
231 RunMode runMode = RunMode.TRAINING;
232 String[] cmdLine = StringArrayUtils.concat(vmArgs(runMode),
233 "-Xshare:off",
234 "-XX:DumpLoadedClassList=" + classListFile,
235 "-cp", classpath(runMode),
236 logToFile(classListFileLog,
237 "class+load=debug"));
238 cmdLine = StringArrayUtils.concat(cmdLine, appCommandLine(runMode));
239 return executeAndCheck(cmdLine, runMode, classListFile, classListFileLog);
240 }
241
242 private OutputAnalyzer dumpStaticArchive() throws Exception {
243 RunMode runMode = RunMode.DUMP_STATIC;
244 String[] cmdLine = StringArrayUtils.concat(vmArgs(runMode),
245 "-Xlog:cds",
306 String baseArchive = getBaseArchiveForDynamicArchive();
307 if (isDynamicWorkflow()) {
308 // "classic" dynamic archive
309 cmdLine = StringArrayUtils.concat(vmArgs(runMode),
310 "-Xlog:cds",
311 "-XX:ArchiveClassesAtExit=" + dynamicArchiveFile,
312 "-cp", classpath(runMode),
313 logToFile(dynamicArchiveFileLog,
314 "cds=debug",
315 "cds+class=debug",
316 "cds+resolve=debug",
317 "class+load=debug"));
318 }
319 if (baseArchive != null) {
320 cmdLine = StringArrayUtils.concat(cmdLine, "-XX:SharedArchiveFile=" + baseArchive);
321 }
322 cmdLine = StringArrayUtils.concat(cmdLine, appCommandLine(runMode));
323 return executeAndCheck(cmdLine, runMode, dynamicArchiveFile, dynamicArchiveFileLog);
324 }
325
326 private String trainingLog(String file) {
327 return logToFile(file,
328 "cds=debug",
329 "cds+class=debug",
330 "cds+heap=warning",
331 "cds+resolve=debug");
332 }
333
334 // normal training workflow (main JVM process spawns child process)
335 private OutputAnalyzer trainingRun() throws Exception {
336 RunMode runMode = RunMode.TRAINING;
337 File f = new File(cdsFile);
338 f.delete();
339 String[] cmdLine = StringArrayUtils.concat(vmArgs(runMode),
340 "-XX:+AOTClassLinking",
341 "-XX:+ArchiveDynamicProxies",
342 //"-XX:+ArchiveReflectionData",
343 "-XX:CacheDataStore=" + cdsFile,
344 "-cp", classpath(runMode),
345 // Use PID to distinguish the logs of the training process
346 // and the forked final image dump process.
347 "-Xlog:cds::uptime,level,tags,pid",
348 trainingLog(cdsFileLog));
349 cmdLine = StringArrayUtils.concat(cmdLine, appCommandLine(runMode));
350 OutputAnalyzer out = executeAndCheck(cmdLine, runMode, cdsFile, cdsFileLog);
351 listOutputFile(cdsFile + ".log.0"); // the preimage dump
352 return out;
353 }
354
355 // "split" training workflow (launch the two processes manually, for easier debugging);
356 private OutputAnalyzer trainingRun0() throws Exception {
357 RunMode runMode = RunMode.TRAINING0;
358 File f = new File(cdsFile);
359 f.delete();
360 String[] cmdLine = StringArrayUtils.concat(vmArgs(runMode),
361 "-XX:+UnlockDiagnosticVMOptions",
362 "-XX:+CDSManualFinalImage",
363 "-XX:+AOTClassLinking",
364 "-XX:+ArchiveDynamicProxies",
365 //"-XX:+ArchiveReflectionData",
366 "-XX:CacheDataStore=" + cdsFile,
367 "-cp", classpath(runMode),
368 trainingLog(cdsFilePreImageLog));
369 cmdLine = StringArrayUtils.concat(cmdLine, appCommandLine(runMode));
370 return executeAndCheck(cmdLine, runMode, cdsFilePreImage, cdsFilePreImageLog);
371 }
372 private OutputAnalyzer trainingRun1() throws Exception {
373 RunMode runMode = RunMode.TRAINING1;
374 File f = new File(cdsFile);
375 f.delete();
376 String[] cmdLine = StringArrayUtils.concat(vmArgs(runMode),
377 "-XX:+UnlockDiagnosticVMOptions",
378 "-XX:+AOTClassLinking",
379 "-XX:+ArchiveDynamicProxies",
380 //"-XX:+ArchiveReflectionData",
381 "-XX:CacheDataStore=" + cdsFile,
382 "-XX:CDSPreimage=" + cdsFilePreImage,
383 "-cp", classpath(runMode),
384 trainingLog(cdsFileLog));
385 cmdLine = StringArrayUtils.concat(cmdLine, appCommandLine(runMode));
386 return executeAndCheck(cmdLine, runMode, cdsFile, cdsFileLog);
387 }
388
389 private OutputAnalyzer productionRun() throws Exception {
390 return productionRun(null, null);
391 }
392
393 public OutputAnalyzer productionRun(String[] extraVmArgs) throws Exception {
394 return productionRun(extraVmArgs, null);
395 }
396
397 // After calling run(String[]), you can call this method to run the app again, with the AOTCache
398 // using different args to the VM and application.
399 public OutputAnalyzer productionRun(String[] extraVmArgs, String[] extraAppArgs) throws Exception {
400 RunMode runMode = RunMode.PRODUCTION;
401 String[] cmdLine = StringArrayUtils.concat(vmArgs(runMode),
402 "-XX:+UnlockDiagnosticVMOptions",
403 "-cp", classpath(runMode),
404 logToFile(productionRunLog(), "cds"));
405
406 if (isStaticWorkflow()) {
407 cmdLine = StringArrayUtils.concat(cmdLine, "-Xshare:on", "-XX:SharedArchiveFile=" + staticArchiveFile);
408 } else if (isDynamicWorkflow()) {
409 cmdLine = StringArrayUtils.concat(cmdLine, "-Xshare:on", "-XX:SharedArchiveFile=" + dynamicArchiveFile);
410 } else if (isAOTWorkflow()) {
411 cmdLine = StringArrayUtils.concat(cmdLine, "-XX:AOTMode=on", "-XX:AOTCache=" + aotCacheFile);
412 } else {
413 cmdLine = StringArrayUtils.concat(cmdLine, "-XX:CacheDataStore=" + cdsFile);
414 }
415
416 if (extraVmArgs != null) {
417 cmdLine = StringArrayUtils.concat(cmdLine, extraVmArgs);
418 }
419
420 cmdLine = StringArrayUtils.concat(cmdLine, appCommandLine(runMode));
421
422 if (extraAppArgs != null) {
423 cmdLine = StringArrayUtils.concat(cmdLine, extraAppArgs);
424 }
425
426 OutputAnalyzer out = executeAndCheck(cmdLine, runMode, productionRunLog());
427 numProductionRuns ++;
428 return out;
429 }
430
431 public void run(String args[]) throws Exception {
432 String err = "Must have exactly one command line argument of the following: ";
433 String prefix = "";
434 for (Workflow wf : Workflow.values()) {
435 err += prefix;
436 err += wf;
437 prefix = ", ";
438 }
439 if (args.length != 1) {
440 throw new RuntimeException(err);
441 } else {
442 if (args[0].equals("STATIC")) {
443 runStaticWorkflow();
444 } else if (args[0].equals("DYNAMIC")) {
445 runDynamicWorkflow();
446 } else if (args[0].equals("AOT")) {
447 runAOTWorkflow();
448 } else if (args[0].equals("LEYDEN")) {
449 runLeydenWorkflow(false);
450 } else if (args[0].equals("LEYDEN_TRAINONLY")) {
451 runLeydenWorkflow(true);
452 } else {
453 throw new RuntimeException(err);
454 }
455 }
456 }
457
458 private void runStaticWorkflow() throws Exception {
459 this.workflow = Workflow.STATIC;
460 createClassList();
461 dumpStaticArchive();
462 productionRun();
463 }
464
465 private void runDynamicWorkflow() throws Exception {
466 this.workflow = Workflow.DYNAMIC;
467 dumpDynamicArchive();
468 productionRun();
469 }
470
471 // See JEP 485
472 private void runAOTWorkflow() throws Exception {
473 this.workflow = Workflow.AOT;
474 recordAOTConfiguration();
475 createAOTCache();
476 productionRun();
477 }
478
479 private void runLeydenWorkflow(boolean trainOnly) throws Exception {
480 this.workflow = Workflow.LEYDEN;
481 if (System.getProperty("CDSAppTester.split.new.workflow") != null) {
482 trainingRun0();
483 trainingRun1();
484 } else {
485 trainingRun();
486 }
487 if (!trainOnly) {
488 productionRun();
489 }
490 }
491 }
|