< prev index next >

test/lib/jdk/test/lib/cds/CDSAppTester.java

Print this page

 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 }
< prev index next >