src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Main.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc

src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Main.java

Print this page




  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));


src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Main.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File