1 /* 2 * Copyright (c) 2013, 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 */ 23 24 package sun.hotspot.tools.ctw; 25 26 import sun.management.ManagementFactoryHelper; 27 28 import java.io.*; 29 import java.nio.file.Files; 30 import java.nio.file.Paths; 31 32 import java.util.List; 33 import java.util.concurrent.*; 34 35 /** 36 * @author igor.ignatyev@oracle.com 37 */ 38 public class CompileTheWorld { 39 /** 40 * Entry point. Compiles classes in {@code args}, or all classes in 41 * boot-classpath if args is empty 42 * 43 * @param args paths to jar/zip, dir contains classes, or to .lst file 44 * contains list of classes to compile 45 */ 46 public static void main(String[] args) { 47 String logfile = Utils.LOG_FILE; 48 PrintStream os = null; 49 if (logfile != null) { 50 try { 51 os = new PrintStream(Files.newOutputStream(Paths.get(logfile))); 52 } catch (IOException io) { 53 } 54 } 55 if (os != null) { 56 System.setOut(os); 57 } 58 59 try { 60 try { 61 if (ManagementFactoryHelper.getCompilationMXBean() == null) { 62 throw new RuntimeException( 63 "CTW can not work in interpreted mode"); 64 } 65 } catch (java.lang.NoClassDefFoundError e) { 66 // compact1, compact2 support 67 } 68 String[] paths = args; 69 boolean skipRtJar = false; 70 if (args.length == 0) { 71 paths = getDefaultPaths(); 72 skipRtJar = true; 73 } 74 ExecutorService executor = createExecutor(); 75 long start = System.currentTimeMillis(); 76 try { 77 String path; 78 for (int i = 0, n = paths.length; i < n 79 && !PathHandler.isFinished(); ++i) { 80 path = paths[i]; 81 if (skipRtJar && i > 0 && isRtJar(path)) { 82 // rt.jar is not first, so skip it 83 continue; 84 } 85 PathHandler.create(path, executor).process(); 86 } 87 } finally { 88 await(executor); 89 } 90 System.out.printf("Done (%d classes, %d methods, %d ms)%n", 91 Compiler.getClassCount(), 92 Compiler.getMethodCount(), 93 System.currentTimeMillis() - start); 94 } finally { 95 if (os != null) { 96 os.close(); 97 } 98 } 99 } 100 101 private static ExecutorService createExecutor() { 102 final int threadsCount = Math.min( 103 Runtime.getRuntime().availableProcessors(), 104 Utils.CI_COMPILER_COUNT); 105 ExecutorService result; 106 if (threadsCount > 1) { 107 result = new ThreadPoolExecutor(threadsCount, threadsCount, 108 /* keepAliveTime */ 0L, TimeUnit.MILLISECONDS, 109 new ArrayBlockingQueue<>(threadsCount), 110 new ThreadPoolExecutor.CallerRunsPolicy()); 111 } else { 112 result = new CurrentThreadExecutor(); 113 } 114 return result; 115 } 116 117 private static String[] getDefaultPaths() { 118 String property = System.getProperty("sun.boot.class.path"); 119 System.out.println( 120 "# use 'sun.boot.class.path' as args: " + property); 121 return Utils.PATH_SEPARATOR.split(property); 122 } 123 124 private static void await(ExecutorService executor) { 125 executor.shutdown(); 126 while (!executor.isTerminated()) { 127 try { 128 executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); 129 } catch (InterruptedException ie) { 130 Thread.currentThread().interrupt(); 131 break; 132 } 133 } 134 } 135 136 private static boolean isRtJar(String path) { 137 return Utils.endsWithIgnoreCase(path, File.separator + "rt.jar"); 138 } 139 140 private static class CurrentThreadExecutor extends AbstractExecutorService { 141 private boolean isShutdown; 142 143 @Override 144 public void shutdown() { 145 this.isShutdown = true; 146 } 147 148 @Override 149 public List<Runnable> shutdownNow() { 150 return null; 151 } 152 153 @Override 154 public boolean isShutdown() { 155 return isShutdown; 156 } 157 158 @Override 159 public boolean isTerminated() { 160 return isShutdown; 161 } 162 163 @Override 164 public boolean awaitTermination(long timeout, TimeUnit unit) 165 throws InterruptedException { 166 return isShutdown; 167 } 168 169 @Override 170 public void execute(Runnable command) { 171 command.run(); 172 } 173 } 174 } 175