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 com.sun.management.HotSpotDiagnosticMXBean; 27 import sun.management.ManagementFactoryHelper; 28 29 import java.io.File; 30 import java.util.regex.Pattern; 31 32 /** 33 * Auxiliary methods. 34 * 35 * @author igor.ignatyev@oracle.com 36 */ 37 public class Utils { 38 /** 39 * Value of {@code -XX:CompileThreshold} 40 */ 41 public static final boolean TIERED_COMPILATION 42 = Boolean.parseBoolean(getVMOption("TieredCompilation", "false")); 43 /** 44 * Value of {@code -XX:BackgroundCompilation} 45 */ 46 public static final boolean BACKGROUND_COMPILATION 47 = Boolean.parseBoolean(getVMOption("BackgroundCompilation", 48 "false")); 49 /** 50 * Value of {@code -XX:TieredStopAtLevel} 51 */ 52 public static final int TIERED_STOP_AT_LEVEL; 53 /** 54 * Value of {@code -XX:CICompilerCount} 55 */ 56 public static final Integer CI_COMPILER_COUNT 57 = Integer.valueOf(getVMOption("CICompilerCount", "1")); 58 /** 59 * Initial compilation level. 60 */ 61 public static final int INITIAL_COMP_LEVEL; 62 /** 63 * Compiled path-separator regexp. 64 */ 65 public static final Pattern PATH_SEPARATOR = Pattern.compile( 66 File.pathSeparator, Pattern.LITERAL); 67 /** 68 * Value of {@code -DDeoptimizeAllClassesRate}. Frequency of 69 * {@code WB.deoptimizeAll()} invocation If it less that {@code 0}, 70 * {@code WB.deoptimizeAll()} will not be invoked. 71 */ 72 public static final int DEOPTIMIZE_ALL_CLASSES_RATE 73 = Integer.getInteger("DeoptimizeAllClassesRate", -1); 74 /** 75 * Value of {@code -DCompileTheWorldStopAt}. Last class to consider. 76 */ 77 public static final long COMPILE_THE_WORLD_STOP_AT 78 = Long.getLong("CompileTheWorldStopAt", Long.MAX_VALUE); 79 /** 80 * Value of {@code -DCompileTheWorldStartAt}. First class to consider. 81 */ 82 public static final long COMPILE_THE_WORLD_START_AT 83 = Long.getLong("CompileTheWorldStartAt", 1); 84 /** 85 * Value of {@code -DCompileTheWorldPreloadClasses}. Preload all classes 86 * used by a class before start loading. 87 */ 88 public static final boolean COMPILE_THE_WORLD_PRELOAD_CLASSES; 89 /** 90 * Value of {@code -Dsun.hotspot.tools.ctw.verbose}. Verbose output, 91 * adds additional information about compilation. 92 */ 93 public static final boolean IS_VERBOSE 94 = Boolean.getBoolean("sun.hotspot.tools.ctw.verbose"); 95 /** 96 * Value of {@code -Dsun.hotspot.tools.ctw.logfile}.Path to logfile, if 97 * it's null, cout will be used. 98 */ 99 public static final String LOG_FILE 100 = System.getProperty("sun.hotspot.tools.ctw.logfile"); 101 static { 102 if (Utils.TIERED_COMPILATION) { 103 INITIAL_COMP_LEVEL = 1; 104 } else { 105 String vmName = System.getProperty("java.vm.name"); 106 if (Utils.endsWithIgnoreCase(vmName, " Server VM")) { 107 INITIAL_COMP_LEVEL = 4; 108 } else if (Utils.endsWithIgnoreCase(vmName, " Client VM") 109 || Utils.endsWithIgnoreCase(vmName, " Minimal VM")) { 110 INITIAL_COMP_LEVEL = 1; 111 } else { 112 throw new RuntimeException("Unknown VM: " + vmName); 113 } 114 } 115 116 TIERED_STOP_AT_LEVEL = Integer.parseInt(getVMOption("TieredStopAtLevel", 117 String.valueOf(INITIAL_COMP_LEVEL))); 118 } 119 120 static { 121 String tmp = System.getProperty("CompileTheWorldPreloadClasses"); 122 if (tmp == null) { 123 COMPILE_THE_WORLD_PRELOAD_CLASSES = true; 124 } else { 125 COMPILE_THE_WORLD_PRELOAD_CLASSES = Boolean.parseBoolean(tmp); 126 } 127 } 128 129 public static final String CLASSFILE_EXT = ".class"; 130 131 private Utils() { 132 } 133 134 /** 135 * Tests if the string ends with the suffix, ignoring case 136 * considerations 137 * 138 * @param string the tested string 139 * @param suffix the suffix 140 * @return {@code true} if {@code string} ends with the {@code suffix} 141 * @see String#endsWith(String) 142 */ 143 public static boolean endsWithIgnoreCase(String string, String suffix) { 144 if (string == null || suffix == null) { 145 return false; 146 } 147 int length = suffix.length(); 148 int toffset = string.length() - length; 149 if (toffset < 0) { 150 return false; 151 } 152 return string.regionMatches(true, toffset, suffix, 0, length); 153 } 154 155 /** 156 * Returns value of VM option. 157 * 158 * @param name option's name 159 * @return value of option or {@code null}, if option doesn't exist 160 * @throws NullPointerException if name is null 161 */ 162 public static String getVMOption(String name) { 163 String result; 164 HotSpotDiagnosticMXBean diagnostic 165 = ManagementFactoryHelper.getDiagnosticMXBean(); 166 result = diagnostic.getVMOption(name).getValue(); 167 return result; 168 } 169 170 /** 171 * Returns value of VM option or default value. 172 * 173 * @param name option's name 174 * @param defaultValue default value 175 * @return value of option or {@code defaultValue}, if option doesn't exist 176 * @throws NullPointerException if name is null 177 * @see #getVMOption(String) 178 */ 179 public static String getVMOption(String name, String defaultValue) { 180 String result; 181 try { 182 result = getVMOption(name); 183 } catch (NoClassDefFoundError e) { 184 // compact1, compact2 support 185 result = defaultValue; 186 } 187 return result == null ? defaultValue : result; 188 } 189 190 /** 191 * Tests if the filename is valid filename for class file. 192 * 193 * @param filename tested filename 194 */ 195 public static boolean isClassFile(String filename) { 196 // If the filename has a period after removing '.class', it's not valid class file 197 return endsWithIgnoreCase(filename, CLASSFILE_EXT) 198 && (filename.indexOf('.') 199 == (filename.length() - CLASSFILE_EXT.length())); 200 } 201 202 /** 203 * Converts the filename to classname. 204 * 205 * @param filename filename to convert 206 * @return corresponding classname. 207 * @throws AssertionError if filename isn't valid filename for class file - 208 * {@link #isClassFile(String)} 209 */ 210 public static String fileNameToClassName(String filename) { 211 assert isClassFile(filename); 212 return filename.substring(0, filename.length() - CLASSFILE_EXT.length()) 213 .replace(File.separatorChar, '.'); 214 } 215 }