1/* 2 * Copyright (c) 2013, 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 */ 23 24package sun.hotspot.tools.ctw; 25 26import com.sun.management.HotSpotDiagnosticMXBean; 27import java.lang.management.ManagementFactory; 28 29import java.io.File; 30import java.util.regex.Pattern; 31 32/** 33 * Auxiliary methods. 34 */ 35public class Utils { 36 /** 37 * Value of {@code -XX:CompileThreshold} 38 */ 39 public static final boolean TIERED_COMPILATION 40 = Boolean.parseBoolean(getVMOption("TieredCompilation", "false")); 41 /** 42 * Value of {@code -XX:BackgroundCompilation} 43 */ 44 public static final boolean BACKGROUND_COMPILATION 45 = Boolean.parseBoolean(getVMOption("BackgroundCompilation", 46 "false")); 47 /** 48 * Value of {@code -XX:TieredStopAtLevel} 49 */ 50 public static final int TIERED_STOP_AT_LEVEL; 51 /** 52 * Value of {@code -XX:CICompilerCount} 53 */ 54 public static final Integer CI_COMPILER_COUNT 55 = Integer.valueOf(getVMOption("CICompilerCount", "1")); 56 /** 57 * Initial compilation level. 58 */ 59 public static final int INITIAL_COMP_LEVEL; 60 /** 61 * Compiled path-separator regexp. 62 */ 63 public static final Pattern PATH_SEPARATOR = Pattern.compile( 64 File.pathSeparator, Pattern.LITERAL); 65 /** 66 * Value of {@code -DDeoptimizeAllClassesRate}. Frequency of 67 * {@code WB.deoptimizeAll()} invocation If it less that {@code 0}, 68 * {@code WB.deoptimizeAll()} will not be invoked. 69 */ 70 public static final int DEOPTIMIZE_ALL_CLASSES_RATE 71 = Integer.getInteger("DeoptimizeAllClassesRate", -1); 72 /** 73 * Value of {@code -DCompileTheWorldStopAt}. Last class to consider. 74 */ 75 public static final long COMPILE_THE_WORLD_STOP_AT 76 = Long.getLong("CompileTheWorldStopAt", Long.MAX_VALUE); 77 /** 78 * Value of {@code -DCompileTheWorldStartAt}. First class to consider. 79 */ 80 public static final long COMPILE_THE_WORLD_START_AT 81 = Long.getLong("CompileTheWorldStartAt", 1); 82 /** 83 * Value of {@code -DCompileTheWorldPreloadClasses}. Preload all classes 84 * used by a class before start loading. 85 */ 86 public static final boolean COMPILE_THE_WORLD_PRELOAD_CLASSES; 87 /** 88 * Value of {@code -Dsun.hotspot.tools.ctw.verbose}. Verbose output, 89 * adds additional information about compilation. 90 */ 91 public static final boolean IS_VERBOSE 92 = Boolean.getBoolean("sun.hotspot.tools.ctw.verbose"); 93 /** 94 * Value of {@code -Dsun.hotspot.tools.ctw.logfile}.Path to logfile, if 95 * it's null, cout will be used. 96 */ 97 public static final String LOG_FILE 98 = System.getProperty("sun.hotspot.tools.ctw.logfile"); 99 static { 100 if (Utils.TIERED_COMPILATION) { 101 INITIAL_COMP_LEVEL = 1; 102 } else { 103 String vmName = System.getProperty("java.vm.name"); 104 String vmInfo = System.getProperty("java.vm.info"); 105 boolean isEmulatedClient = (vmInfo != null) && vmInfo.contains("emulated-client"); 106 if (Utils.endsWithIgnoreCase(vmName, " Server VM") && !isEmulatedClient) { 107 INITIAL_COMP_LEVEL = 4; 108 } else if (Utils.endsWithIgnoreCase(vmName, " Client VM") 109 || Utils.endsWithIgnoreCase(vmName, " Minimal VM") || isEmulatedClient) { 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 = ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class); 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 final char nameSeparator = '/'; 213 return filename.substring(0, filename.length() - CLASSFILE_EXT.length()) 214 .replace(nameSeparator, '.'); 215 } 216 217 public static String classNameToFileName(String classname) { 218 return classname.replace('.', '/') 219 .concat(CLASSFILE_EXT); 220 } 221} 222