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 INITIAL_COMP_LEVEL = 1; 110 } else { 111 throw new RuntimeException("Unknown VM: " + vmName); 112 } 113 } 114 115 TIERED_STOP_AT_LEVEL = Integer.parseInt(getVMOption("TieredStopAtLevel", 116 String.valueOf(INITIAL_COMP_LEVEL))); 117 } 118 119 static { 120 String tmp = System.getProperty("CompileTheWorldPreloadClasses"); 121 if (tmp == null) { 122 COMPILE_THE_WORLD_PRELOAD_CLASSES = true; 123 } else { 124 COMPILE_THE_WORLD_PRELOAD_CLASSES = Boolean.parseBoolean(tmp); 125 } 126 } 127 128 public static final String CLASSFILE_EXT = ".class"; 129 130 private Utils() { 131 } 132 133 /** 134 * Tests if the string ends with the suffix, ignoring case 135 * considerations 136 * 137 * @param string the tested string 138 * @param suffix the suffix 139 * @return {@code true} if {@code string} ends with the {@code suffix} 140 * @see String#endsWith(String) 141 */ 142 public static boolean endsWithIgnoreCase(String string, String suffix) { 143 if (string == null || suffix == null) { 144 return false; 145 } 146 int length = suffix.length(); 147 int toffset = string.length() - length; 148 if (toffset < 0) { 149 return false; 150 } 151 return string.regionMatches(true, toffset, suffix, 0, length); 152 } 153 154 /** 155 * Returns value of VM option. 156 * 157 * @param name option's name 158 * @return value of option or {@code null}, if option doesn't exist 159 * @throws NullPointerException if name is null 160 */ 161 public static String getVMOption(String name) { 162 String result; 163 HotSpotDiagnosticMXBean diagnostic 164 = ManagementFactoryHelper.getDiagnosticMXBean(); 165 result = diagnostic.getVMOption(name).getValue(); 166 return result; 167 } 168 169 /** 170 * Returns value of VM option or default value. 171 * 172 * @param name option's name 173 * @param defaultValue default value 174 * @return value of option or {@code defaultValue}, if option doesn't exist 175 * @throws NullPointerException if name is null 176 * @see #getVMOption(String) 177 */ 178 public static String getVMOption(String name, String defaultValue) { 179 String result = getVMOption(name); 180 return result == null ? defaultValue : result; 181 } 182 183 /** 184 * Tests if the filename is valid filename for class file. 185 * 186 * @param filename tested filename 187 */ 188 public static boolean isClassFile(String filename) { 189 // If the filename has a period after removing '.class', it's not valid class file 190 return endsWithIgnoreCase(filename, CLASSFILE_EXT) 191 && (filename.indexOf('.') 192 == (filename.length() - CLASSFILE_EXT.length())); 193 } 194 195 /** 196 * Converts the filename to classname. 197 * 198 * @param filename filename to convert 199 * @return corresponding classname. 200 * @throws AssertionError if filename isn't valid filename for class file - 201 * {@link #isClassFile(String)} 202 */ 203 public static String fileNameToClassName(String filename) { 204 assert isClassFile(filename); 205 return filename.substring(0, filename.length() - CLASSFILE_EXT.length()) 206 .replace(File.separatorChar, '.'); 207 } 208 }