/* * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package sun.hotspot.tools.ctw; import com.sun.management.HotSpotDiagnosticMXBean; import sun.management.ManagementFactoryHelper; import java.io.File; import java.util.regex.Pattern; /** * Auxiliary methods. * * @author igor.ignatyev@oracle.com */ public class Utils { /** * Value of {@code -XX:CompileThreshold} */ public static final boolean TIERED_COMPILATION = Boolean.parseBoolean(getVMOption("TieredCompilation", "false")); /** * Value of {@code -XX:BackgroundCompilation} */ public static final boolean BACKGROUND_COMPILATION = Boolean.parseBoolean(getVMOption("BackgroundCompilation", "false")); /** * Value of {@code -XX:TieredStopAtLevel} */ public static final int TIERED_STOP_AT_LEVEL; /** * Value of {@code -XX:CICompilerCount} */ public static final Integer CI_COMPILER_COUNT = Integer.valueOf(getVMOption("CICompilerCount", "1")); /** * Initial compilation level. */ public static final int INITIAL_COMP_LEVEL; /** * Compiled path-separator regexp. */ public static final Pattern PATH_SEPARATOR = Pattern.compile( File.pathSeparator, Pattern.LITERAL); /** * Value of {@code -DDeoptimizeAllClassesRate}. Frequency of * {@code WB.deoptimizeAll()} invocation If it less that {@code 0}, * {@code WB.deoptimizeAll()} will not be invoked. */ public static final int DEOPTIMIZE_ALL_CLASSES_RATE = Integer.getInteger("DeoptimizeAllClassesRate", -1); /** * Value of {@code -DCompileTheWorldStopAt}. Last class to consider. */ public static final long COMPILE_THE_WORLD_STOP_AT = Long.getLong("CompileTheWorldStopAt", Long.MAX_VALUE); /** * Value of {@code -DCompileTheWorldStartAt}. First class to consider. */ public static final long COMPILE_THE_WORLD_START_AT = Long.getLong("CompileTheWorldStartAt", 1); /** * Value of {@code -DCompileTheWorldPreloadClasses}. Preload all classes * used by a class before start loading. */ public static final boolean COMPILE_THE_WORLD_PRELOAD_CLASSES; /** * Value of {@code -Dsun.hotspot.tools.ctw.verbose}. Verbose output, * adds additional information about compilation. */ public static final boolean IS_VERBOSE = Boolean.getBoolean("sun.hotspot.tools.ctw.verbose"); /** * Value of {@code -Dsun.hotspot.tools.ctw.logfile}.Path to logfile, if * it's null, cout will be used. */ public static final String LOG_FILE = System.getProperty("sun.hotspot.tools.ctw.logfile"); static { if (Utils.TIERED_COMPILATION) { INITIAL_COMP_LEVEL = 1; } else { String vmName = System.getProperty("java.vm.name"); if (Utils.endsWithIgnoreCase(vmName, " Server VM")) { INITIAL_COMP_LEVEL = 4; } else if (Utils.endsWithIgnoreCase(vmName, " Client VM")) { INITIAL_COMP_LEVEL = 1; } else { throw new RuntimeException("Unknown VM: " + vmName); } } TIERED_STOP_AT_LEVEL = Integer.parseInt(getVMOption("TieredStopAtLevel", String.valueOf(INITIAL_COMP_LEVEL))); } static { String tmp = System.getProperty("CompileTheWorldPreloadClasses"); if (tmp == null) { COMPILE_THE_WORLD_PRELOAD_CLASSES = true; } else { COMPILE_THE_WORLD_PRELOAD_CLASSES = Boolean.parseBoolean(tmp); } } public static final String CLASSFILE_EXT = ".class"; private Utils() { } /** * Tests if the string ends with the suffix, ignoring case * considerations * * @param string the tested string * @param suffix the suffix * @return {@code true} if {@code string} ends with the {@code suffix} * @see String#endsWith(String) */ public static boolean endsWithIgnoreCase(String string, String suffix) { if (string == null || suffix == null) { return false; } int length = suffix.length(); int toffset = string.length() - length; if (toffset < 0) { return false; } return string.regionMatches(true, toffset, suffix, 0, length); } /** * Returns value of VM option. * * @param name option's name * @return value of option or {@code null}, if option doesn't exist * @throws NullPointerException if name is null */ public static String getVMOption(String name) { String result; HotSpotDiagnosticMXBean diagnostic = ManagementFactoryHelper.getDiagnosticMXBean(); result = diagnostic.getVMOption(name).getValue(); return result; } /** * Returns value of VM option or default value. * * @param name option's name * @param defaultValue default value * @return value of option or {@code defaultValue}, if option doesn't exist * @throws NullPointerException if name is null * @see #getVMOption(String) */ public static String getVMOption(String name, String defaultValue) { String result = getVMOption(name); return result == null ? defaultValue : result; } /** * Tests if the filename is valid filename for class file. * * @param filename tested filename */ public static boolean isClassFile(String filename) { // If the filename has a period after removing '.class', it's not valid class file return endsWithIgnoreCase(filename, CLASSFILE_EXT) && (filename.indexOf('.') == (filename.length() - CLASSFILE_EXT.length())); } /** * Converts the filename to classname. * * @param filename filename to convert * @return corresponding classname. * @throws AssertionError if filename isn't valid filename for class file - * {@link #isClassFile(String)} */ public static String fileNameToClassName(String filename) { assert isClassFile(filename); return filename.substring(0, filename.length() - CLASSFILE_EXT.length()) .replace(File.separatorChar, '.'); } }