43 import java.text.MessageFormat;
44 import java.util.ArrayList;
45 import java.util.Date;
46 import java.util.HashSet;
47 import java.util.LinkedList;
48 import java.util.List;
49 import java.util.ListIterator;
50 import java.util.Set;
51 import java.util.stream.Stream;
52
53 import jdk.tools.jaotc.binformat.BinaryContainer;
54 import jdk.tools.jaotc.binformat.ByteContainer;
55 import jdk.tools.jaotc.collect.*;
56 import jdk.tools.jaotc.collect.classname.ClassNameSourceProvider;
57 import jdk.tools.jaotc.collect.directory.DirectorySourceProvider;
58 import jdk.tools.jaotc.collect.jar.JarSourceProvider;
59 import jdk.tools.jaotc.collect.module.ModuleSourceProvider;
60 import jdk.tools.jaotc.utils.Timer;
61
62 import org.graalvm.compiler.api.runtime.GraalJVMCICompiler;
63 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
64 import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
65 import org.graalvm.compiler.hotspot.HotSpotHostBackend;
66 import org.graalvm.compiler.java.GraphBuilderPhase;
67 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration;
68 import org.graalvm.compiler.phases.BasePhase;
69 import org.graalvm.compiler.phases.PhaseSuite;
70 import org.graalvm.compiler.phases.tiers.HighTierContext;
71 import org.graalvm.compiler.runtime.RuntimeProvider;
72
73 import jdk.vm.ci.meta.MetaAccessProvider;
74 import jdk.vm.ci.meta.ResolvedJavaMethod;
75 import jdk.vm.ci.meta.ResolvedJavaType;
76 import jdk.vm.ci.runtime.JVMCI;
77
78 public class Main implements LogPrinter {
79 static {
80 GeneratePIC.setValue(true);
81 ImmutableCode.setValue(true);
82 }
83
84 static class BadArgs extends Exception {
85 private static final long serialVersionUID = 1L;
86 final String key;
87 final Object[] args;
88 boolean showUsage;
89
90 BadArgs(String key, Object... args) {
91 super(MessageFormat.format(key, args));
92 this.key = key;
93 this.args = args;
94 }
95
96 BadArgs showUsage(boolean b) {
97 showUsage = b;
98 return this;
99 }
100 }
101
102 abstract static class Option {
103 final String help;
115 }
116
117 boolean matches(String opt) {
118 for (String a : aliases) {
119 if (a.equals(opt)) {
120 return true;
121 } else if (opt.startsWith("--") && hasArg && opt.startsWith(a + "=")) {
122 return true;
123 }
124 }
125 return false;
126 }
127
128 boolean ignoreRest() {
129 return false;
130 }
131
132 abstract void process(Main task, String opt, String arg) throws BadArgs;
133 }
134
135 static Option[] recognizedOptions = { new Option(" --output <file> Output file name", true, "--output") {
136 @Override
137 void process(Main task, String opt, String arg) {
138 String name = arg;
139 task.options.outputName = name;
140 }
141 }, new Option(" --class-name <class names> List of classes to compile", true, "--class-name", "--classname") {
142 @Override
143 void process(Main task, String opt, String arg) {
144 task.options.files.addAll(ClassSearch.makeList(ClassNameSourceProvider.TYPE, arg));
145 }
146 }, new Option(" --jar <jarfiles> List of jar files to compile", true, "--jar") {
147 @Override
148 void process(Main task, String opt, String arg) {
149 task.options.files.addAll(ClassSearch.makeList(JarSourceProvider.TYPE, arg));
150 }
151 }, new Option(" --module <modules> List of modules to compile", true, "--module") {
152 @Override
153 void process(Main task, String opt, String arg) {
154 task.options.files.addAll(ClassSearch.makeList(ModuleSourceProvider.TYPE, arg));
155 }
156 }, new Option(" --directory <dirs> List of directories where to search for files to compile", true, "--directory") {
157 @Override
158 void process(Main task, String opt, String arg) {
159 task.options.files.addAll(ClassSearch.makeList(DirectorySourceProvider.TYPE, arg));
160 }
161 }, new Option(" --search-path <dirs> List of directories where to search for specified files", true, "--search-path") {
162 @Override
163 void process(Main task, String opt, String arg) {
164 String[] elements = arg.split(":");
165 task.options.searchPath.add(elements);
166 }
167 }, new Option(" --compile-commands <file> Name of file with compile commands", true, "--compile-commands") {
168 @Override
169 void process(Main task, String opt, String arg) {
170 task.options.methodList = arg;
171 }
172 }, new Option(" --compile-for-tiered Generate profiling code for tiered compilation", false, "--compile-for-tiered") {
173 @Override
174 void process(Main task, String opt, String arg) {
175 TieredAOT.setValue(true);
176 }
177 }, new Option(" --compile-with-assertions Compile with java assertions", false, "--compile-with-assertions") {
178 @Override
179 void process(Main task, String opt, String arg) {
180 task.options.compileWithAssertions = true;
181 }
182 }, new Option(" --compile-threads <number> Number of compilation threads to be used", true, "--compile-threads", "--threads") {
183 @Override
184 void process(Main task, String opt, String arg) {
185 int threads = Integer.parseInt(arg);
186 final int available = Runtime.getRuntime().availableProcessors();
187 if (threads <= 0) {
188 task.warning("invalid number of threads specified: {0}, using: {1}", threads, available);
189 threads = available;
190 }
191 if (threads > available) {
192 task.warning("too many threads specified: {0}, limiting to: {1}", threads, available);
193 }
194 task.options.threads = Integer.min(threads, available);
195 }
248 public String methodList;
249 public List<ClassSource> sources = new ArrayList<>();
250 public String linkerpath = null;
251 public SearchPath searchPath = new SearchPath();
252
253 /**
254 * We don't see scaling beyond 16 threads.
255 */
256 private static final int COMPILER_THREADS = 16;
257
258 public int threads = Integer.min(COMPILER_THREADS, Runtime.getRuntime().availableProcessors());
259
260 public boolean ignoreClassLoadingErrors;
261 public boolean exitOnError;
262 public boolean info;
263 public boolean verbose;
264 public boolean debug;
265 public boolean help;
266 public boolean version;
267 public boolean compileWithAssertions;
268 }
269
270 /* package */final Options options = new Options();
271
272 /**
273 * Logfile.
274 */
275 private static FileWriter logFile = null;
276
277 private static final int EXIT_OK = 0; // No errors.
278 private static final int EXIT_CMDERR = 2; // Bad command-line arguments and/or switches.
279 private static final int EXIT_ABNORMAL = 4; // Terminated abnormally.
280
281 private static final String PROGNAME = "jaotc";
282
283 private static final String JVM_VERSION = System.getProperty("java.runtime.version");
284
285 public static void main(String[] args) throws Exception {
286 Main t = new Main();
287 final int exitCode = t.run(args);
334 return bytes + " B";
335 }
336
337 int exp = (int) (Math.log(bytes) / Math.log(unit));
338 char pre = "KMGTPE".charAt(exp - 1);
339 return String.format("%.1f %cB", bytes / Math.pow(unit, exp), pre);
340 }
341
342 void printMemoryUsage() {
343 if (options.verbose) {
344 MemoryUsage memusage = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
345 float freeratio = 1f - (float) memusage.getUsed() / memusage.getCommitted();
346 log.format(" [used: %-7s, comm: %-7s, freeRatio ~= %.1f%%]",
347 humanReadableByteCount(memusage.getUsed()),
348 humanReadableByteCount(memusage.getCommitted()),
349 freeratio * 100);
350 }
351 }
352
353 /**
354 * Visual Studio supported versions
355 * Search Order is: VS2013, VS2015, VS2012
356 */
357 public enum VSVERSIONS {
358 VS2013("VS120COMNTOOLS", "C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\bin\\amd64\\link.exe"),
359 VS2015("VS140COMNTOOLS", "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\bin\\amd64\\link.exe"),
360 VS2012("VS110COMNTOOLS", "C:\\Program Files (x86)\\Microsoft Visual Studio 11.0\\VC\\bin\\amd64\\link.exe");
361
362 private final String envvariable;
363 private final String wkp;
364
365 VSVERSIONS(String envvariable, String wellknownpath) {
366 this.envvariable = envvariable;
367 this.wkp = wellknownpath;
368 }
369
370 String EnvVariable() { return envvariable; }
371 String WellKnownPath() { return wkp; }
372 }
373
374 /**
375 * Search for Visual Studio link.exe
376 * Search Order is: VS2013, VS2015, VS2012
377 */
378 private static String getWindowsLinkPath() {
379 String link = "\\VC\\bin\\amd64\\link.exe";
380
381 /**
382 * First try searching the paths pointed to by
383 * the VS environment variables.
384 */
385 for (VSVERSIONS vs : VSVERSIONS.values()) {
386 String vspath = System.getenv(vs.EnvVariable());
387 if (vspath != null) {
388 File commonTools = new File(vspath);
389 File vsRoot = commonTools.getParentFile().getParentFile();
390 File linkPath = new File(vsRoot, link);
391 if (linkPath.exists()) return linkPath.getPath();
392 }
393 }
394
395 /**
396 * If we didn't find via the VS environment variables,
397 * try the well known paths
398 */
399 for (VSVERSIONS vs : VSVERSIONS.values()) {
400 String wkp = vs.WellKnownPath();
401 if (new File(wkp).exists()) {
402 return wkp;
403 }
404 }
405
406 return null;
407 }
408
409 @SuppressWarnings("try")
410 private boolean run() throws Exception {
411 openLog();
412
413 try {
414 CompilationSpec compilationRestrictions = collectSpecifiedMethods();
415
416 Set<Class<?>> classesToCompile = new HashSet<>();
417
421 lookup.addProvider(new ModuleSourceProvider());
422 lookup.addProvider(new ClassNameSourceProvider(fileSupport));
423 lookup.addProvider(new JarSourceProvider());
424 lookup.addProvider(new DirectorySourceProvider(fileSupport));
425
426 List<LoadedClass> found = null;
427 try {
428 found = lookup.search(options.files, options.searchPath);
429 } catch (InternalError e) {
430 reportError(e);
431 return false;
432 }
433
434 for (LoadedClass loadedClass : found) {
435 classesToCompile.add(loadedClass.getLoadedClass());
436 }
437
438 printInfo(classesToCompile.size() + " classes found");
439 }
440
441 GraalJVMCICompiler graalCompiler = (GraalJVMCICompiler) JVMCI.getRuntime().getCompiler();
442 HotSpotGraalRuntimeProvider runtime = (HotSpotGraalRuntimeProvider) graalCompiler.getGraalRuntime();
443 HotSpotHostBackend backend = (HotSpotHostBackend) runtime.getCapability(RuntimeProvider.class).getHostBackend();
444 MetaAccessProvider metaAccess = backend.getProviders().getMetaAccess();
445 GraalFilters filters = new GraalFilters(metaAccess);
446
447 List<AOTCompiledClass> classes;
448
449 try (Timer t = new Timer(this, "")) {
450 classes = collectMethodsToCompile(classesToCompile, compilationRestrictions, filters, metaAccess);
451 }
452
453 // Free memory!
454 try (Timer t = options.verbose ? new Timer(this, "Freeing memory") : null) {
455 printMemoryUsage();
456 compilationRestrictions = null;
457 classesToCompile = null;
458 System.gc();
459 }
460
461 AOTBackend aotBackend = new AOTBackend(this, backend, filters);
462 AOTCompiler compiler = new AOTCompiler(this, aotBackend, options.threads);
463 classes = compiler.compileClasses(classes);
464
465 GraalHotSpotVMConfig graalHotSpotVMConfig = runtime.getVMConfig();
466 PhaseSuite<HighTierContext> graphBuilderSuite = aotBackend.getGraphBuilderSuite();
467 ListIterator<BasePhase<? super HighTierContext>> iterator = graphBuilderSuite.findPhase(GraphBuilderPhase.class);
468 GraphBuilderConfiguration graphBuilderConfig = ((GraphBuilderPhase) iterator.previous()).getGraphBuilderConfig();
469
470 // Free memory!
471 try (Timer t = options.verbose ? new Timer(this, "Freeing memory") : null) {
472 printMemoryUsage();
473 aotBackend = null;
474 compiler = null;
475 System.gc();
476 }
477
478 BinaryContainer binaryContainer = new BinaryContainer(graalHotSpotVMConfig, graphBuilderConfig, JVM_VERSION);
479 DataBuilder dataBuilder = new DataBuilder(this, backend, classes, binaryContainer);
480 dataBuilder.prepareData();
481
482 // Print information about section sizes
483 printContainerInfo(binaryContainer.getHeaderContainer().getContainer());
484 printContainerInfo(binaryContainer.getConfigContainer());
485 printContainerInfo(binaryContainer.getKlassesOffsetsContainer());
486 printContainerInfo(binaryContainer.getMethodsOffsetsContainer());
487 printContainerInfo(binaryContainer.getKlassesDependenciesContainer());
488 printContainerInfo(binaryContainer.getStubsOffsetsContainer());
489 printContainerInfo(binaryContainer.getMethodMetadataContainer());
490 printContainerInfo(binaryContainer.getCodeContainer());
491 printContainerInfo(binaryContainer.getCodeSegmentsContainer());
492 printContainerInfo(binaryContainer.getConstantDataContainer());
493 printContainerInfo(binaryContainer.getMetaspaceGotContainer());
494 printContainerInfo(binaryContainer.getMetadataGotContainer());
495 printContainerInfo(binaryContainer.getMethodStateContainer());
496 printContainerInfo(binaryContainer.getOopGotContainer());
497 printContainerInfo(binaryContainer.getMetaspaceNamesContainer());
498
507 classes = null;
508 dataBuilder = null;
509 binaryContainer.freeMemory();
510 System.gc();
511 }
512
513 String name = options.outputName;
514 String objectFileName = name;
515
516 // [TODO] The jtregs tests expect .so extension so don't
517 // override with platform specific file extension until the
518 // tests are fixed.
519 String libraryFileName = name;
520
521 String linkerCmd;
522 String linkerPath;
523 String osName = System.getProperty("os.name");
524
525 if (name.endsWith(".so")) {
526 objectFileName = name.substring(0, name.length() - ".so".length());
527 }
528 else if (name.endsWith(".dylib")) {
529 objectFileName = name.substring(0, name.length() - ".dylib".length());
530 }
531 else if (name.endsWith(".dll")) {
532 objectFileName = name.substring(0, name.length() - ".dll".length());
533 }
534
535 switch (osName) {
536 case "Linux":
537 // libraryFileName = options.outputName + ".so";
538 objectFileName = objectFileName + ".o";
539 linkerPath = (options.linkerpath != null) ? options.linkerpath : "ld";
540 linkerCmd = linkerPath + " -shared -z noexecstack -o " + libraryFileName + " " + objectFileName;
541 break;
542 case "SunOS":
543 // libraryFileName = options.outputName + ".so";
544 objectFileName = objectFileName + ".o";
545 linkerPath = (options.linkerpath != null) ? options.linkerpath : "ld";
546 linkerCmd = linkerPath + " -shared -o " + libraryFileName + " " + objectFileName;
547 break;
548 case "Mac OS X":
549 // libraryFileName = options.outputName + ".dylib";
550 objectFileName = objectFileName + ".o";
551 linkerPath = (options.linkerpath != null) ? options.linkerpath : "ld";
552 linkerCmd = linkerPath + " -dylib -o " + libraryFileName + " " + objectFileName;
553 break;
554 default:
555 if (osName.startsWith("Windows")) {
556 // libraryFileName = options.outputName + ".dll";
557 objectFileName = objectFileName + ".obj";
558 linkerPath = (options.linkerpath != null) ?
559 options.linkerpath : getWindowsLinkPath();
560 if (linkerPath == null) {
561 throw new InternalError("Can't locate Microsoft Visual Studio amd64 link.exe");
562 }
563 linkerCmd = linkerPath + " /DLL /OPT:NOREF /NOLOGO /NOENTRY" + " /OUT:" + libraryFileName + " " + objectFileName;
564 break;
565 }
566 else
567 throw new InternalError("Unsupported platform: " + osName);
568 }
569
570 try (Timer t = new Timer(this, "Creating binary: " + objectFileName)) {
571 binaryContainer.createBinary(objectFileName, JVM_VERSION);
572 }
573
574 // Free memory!
575 try (Timer t = options.verbose ? new Timer(this, "Freeing memory") : null) {
576 printMemoryUsage();
577 binaryContainer = null;
578 System.gc();
579 }
580
581 try (Timer t = new Timer(this, "Creating shared library: " + libraryFileName)) {
582 Process p = Runtime.getRuntime().exec(linkerCmd);
583 final int exitCode = p.waitFor();
584 if (exitCode != 0) {
585 InputStream stderr = p.getErrorStream();
586 BufferedReader br = new BufferedReader(new InputStreamReader(stderr));
|
43 import java.text.MessageFormat;
44 import java.util.ArrayList;
45 import java.util.Date;
46 import java.util.HashSet;
47 import java.util.LinkedList;
48 import java.util.List;
49 import java.util.ListIterator;
50 import java.util.Set;
51 import java.util.stream.Stream;
52
53 import jdk.tools.jaotc.binformat.BinaryContainer;
54 import jdk.tools.jaotc.binformat.ByteContainer;
55 import jdk.tools.jaotc.collect.*;
56 import jdk.tools.jaotc.collect.classname.ClassNameSourceProvider;
57 import jdk.tools.jaotc.collect.directory.DirectorySourceProvider;
58 import jdk.tools.jaotc.collect.jar.JarSourceProvider;
59 import jdk.tools.jaotc.collect.module.ModuleSourceProvider;
60 import jdk.tools.jaotc.utils.Timer;
61
62 import org.graalvm.compiler.api.runtime.GraalJVMCICompiler;
63 import org.graalvm.compiler.hotspot.CompilerConfigurationFactory;
64 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
65 import org.graalvm.compiler.hotspot.HotSpotGraalCompilerFactory;
66 import org.graalvm.compiler.hotspot.HotSpotGraalOptionValues;
67 import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
68 import org.graalvm.compiler.hotspot.HotSpotHostBackend;
69 import org.graalvm.compiler.java.GraphBuilderPhase;
70 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration;
71 import org.graalvm.compiler.options.OptionValues;
72 import org.graalvm.compiler.phases.BasePhase;
73 import org.graalvm.compiler.phases.PhaseSuite;
74 import org.graalvm.compiler.phases.tiers.HighTierContext;
75 import org.graalvm.compiler.runtime.RuntimeProvider;
76
77 import jdk.vm.ci.meta.MetaAccessProvider;
78 import jdk.vm.ci.meta.ResolvedJavaMethod;
79 import jdk.vm.ci.meta.ResolvedJavaType;
80 import jdk.vm.ci.runtime.JVMCI;
81
82 public class Main implements LogPrinter {
83 static class BadArgs extends Exception {
84 private static final long serialVersionUID = 1L;
85 final String key;
86 final Object[] args;
87 boolean showUsage;
88
89 BadArgs(String key, Object... args) {
90 super(MessageFormat.format(key, args));
91 this.key = key;
92 this.args = args;
93 }
94
95 BadArgs showUsage(boolean b) {
96 showUsage = b;
97 return this;
98 }
99 }
100
101 abstract static class Option {
102 final String help;
114 }
115
116 boolean matches(String opt) {
117 for (String a : aliases) {
118 if (a.equals(opt)) {
119 return true;
120 } else if (opt.startsWith("--") && hasArg && opt.startsWith(a + "=")) {
121 return true;
122 }
123 }
124 return false;
125 }
126
127 boolean ignoreRest() {
128 return false;
129 }
130
131 abstract void process(Main task, String opt, String arg) throws BadArgs;
132 }
133
134 static Option[] recognizedOptions = {new Option(" --output <file> Output file name", true, "--output") {
135 @Override
136 void process(Main task, String opt, String arg) {
137 String name = arg;
138 task.options.outputName = name;
139 }
140 }, new Option(" --class-name <class names> List of classes to compile", true, "--class-name", "--classname") {
141 @Override
142 void process(Main task, String opt, String arg) {
143 task.options.files.addAll(ClassSearch.makeList(ClassNameSourceProvider.TYPE, arg));
144 }
145 }, new Option(" --jar <jarfiles> List of jar files to compile", true, "--jar") {
146 @Override
147 void process(Main task, String opt, String arg) {
148 task.options.files.addAll(ClassSearch.makeList(JarSourceProvider.TYPE, arg));
149 }
150 }, new Option(" --module <modules> List of modules to compile", true, "--module") {
151 @Override
152 void process(Main task, String opt, String arg) {
153 task.options.files.addAll(ClassSearch.makeList(ModuleSourceProvider.TYPE, arg));
154 }
155 }, new Option(" --directory <dirs> List of directories where to search for files to compile", true, "--directory") {
156 @Override
157 void process(Main task, String opt, String arg) {
158 task.options.files.addAll(ClassSearch.makeList(DirectorySourceProvider.TYPE, arg));
159 }
160 }, new Option(" --search-path <dirs> List of directories where to search for specified files", true, "--search-path") {
161 @Override
162 void process(Main task, String opt, String arg) {
163 String[] elements = arg.split(":");
164 task.options.searchPath.add(elements);
165 }
166 }, new Option(" --compile-commands <file> Name of file with compile commands", true, "--compile-commands") {
167 @Override
168 void process(Main task, String opt, String arg) {
169 task.options.methodList = arg;
170 }
171 }, new Option(" --compile-for-tiered Generate profiling code for tiered compilation", false, "--compile-for-tiered") {
172 @Override
173 void process(Main task, String opt, String arg) {
174 task.options.tiered = true;
175 }
176 }, new Option(" --compile-with-assertions Compile with java assertions", false, "--compile-with-assertions") {
177 @Override
178 void process(Main task, String opt, String arg) {
179 task.options.compileWithAssertions = true;
180 }
181 }, new Option(" --compile-threads <number> Number of compilation threads to be used", true, "--compile-threads", "--threads") {
182 @Override
183 void process(Main task, String opt, String arg) {
184 int threads = Integer.parseInt(arg);
185 final int available = Runtime.getRuntime().availableProcessors();
186 if (threads <= 0) {
187 task.warning("invalid number of threads specified: {0}, using: {1}", threads, available);
188 threads = available;
189 }
190 if (threads > available) {
191 task.warning("too many threads specified: {0}, limiting to: {1}", threads, available);
192 }
193 task.options.threads = Integer.min(threads, available);
194 }
247 public String methodList;
248 public List<ClassSource> sources = new ArrayList<>();
249 public String linkerpath = null;
250 public SearchPath searchPath = new SearchPath();
251
252 /**
253 * We don't see scaling beyond 16 threads.
254 */
255 private static final int COMPILER_THREADS = 16;
256
257 public int threads = Integer.min(COMPILER_THREADS, Runtime.getRuntime().availableProcessors());
258
259 public boolean ignoreClassLoadingErrors;
260 public boolean exitOnError;
261 public boolean info;
262 public boolean verbose;
263 public boolean debug;
264 public boolean help;
265 public boolean version;
266 public boolean compileWithAssertions;
267 public boolean tiered;
268 }
269
270 /* package */final Options options = new Options();
271
272 /**
273 * Logfile.
274 */
275 private static FileWriter logFile = null;
276
277 private static final int EXIT_OK = 0; // No errors.
278 private static final int EXIT_CMDERR = 2; // Bad command-line arguments and/or switches.
279 private static final int EXIT_ABNORMAL = 4; // Terminated abnormally.
280
281 private static final String PROGNAME = "jaotc";
282
283 private static final String JVM_VERSION = System.getProperty("java.runtime.version");
284
285 public static void main(String[] args) throws Exception {
286 Main t = new Main();
287 final int exitCode = t.run(args);
334 return bytes + " B";
335 }
336
337 int exp = (int) (Math.log(bytes) / Math.log(unit));
338 char pre = "KMGTPE".charAt(exp - 1);
339 return String.format("%.1f %cB", bytes / Math.pow(unit, exp), pre);
340 }
341
342 void printMemoryUsage() {
343 if (options.verbose) {
344 MemoryUsage memusage = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
345 float freeratio = 1f - (float) memusage.getUsed() / memusage.getCommitted();
346 log.format(" [used: %-7s, comm: %-7s, freeRatio ~= %.1f%%]",
347 humanReadableByteCount(memusage.getUsed()),
348 humanReadableByteCount(memusage.getCommitted()),
349 freeratio * 100);
350 }
351 }
352
353 /**
354 * Visual Studio supported versions Search Order is: VS2013, VS2015, VS2012
355 */
356 public enum VSVERSIONS {
357 VS2013("VS120COMNTOOLS", "C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\bin\\amd64\\link.exe"),
358 VS2015("VS140COMNTOOLS", "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\bin\\amd64\\link.exe"),
359 VS2012("VS110COMNTOOLS", "C:\\Program Files (x86)\\Microsoft Visual Studio 11.0\\VC\\bin\\amd64\\link.exe");
360
361 private final String envvariable;
362 private final String wkp;
363
364 VSVERSIONS(String envvariable, String wellknownpath) {
365 this.envvariable = envvariable;
366 this.wkp = wellknownpath;
367 }
368
369 String EnvVariable() {
370 return envvariable;
371 }
372
373 String WellKnownPath() {
374 return wkp;
375 }
376 }
377
378 /**
379 * Search for Visual Studio link.exe Search Order is: VS2013, VS2015, VS2012
380 */
381 private static String getWindowsLinkPath() {
382 String link = "\\VC\\bin\\amd64\\link.exe";
383
384 /**
385 * First try searching the paths pointed to by the VS environment variables.
386 */
387 for (VSVERSIONS vs : VSVERSIONS.values()) {
388 String vspath = System.getenv(vs.EnvVariable());
389 if (vspath != null) {
390 File commonTools = new File(vspath);
391 File vsRoot = commonTools.getParentFile().getParentFile();
392 File linkPath = new File(vsRoot, link);
393 if (linkPath.exists())
394 return linkPath.getPath();
395 }
396 }
397
398 /**
399 * If we didn't find via the VS environment variables, try the well known paths
400 */
401 for (VSVERSIONS vs : VSVERSIONS.values()) {
402 String wkp = vs.WellKnownPath();
403 if (new File(wkp).exists()) {
404 return wkp;
405 }
406 }
407
408 return null;
409 }
410
411 @SuppressWarnings("try")
412 private boolean run() throws Exception {
413 openLog();
414
415 try {
416 CompilationSpec compilationRestrictions = collectSpecifiedMethods();
417
418 Set<Class<?>> classesToCompile = new HashSet<>();
419
423 lookup.addProvider(new ModuleSourceProvider());
424 lookup.addProvider(new ClassNameSourceProvider(fileSupport));
425 lookup.addProvider(new JarSourceProvider());
426 lookup.addProvider(new DirectorySourceProvider(fileSupport));
427
428 List<LoadedClass> found = null;
429 try {
430 found = lookup.search(options.files, options.searchPath);
431 } catch (InternalError e) {
432 reportError(e);
433 return false;
434 }
435
436 for (LoadedClass loadedClass : found) {
437 classesToCompile.add(loadedClass.getLoadedClass());
438 }
439
440 printInfo(classesToCompile.size() + " classes found");
441 }
442
443 OptionValues graalOptions = HotSpotGraalOptionValues.HOTSPOT_OPTIONS;
444 // Setting -Dgraal.TieredAOT overrides --compile-for-tiered
445 if (!TieredAOT.hasBeenSet(graalOptions)) {
446 graalOptions = new OptionValues(graalOptions, TieredAOT, options.tiered);
447 }
448 graalOptions = new OptionValues(HotSpotGraalOptionValues.HOTSPOT_OPTIONS, GeneratePIC, true, ImmutableCode, true);
449 GraalJVMCICompiler graalCompiler = HotSpotGraalCompilerFactory.createCompiler(JVMCI.getRuntime(), graalOptions, CompilerConfigurationFactory.selectFactory(null, graalOptions));
450 HotSpotGraalRuntimeProvider runtime = (HotSpotGraalRuntimeProvider) graalCompiler.getGraalRuntime();
451 HotSpotHostBackend backend = (HotSpotHostBackend) runtime.getCapability(RuntimeProvider.class).getHostBackend();
452 MetaAccessProvider metaAccess = backend.getProviders().getMetaAccess();
453 GraalFilters filters = new GraalFilters(metaAccess);
454
455 List<AOTCompiledClass> classes;
456
457 try (Timer t = new Timer(this, "")) {
458 classes = collectMethodsToCompile(classesToCompile, compilationRestrictions, filters, metaAccess);
459 }
460
461 // Free memory!
462 try (Timer t = options.verbose ? new Timer(this, "Freeing memory") : null) {
463 printMemoryUsage();
464 compilationRestrictions = null;
465 classesToCompile = null;
466 System.gc();
467 }
468
469 AOTBackend aotBackend = new AOTBackend(this, graalOptions, backend, filters);
470 AOTCompiler compiler = new AOTCompiler(this, graalOptions, aotBackend, options.threads);
471 classes = compiler.compileClasses(classes);
472
473 GraalHotSpotVMConfig graalHotSpotVMConfig = runtime.getVMConfig();
474 PhaseSuite<HighTierContext> graphBuilderSuite = aotBackend.getGraphBuilderSuite();
475 ListIterator<BasePhase<? super HighTierContext>> iterator = graphBuilderSuite.findPhase(GraphBuilderPhase.class);
476 GraphBuilderConfiguration graphBuilderConfig = ((GraphBuilderPhase) iterator.previous()).getGraphBuilderConfig();
477
478 // Free memory!
479 try (Timer t = options.verbose ? new Timer(this, "Freeing memory") : null) {
480 printMemoryUsage();
481 aotBackend = null;
482 compiler = null;
483 System.gc();
484 }
485
486 BinaryContainer binaryContainer = new BinaryContainer(graalOptions, graalHotSpotVMConfig, graphBuilderConfig, JVM_VERSION);
487 DataBuilder dataBuilder = new DataBuilder(this, backend, classes, binaryContainer);
488 dataBuilder.prepareData();
489
490 // Print information about section sizes
491 printContainerInfo(binaryContainer.getHeaderContainer().getContainer());
492 printContainerInfo(binaryContainer.getConfigContainer());
493 printContainerInfo(binaryContainer.getKlassesOffsetsContainer());
494 printContainerInfo(binaryContainer.getMethodsOffsetsContainer());
495 printContainerInfo(binaryContainer.getKlassesDependenciesContainer());
496 printContainerInfo(binaryContainer.getStubsOffsetsContainer());
497 printContainerInfo(binaryContainer.getMethodMetadataContainer());
498 printContainerInfo(binaryContainer.getCodeContainer());
499 printContainerInfo(binaryContainer.getCodeSegmentsContainer());
500 printContainerInfo(binaryContainer.getConstantDataContainer());
501 printContainerInfo(binaryContainer.getMetaspaceGotContainer());
502 printContainerInfo(binaryContainer.getMetadataGotContainer());
503 printContainerInfo(binaryContainer.getMethodStateContainer());
504 printContainerInfo(binaryContainer.getOopGotContainer());
505 printContainerInfo(binaryContainer.getMetaspaceNamesContainer());
506
515 classes = null;
516 dataBuilder = null;
517 binaryContainer.freeMemory();
518 System.gc();
519 }
520
521 String name = options.outputName;
522 String objectFileName = name;
523
524 // [TODO] The jtregs tests expect .so extension so don't
525 // override with platform specific file extension until the
526 // tests are fixed.
527 String libraryFileName = name;
528
529 String linkerCmd;
530 String linkerPath;
531 String osName = System.getProperty("os.name");
532
533 if (name.endsWith(".so")) {
534 objectFileName = name.substring(0, name.length() - ".so".length());
535 } else if (name.endsWith(".dylib")) {
536 objectFileName = name.substring(0, name.length() - ".dylib".length());
537 } else if (name.endsWith(".dll")) {
538 objectFileName = name.substring(0, name.length() - ".dll".length());
539 }
540
541 switch (osName) {
542 case "Linux":
543 // libraryFileName = options.outputName + ".so";
544 objectFileName = objectFileName + ".o";
545 linkerPath = (options.linkerpath != null) ? options.linkerpath : "ld";
546 linkerCmd = linkerPath + " -shared -z noexecstack -o " + libraryFileName + " " + objectFileName;
547 break;
548 case "SunOS":
549 // libraryFileName = options.outputName + ".so";
550 objectFileName = objectFileName + ".o";
551 linkerPath = (options.linkerpath != null) ? options.linkerpath : "ld";
552 linkerCmd = linkerPath + " -shared -o " + libraryFileName + " " + objectFileName;
553 break;
554 case "Mac OS X":
555 // libraryFileName = options.outputName + ".dylib";
556 objectFileName = objectFileName + ".o";
557 linkerPath = (options.linkerpath != null) ? options.linkerpath : "ld";
558 linkerCmd = linkerPath + " -dylib -o " + libraryFileName + " " + objectFileName;
559 break;
560 default:
561 if (osName.startsWith("Windows")) {
562 // libraryFileName = options.outputName + ".dll";
563 objectFileName = objectFileName + ".obj";
564 linkerPath = (options.linkerpath != null) ? options.linkerpath : getWindowsLinkPath();
565 if (linkerPath == null) {
566 throw new InternalError("Can't locate Microsoft Visual Studio amd64 link.exe");
567 }
568 linkerCmd = linkerPath + " /DLL /OPT:NOREF /NOLOGO /NOENTRY" + " /OUT:" + libraryFileName + " " + objectFileName;
569 break;
570 } else
571 throw new InternalError("Unsupported platform: " + osName);
572 }
573
574 try (Timer t = new Timer(this, "Creating binary: " + objectFileName)) {
575 binaryContainer.createBinary(objectFileName, JVM_VERSION);
576 }
577
578 // Free memory!
579 try (Timer t = options.verbose ? new Timer(this, "Freeing memory") : null) {
580 printMemoryUsage();
581 binaryContainer = null;
582 System.gc();
583 }
584
585 try (Timer t = new Timer(this, "Creating shared library: " + libraryFileName)) {
586 Process p = Runtime.getRuntime().exec(linkerCmd);
587 final int exitCode = p.waitFor();
588 if (exitCode != 0) {
589 InputStream stderr = p.getErrorStream();
590 BufferedReader br = new BufferedReader(new InputStreamReader(stderr));
|