1 /*
2 * Copyright (c) 2016, 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 */
117 return false;
118 }
119
120 abstract void process(Main task, String opt, String arg) throws BadArgs;
121 }
122
123 static Option[] recognizedOptions = {new Option(" --module <name> Module to compile", true, "--module") {
124 @Override
125 void process(Main task, String opt, String arg) {
126 task.options.module = arg;
127 }
128 }, new Option(" --module-path <path> Specify where to find module to compile", true, "--module-path") {
129 @Override
130 void process(Main task, String opt, String arg) {
131 task.options.modulepath = arg;
132 }
133 }, new Option(" --output <file> Output file name", true, "--output") {
134 @Override
135 void process(Main task, String opt, String arg) {
136 String name = arg;
137 if (name.endsWith(".so")) {
138 name = name.substring(0, name.length() - ".so".length());
139 }
140 task.options.outputName = name;
141 }
142 }, new Option(" --compile-commands <file> Name of file with compile commands", true, "--compile-commands") {
143 @Override
144 void process(Main task, String opt, String arg) {
145 task.options.methodList = arg;
146 }
147 }, new Option(" --compile-for-tiered Generated profiling code for tiered compilation", false, "--compile-for-tiered") {
148 @Override
149 void process(Main task, String opt, String arg) {
150 TieredAOT.setValue(true);
151 }
152 }, new Option(" --classpath <path> Specify where to find user class files", true, "--classpath", "--class-path") {
153 @Override
154 void process(Main task, String opt, String arg) {
155 task.options.classpath = arg;
156 }
157 }, new Option(" --threads <number> Number of compilation threads to be used", true, "--threads") {
158 @Override
159 void process(Main task, String opt, String arg) {
199 }, new Option(" --help Print this usage message", false, "--help") {
200 @Override
201 void process(Main task, String opt, String arg) {
202 task.options.help = true;
203 }
204 }, new Option(" --version Version information", false, "--version") {
205 @Override
206 void process(Main task, String opt, String arg) {
207 task.options.version = true;
208 }
209 }, new Option(" -J<flag> Pass <flag> directly to the runtime system", false, "-J") {
210 @Override
211 void process(Main task, String opt, String arg) {
212 }
213 }};
214
215 public static class Options {
216 public List<String> files = new LinkedList<>();
217 public String module = null;
218 public String modulepath = "modules";
219 public String outputName = "unnamed";
220 public String methodList;
221 public String classpath = ".";
222
223 /**
224 * We don't see scaling beyond 16 threads.
225 */
226 private static final int COMPILER_THREADS = 16;
227
228 int threads = Integer.min(COMPILER_THREADS, Runtime.getRuntime().availableProcessors());
229
230 public boolean ignoreClassLoadingErrors;
231 public boolean exitOnError;
232 boolean info;
233 boolean verbose;
234 boolean debug;
235 boolean help;
236 boolean version;
237 }
238
239 /* package */final Options options = new Options();
300 if (bytes < unit) {
301 return bytes + " B";
302 }
303
304 int exp = (int) (Math.log(bytes) / Math.log(unit));
305 char pre = "KMGTPE".charAt(exp - 1);
306 return String.format("%.1f %cB", bytes / Math.pow(unit, exp), pre);
307 }
308
309 void printMemoryUsage() {
310 if (options.verbose) {
311 MemoryUsage memusage = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
312 float freeratio = 1f - (float) memusage.getUsed() / memusage.getCommitted();
313 log.format(" [used: %-7s, comm: %-7s, freeRatio ~= %.1f%%]",
314 humanReadableByteCount(memusage.getUsed()),
315 humanReadableByteCount(memusage.getCommitted()),
316 freeratio * 100);
317 }
318 }
319
320 @SuppressWarnings("try")
321 private void run() throws Exception {
322 openLog();
323
324 try {
325 CompilationSpec compilationRestrictions = collectSpecifiedMethods();
326
327 Set<Class<?>> classesToCompile;
328
329 try (Timer t = new Timer(this, "")) {
330 ClassCollector collector = new ClassCollector(this.options, this);
331 classesToCompile = collector.collectClassesToCompile();
332 printInfo(classesToCompile.size() + " classes found");
333 }
334
335 GraalJVMCICompiler graalCompiler = (GraalJVMCICompiler) JVMCI.getRuntime().getCompiler();
336 HotSpotGraalRuntimeProvider runtime = (HotSpotGraalRuntimeProvider) graalCompiler.getGraalRuntime();
337 HotSpotHostBackend backend = (HotSpotHostBackend) runtime.getCapability(RuntimeProvider.class).getHostBackend();
338 MetaAccessProvider metaAccess = backend.getProviders().getMetaAccess();
339 GraalFilters filters = new GraalFilters(metaAccess);
382 printContainerInfo(binaryContainer.getMetaspaceGotContainer());
383 printContainerInfo(binaryContainer.getMetadataGotContainer());
384 printContainerInfo(binaryContainer.getMethodStateContainer());
385 printContainerInfo(binaryContainer.getOopGotContainer());
386 printContainerInfo(binaryContainer.getMetaspaceNamesContainer());
387
388 // Free memory!
389 try (Timer t = options.verbose ? new Timer(this, "Freeing memory") : null) {
390 printMemoryUsage();
391 backend = null;
392 for (AOTCompiledClass aotCompClass : classes) {
393 aotCompClass.clear();
394 }
395 classes.clear();
396 classes = null;
397 dataBuilder = null;
398 binaryContainer.freeMemory();
399 System.gc();
400 }
401
402 String objectFileName = options.outputName + ".o";
403 String libraryFileName = options.outputName + ".so";
404
405 try (Timer t = new Timer(this, "Creating binary: " + objectFileName)) {
406 binaryContainer.createBinary(objectFileName, JVM_VERSION);
407 }
408
409 // Free memory!
410 try (Timer t = options.verbose ? new Timer(this, "Freeing memory") : null) {
411 printMemoryUsage();
412 binaryContainer = null;
413 System.gc();
414 }
415
416 try (Timer t = new Timer(this, "Creating shared library: " + libraryFileName)) {
417 Process p = Runtime.getRuntime().exec("ld -shared -z noexecstack -o " + libraryFileName + " " + objectFileName);
418 final int exitCode = p.waitFor();
419 if (exitCode != 0) {
420 InputStream stderr = p.getErrorStream();
421 BufferedReader br = new BufferedReader(new InputStreamReader(stderr));
422 Stream<String> lines = br.lines();
423 StringBuilder sb = new StringBuilder();
424 lines.iterator().forEachRemaining(e -> sb.append(e));
425 throw new InternalError(sb.toString());
426 }
427 File objFile = new File(objectFileName);
428 if (objFile.exists()) {
429 if (!objFile.delete()) {
430 throw new InternalError("Failed to delete " + objectFileName + " file");
431 }
432 }
433 // Make non-executable for all.
434 File libFile = new File(libraryFileName);
435 if (libFile.exists()) {
436 if (!libFile.setExecutable(false, false)) {
437 throw new InternalError("Failed to change attribute for " + libraryFileName + " file");
438 }
439 }
440 }
441
442 printVerbose("Final memory ");
443 printMemoryUsage();
444 printlnVerbose("");
445
446 } finally {
447 closeLog();
448 }
449 }
450
451 private void addMethods(AOTCompiledClass aotClass, ResolvedJavaMethod[] methods, CompilationSpec compilationRestrictions, GraalFilters filters) {
452 for (ResolvedJavaMethod m : methods) {
453 addMethod(aotClass, m, compilationRestrictions, filters);
454 }
455 }
|
1 /*
2 * Copyright (c) 2016, 2017, 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 */
117 return false;
118 }
119
120 abstract void process(Main task, String opt, String arg) throws BadArgs;
121 }
122
123 static Option[] recognizedOptions = {new Option(" --module <name> Module to compile", true, "--module") {
124 @Override
125 void process(Main task, String opt, String arg) {
126 task.options.module = arg;
127 }
128 }, new Option(" --module-path <path> Specify where to find module to compile", true, "--module-path") {
129 @Override
130 void process(Main task, String opt, String arg) {
131 task.options.modulepath = arg;
132 }
133 }, new Option(" --output <file> Output file name", true, "--output") {
134 @Override
135 void process(Main task, String opt, String arg) {
136 String name = arg;
137 task.options.outputName = name;
138 }
139 }, new Option(" --compile-commands <file> Name of file with compile commands", true, "--compile-commands") {
140 @Override
141 void process(Main task, String opt, String arg) {
142 task.options.methodList = arg;
143 }
144 }, new Option(" --compile-for-tiered Generated profiling code for tiered compilation", false, "--compile-for-tiered") {
145 @Override
146 void process(Main task, String opt, String arg) {
147 TieredAOT.setValue(true);
148 }
149 }, new Option(" --classpath <path> Specify where to find user class files", true, "--classpath", "--class-path") {
150 @Override
151 void process(Main task, String opt, String arg) {
152 task.options.classpath = arg;
153 }
154 }, new Option(" --threads <number> Number of compilation threads to be used", true, "--threads") {
155 @Override
156 void process(Main task, String opt, String arg) {
196 }, new Option(" --help Print this usage message", false, "--help") {
197 @Override
198 void process(Main task, String opt, String arg) {
199 task.options.help = true;
200 }
201 }, new Option(" --version Version information", false, "--version") {
202 @Override
203 void process(Main task, String opt, String arg) {
204 task.options.version = true;
205 }
206 }, new Option(" -J<flag> Pass <flag> directly to the runtime system", false, "-J") {
207 @Override
208 void process(Main task, String opt, String arg) {
209 }
210 }};
211
212 public static class Options {
213 public List<String> files = new LinkedList<>();
214 public String module = null;
215 public String modulepath = "modules";
216 public String outputName = "unnamed.so";
217 public String methodList;
218 public String classpath = ".";
219
220 /**
221 * We don't see scaling beyond 16 threads.
222 */
223 private static final int COMPILER_THREADS = 16;
224
225 int threads = Integer.min(COMPILER_THREADS, Runtime.getRuntime().availableProcessors());
226
227 public boolean ignoreClassLoadingErrors;
228 public boolean exitOnError;
229 boolean info;
230 boolean verbose;
231 boolean debug;
232 boolean help;
233 boolean version;
234 }
235
236 /* package */final Options options = new Options();
297 if (bytes < unit) {
298 return bytes + " B";
299 }
300
301 int exp = (int) (Math.log(bytes) / Math.log(unit));
302 char pre = "KMGTPE".charAt(exp - 1);
303 return String.format("%.1f %cB", bytes / Math.pow(unit, exp), pre);
304 }
305
306 void printMemoryUsage() {
307 if (options.verbose) {
308 MemoryUsage memusage = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
309 float freeratio = 1f - (float) memusage.getUsed() / memusage.getCommitted();
310 log.format(" [used: %-7s, comm: %-7s, freeRatio ~= %.1f%%]",
311 humanReadableByteCount(memusage.getUsed()),
312 humanReadableByteCount(memusage.getCommitted()),
313 freeratio * 100);
314 }
315 }
316
317 /**
318 * Search for Visual Studio link.exe
319 * Search Order is: VS2013, VS2015, VS2012
320 */
321 private String getWindowsLinkPath() {
322 String vs2013 = "C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\bin\\amd64\\link.exe";
323 String vs2015 = "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\bin\\amd64\\link.exe";
324 String vs2012 = "C:\\Program Files (x86)\\Microsoft Visual Studio 11.0\\VC\\bin\\amd64\\link.exe";
325
326 if (new File(vs2015).exists()) return vs2015;
327 if (new File(vs2013).exists()) return vs2013;
328 if (new File(vs2012).exists()) return vs2012;
329 return null;
330 }
331
332 @SuppressWarnings("try")
333 private void run() throws Exception {
334 openLog();
335
336 try {
337 CompilationSpec compilationRestrictions = collectSpecifiedMethods();
338
339 Set<Class<?>> classesToCompile;
340
341 try (Timer t = new Timer(this, "")) {
342 ClassCollector collector = new ClassCollector(this.options, this);
343 classesToCompile = collector.collectClassesToCompile();
344 printInfo(classesToCompile.size() + " classes found");
345 }
346
347 GraalJVMCICompiler graalCompiler = (GraalJVMCICompiler) JVMCI.getRuntime().getCompiler();
348 HotSpotGraalRuntimeProvider runtime = (HotSpotGraalRuntimeProvider) graalCompiler.getGraalRuntime();
349 HotSpotHostBackend backend = (HotSpotHostBackend) runtime.getCapability(RuntimeProvider.class).getHostBackend();
350 MetaAccessProvider metaAccess = backend.getProviders().getMetaAccess();
351 GraalFilters filters = new GraalFilters(metaAccess);
394 printContainerInfo(binaryContainer.getMetaspaceGotContainer());
395 printContainerInfo(binaryContainer.getMetadataGotContainer());
396 printContainerInfo(binaryContainer.getMethodStateContainer());
397 printContainerInfo(binaryContainer.getOopGotContainer());
398 printContainerInfo(binaryContainer.getMetaspaceNamesContainer());
399
400 // Free memory!
401 try (Timer t = options.verbose ? new Timer(this, "Freeing memory") : null) {
402 printMemoryUsage();
403 backend = null;
404 for (AOTCompiledClass aotCompClass : classes) {
405 aotCompClass.clear();
406 }
407 classes.clear();
408 classes = null;
409 dataBuilder = null;
410 binaryContainer.freeMemory();
411 System.gc();
412 }
413
414 String name = options.outputName;
415 String objectFileName = name;
416
417 // [TODO] The jtregs tests expect .so extension so don't
418 // override with platform specific file extension until the
419 // tests are fixed.
420 String libraryFileName = name;
421
422 String ldCmd;
423 String osName = System.getProperty("os.name");
424
425 if (name.endsWith(".so")) {
426 objectFileName = name.substring(0, name.length() - ".so".length());
427 }
428 else if (name.endsWith(".dylib")) {
429 objectFileName = name.substring(0, name.length() - ".dylib".length());
430 }
431 else if (name.endsWith(".dll")) {
432 objectFileName = name.substring(0, name.length() - ".dll".length());
433 }
434
435 switch (osName) {
436 case "Linux":
437 // libraryFileName = options.outputName + ".so";
438 objectFileName = objectFileName + ".o";
439 ldCmd = "ld -shared -z noexecstack -o " + libraryFileName + " " + objectFileName;
440 break;
441 case "SunOS":
442 // libraryFileName = options.outputName + ".so";
443 objectFileName = objectFileName + ".o";
444 ldCmd = "ld -shared -o " + libraryFileName + " " + objectFileName;
445 break;
446 case "Mac OS X":
447 // libraryFileName = options.outputName + ".dylib";
448 objectFileName = objectFileName + ".o";
449 ldCmd = "ld -dylib -o " + libraryFileName + " " + objectFileName;
450 break;
451 default:
452 if (osName.startsWith("Windows")) {
453 // libraryFileName = options.outputName + ".dll";
454 objectFileName = objectFileName + ".obj";
455 String linkpath = getWindowsLinkPath();
456 if (linkpath == null) {
457 throw new InternalError("Can't locate Microsoft Visual Studio amd64 link.exe");
458 }
459 ldCmd = linkpath + " /DLL /OPT:NOREF /NOLOGO /NOENTRY" + " /OUT:" + libraryFileName + " " + objectFileName;
460 break;
461 }
462 else
463 throw new InternalError("Unsupported platform: " + osName);
464 }
465
466 try (Timer t = new Timer(this, "Creating binary: " + objectFileName)) {
467 binaryContainer.createBinary(objectFileName, JVM_VERSION);
468 }
469
470 // Free memory!
471 try (Timer t = options.verbose ? new Timer(this, "Freeing memory") : null) {
472 printMemoryUsage();
473 binaryContainer = null;
474 System.gc();
475 }
476
477 try (Timer t = new Timer(this, "Creating shared library: " + libraryFileName)) {
478 Process p = Runtime.getRuntime().exec(ldCmd);
479 final int exitCode = p.waitFor();
480 if (exitCode != 0) {
481 InputStream stderr = p.getErrorStream();
482 BufferedReader br = new BufferedReader(new InputStreamReader(stderr));
483 Stream<String> lines = br.lines();
484 StringBuilder sb = new StringBuilder();
485 lines.iterator().forEachRemaining(e -> sb.append(e));
486 throw new InternalError(sb.toString());
487 }
488 File objFile = new File(objectFileName);
489 if (objFile.exists()) {
490 if (!objFile.delete()) {
491 throw new InternalError("Failed to delete " + objectFileName + " file");
492 }
493 }
494 // Make non-executable for all.
495 File libFile = new File(libraryFileName);
496 if (libFile.exists() && !osName.startsWith("Windows")) {
497 if (!libFile.setExecutable(false, false)) {
498 throw new InternalError("Failed to change attribute for " + libraryFileName + " file");
499 }
500 }
501 }
502
503 printVerbose("Final memory ");
504 printMemoryUsage();
505 printlnVerbose("");
506
507 } finally {
508 closeLog();
509 }
510 }
511
512 private void addMethods(AOTCompiledClass aotClass, ResolvedJavaMethod[] methods, CompilationSpec compilationRestrictions, GraalFilters filters) {
513 for (ResolvedJavaMethod m : methods) {
514 addMethod(aotClass, m, compilationRestrictions, filters);
515 }
516 }
|