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 package org.graalvm.compiler.hotspot; 24 25 import static org.graalvm.compiler.core.common.util.Util.Java8OrEarlier; 26 import static org.graalvm.compiler.options.OptionValue.PROFILE_OPTIONVALUE_PROPERTY_NAME; 27 import static jdk.vm.ci.common.InitTimer.timer; 28 29 import java.io.File; 30 import java.io.FileReader; 31 import java.io.IOException; 32 import java.io.PrintStream; 33 import java.lang.reflect.Field; 34 import java.util.HashMap; 35 import java.util.Map; 36 import java.util.Properties; 37 import java.util.ServiceLoader; 38 39 import org.graalvm.compiler.debug.GraalError; 40 import org.graalvm.compiler.debug.MethodFilter; 41 import org.graalvm.compiler.options.Option; 42 import org.graalvm.compiler.options.OptionDescriptors; 43 import org.graalvm.compiler.options.OptionType; 44 import org.graalvm.compiler.options.OptionValue; 45 import org.graalvm.compiler.options.OptionsParser; 46 import org.graalvm.compiler.phases.tiers.CompilerConfiguration; 47 48 import jdk.vm.ci.common.InitTimer; 49 import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; 50 import jdk.vm.ci.hotspot.HotSpotSignature; 51 import jdk.vm.ci.hotspot.HotSpotJVMCICompilerFactory; 52 import jdk.vm.ci.runtime.JVMCIRuntime; 53 54 public final class HotSpotGraalCompilerFactory extends HotSpotJVMCICompilerFactory { 55 56 /** 57 * The name of the system property specifying a file containing extra Graal option settings. 58 */ 59 private static final String GRAAL_OPTIONS_FILE_PROPERTY_NAME = "graal.options.file"; 60 61 /** 62 * The name of the system property specifying the Graal version. 63 */ 64 private static final String GRAAL_VERSION_PROPERTY_NAME = "graal.version"; 65 66 /** 67 * The prefix for system properties that correspond to {@link Option} annotated fields. A field 68 * named {@code MyOption} will have its value set from a system property with the name 69 * {@code GRAAL_OPTION_PROPERTY_PREFIX + "MyOption"}. 70 */ 71 public static final String GRAAL_OPTION_PROPERTY_PREFIX = "graal."; 72 118 119 } 120 121 private static Map<String, String> allOptionsSettings; 122 123 /** 124 * Initializes options if they haven't already been initialized. 125 * 126 * Initialization means first parsing the options in the file denoted by the 127 * {@code VM.getSavedProperty(String) saved} system property named 128 * {@value HotSpotGraalCompilerFactory#GRAAL_OPTIONS_FILE_PROPERTY_NAME} if the file exists 129 * followed by parsing the options encoded in saved system properties whose names start with 130 * {@value #GRAAL_OPTION_PROPERTY_PREFIX}. Key/value pairs are parsed from the aforementioned 131 * file with {@link Properties#load(java.io.Reader)}. 132 */ 133 @SuppressWarnings("try") 134 private static synchronized void initializeOptions() { 135 if (allOptionsSettings == null) { 136 try (InitTimer t = timer("InitializeOptions")) { 137 ServiceLoader<OptionDescriptors> loader = ServiceLoader.load(OptionDescriptors.class, OptionDescriptors.class.getClassLoader()); 138 Properties savedProps = getSavedProperties(Java8OrEarlier); 139 String optionsFile = savedProps.getProperty(GRAAL_OPTIONS_FILE_PROPERTY_NAME); 140 141 if (optionsFile != null) { 142 File graalOptions = new File(optionsFile); 143 if (graalOptions.exists()) { 144 try (FileReader fr = new FileReader(graalOptions)) { 145 Properties props = new Properties(); 146 props.load(fr); 147 Map<String, String> optionSettings = new HashMap<>(); 148 for (Map.Entry<Object, Object> e : props.entrySet()) { 149 optionSettings.put((String) e.getKey(), (String) e.getValue()); 150 } 151 try { 152 OptionsParser.parseOptions(optionSettings, null, loader); 153 if (allOptionsSettings == null) { 154 allOptionsSettings = new HashMap<>(optionSettings); 155 } else { 156 allOptionsSettings.putAll(optionSettings); 157 } 158 } catch (Throwable e) { 159 throw new InternalError("Error parsing an option from " + graalOptions, e); 160 } 161 } catch (IOException e) { 162 throw new InternalError("Error reading " + graalOptions, e); 163 } 164 } 165 } 166 167 Map<String, String> optionSettings = new HashMap<>(); 168 for (Map.Entry<Object, Object> e : savedProps.entrySet()) { 169 String name = (String) e.getKey(); 170 if (name.startsWith(GRAAL_OPTION_PROPERTY_PREFIX)) { 171 if (name.equals("graal.PrintFlags") || name.equals("graal.ShowFlags")) { 172 System.err.println("The " + name + " option has been removed and will be ignored. Use -XX:+JVMCIPrintProperties instead."); 173 } else if (name.equals(GRAAL_OPTIONS_FILE_PROPERTY_NAME) || name.equals(GRAAL_VERSION_PROPERTY_NAME) || name.equals(PROFILE_OPTIONVALUE_PROPERTY_NAME)) { 174 // Ignore well known properties that do not denote an option 175 } else { 176 String value = (String) e.getValue(); 177 optionSettings.put(name.substring(GRAAL_OPTION_PROPERTY_PREFIX.length()), value); 178 } 179 } 180 } 181 182 OptionsParser.parseOptions(optionSettings, null, loader); 183 184 if (allOptionsSettings == null) { 185 allOptionsSettings = optionSettings; 186 } else { 187 allOptionsSettings.putAll(optionSettings); 188 } 189 190 if (Options.GraalCompileOnly.getValue() != null) { 191 graalCompileOnlyFilter = MethodFilter.parse(Options.GraalCompileOnly.getValue()); 192 if (graalCompileOnlyFilter.length == 0) { 193 graalCompileOnlyFilter = null; 194 } 195 } 196 if (graalCompileOnlyFilter != null || !Options.UseTrivialPrefixes.getValue()) { 197 /* 198 * Exercise this code path early to encourage loading now. This doesn't solve 199 * problem of deadlock during class loading but seems to eliminate it in 200 * practice. 201 */ 202 adjustCompilationLevelInternal(Object.class, "hashCode", "()I", CompilationLevel.FullOptimization); 203 adjustCompilationLevelInternal(Object.class, "hashCode", "()I", CompilationLevel.Simple); 204 } 205 } 206 } 207 } 208 209 private static Properties getSavedProperties(boolean jdk8OrEarlier) { 210 try { 211 String vmClassName = jdk8OrEarlier ? "sun.misc.VM" : "jdk.internal.misc.VM"; 212 Class<?> vmClass = Class.forName(vmClassName); 213 Field savedPropsField = vmClass.getDeclaredField("savedProps"); 214 savedPropsField.setAccessible(true); 215 return (Properties) savedPropsField.get(null); 216 } catch (Exception e) { 217 throw new GraalError(e); 218 } 219 } 220 221 @Override 222 public HotSpotGraalCompiler createCompiler(JVMCIRuntime runtime) { 223 HotSpotGraalCompiler compiler = createCompiler(runtime, CompilerConfigurationFactory.selectFactory(null)); 224 // Only the HotSpotGraalRuntime associated with the compiler created via 225 // jdk.vm.ci.runtime.JVMCIRuntime.getCompiler() is registered for receiving 226 // VM events. 227 locator.onCompilerCreation(compiler); 228 return compiler; 229 } 230 231 /** 232 * Creates a new {@link HotSpotGraalRuntime} object and a new {@link HotSpotGraalCompiler} and 233 * returns the latter. 234 * 235 * @param runtime the JVMCI runtime on which the {@link HotSpotGraalRuntime} is built 236 * @param compilerConfigurationFactory factory for the {@link CompilerConfiguration} 237 */ 238 @SuppressWarnings("try") 239 public static HotSpotGraalCompiler createCompiler(JVMCIRuntime runtime, CompilerConfigurationFactory compilerConfigurationFactory) { 240 HotSpotJVMCIRuntime jvmciRuntime = (HotSpotJVMCIRuntime) runtime; | 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 package org.graalvm.compiler.hotspot; 24 25 import static org.graalvm.compiler.core.common.util.Util.Java8OrEarlier; 26 import static org.graalvm.compiler.options.OptionValue.PROFILE_OPTIONVALUE_PROPERTY_NAME; 27 import static jdk.vm.ci.common.InitTimer.timer; 28 29 import java.io.File; 30 import java.io.FileReader; 31 import java.io.IOException; 32 import java.io.PrintStream; 33 import java.lang.reflect.Field; 34 import java.util.HashMap; 35 import java.util.Map; 36 import java.util.Map.Entry; 37 import java.util.Properties; 38 import java.util.ServiceLoader; 39 40 import org.graalvm.compiler.debug.GraalError; 41 import org.graalvm.compiler.debug.MethodFilter; 42 import org.graalvm.compiler.options.Option; 43 import org.graalvm.compiler.options.OptionDescriptors; 44 import org.graalvm.compiler.options.OptionType; 45 import org.graalvm.compiler.options.OptionValue; 46 import org.graalvm.compiler.options.OptionsParser; 47 import org.graalvm.compiler.phases.tiers.CompilerConfiguration; 48 49 import jdk.vm.ci.common.InitTimer; 50 import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; 51 import jdk.vm.ci.hotspot.HotSpotSignature; 52 import jdk.vm.ci.hotspot.HotSpotJVMCICompilerFactory; 53 import jdk.vm.ci.runtime.JVMCIRuntime; 54 import jdk.vm.ci.services.Services; 55 56 public final class HotSpotGraalCompilerFactory extends HotSpotJVMCICompilerFactory { 57 58 /** 59 * The name of the system property specifying a file containing extra Graal option settings. 60 */ 61 private static final String GRAAL_OPTIONS_FILE_PROPERTY_NAME = "graal.options.file"; 62 63 /** 64 * The name of the system property specifying the Graal version. 65 */ 66 private static final String GRAAL_VERSION_PROPERTY_NAME = "graal.version"; 67 68 /** 69 * The prefix for system properties that correspond to {@link Option} annotated fields. A field 70 * named {@code MyOption} will have its value set from a system property with the name 71 * {@code GRAAL_OPTION_PROPERTY_PREFIX + "MyOption"}. 72 */ 73 public static final String GRAAL_OPTION_PROPERTY_PREFIX = "graal."; 74 120 121 } 122 123 private static Map<String, String> allOptionsSettings; 124 125 /** 126 * Initializes options if they haven't already been initialized. 127 * 128 * Initialization means first parsing the options in the file denoted by the 129 * {@code VM.getSavedProperty(String) saved} system property named 130 * {@value HotSpotGraalCompilerFactory#GRAAL_OPTIONS_FILE_PROPERTY_NAME} if the file exists 131 * followed by parsing the options encoded in saved system properties whose names start with 132 * {@value #GRAAL_OPTION_PROPERTY_PREFIX}. Key/value pairs are parsed from the aforementioned 133 * file with {@link Properties#load(java.io.Reader)}. 134 */ 135 @SuppressWarnings("try") 136 private static synchronized void initializeOptions() { 137 if (allOptionsSettings == null) { 138 try (InitTimer t = timer("InitializeOptions")) { 139 ServiceLoader<OptionDescriptors> loader = ServiceLoader.load(OptionDescriptors.class, OptionDescriptors.class.getClassLoader()); 140 Map<String, String> savedProps = Services.getSavedProperties(); 141 String optionsFile = savedProps.get(GRAAL_OPTIONS_FILE_PROPERTY_NAME); 142 143 if (optionsFile != null) { 144 File graalOptions = new File(optionsFile); 145 if (graalOptions.exists()) { 146 try (FileReader fr = new FileReader(graalOptions)) { 147 Properties props = new Properties(); 148 props.load(fr); 149 Map<String, String> optionSettings = new HashMap<>(); 150 for (Map.Entry<Object, Object> e : props.entrySet()) { 151 optionSettings.put((String) e.getKey(), (String) e.getValue()); 152 } 153 try { 154 OptionsParser.parseOptions(optionSettings, null, loader); 155 if (allOptionsSettings == null) { 156 allOptionsSettings = new HashMap<>(optionSettings); 157 } else { 158 allOptionsSettings.putAll(optionSettings); 159 } 160 } catch (Throwable e) { 161 throw new InternalError("Error parsing an option from " + graalOptions, e); 162 } 163 } catch (IOException e) { 164 throw new InternalError("Error reading " + graalOptions, e); 165 } 166 } 167 } 168 169 Map<String, String> optionSettings = new HashMap<>(); 170 for (Entry<String, String> e : savedProps.entrySet()) { 171 String name = e.getKey(); 172 if (name.startsWith(GRAAL_OPTION_PROPERTY_PREFIX)) { 173 if (name.equals("graal.PrintFlags") || name.equals("graal.ShowFlags")) { 174 System.err.println("The " + name + " option has been removed and will be ignored. Use -XX:+JVMCIPrintProperties instead."); 175 } else if (name.equals(GRAAL_OPTIONS_FILE_PROPERTY_NAME) || name.equals(GRAAL_VERSION_PROPERTY_NAME) || name.equals(PROFILE_OPTIONVALUE_PROPERTY_NAME)) { 176 // Ignore well known properties that do not denote an option 177 } else { 178 String value = e.getValue(); 179 optionSettings.put(name.substring(GRAAL_OPTION_PROPERTY_PREFIX.length()), value); 180 } 181 } 182 } 183 184 OptionsParser.parseOptions(optionSettings, null, loader); 185 186 if (allOptionsSettings == null) { 187 allOptionsSettings = optionSettings; 188 } else { 189 allOptionsSettings.putAll(optionSettings); 190 } 191 192 if (Options.GraalCompileOnly.getValue() != null) { 193 graalCompileOnlyFilter = MethodFilter.parse(Options.GraalCompileOnly.getValue()); 194 if (graalCompileOnlyFilter.length == 0) { 195 graalCompileOnlyFilter = null; 196 } 197 } 198 if (graalCompileOnlyFilter != null || !Options.UseTrivialPrefixes.getValue()) { 199 /* 200 * Exercise this code path early to encourage loading now. This doesn't solve 201 * problem of deadlock during class loading but seems to eliminate it in 202 * practice. 203 */ 204 adjustCompilationLevelInternal(Object.class, "hashCode", "()I", CompilationLevel.FullOptimization); 205 adjustCompilationLevelInternal(Object.class, "hashCode", "()I", CompilationLevel.Simple); 206 } 207 } 208 } 209 } 210 211 @Override 212 public HotSpotGraalCompiler createCompiler(JVMCIRuntime runtime) { 213 HotSpotGraalCompiler compiler = createCompiler(runtime, CompilerConfigurationFactory.selectFactory(null)); 214 // Only the HotSpotGraalRuntime associated with the compiler created via 215 // jdk.vm.ci.runtime.JVMCIRuntime.getCompiler() is registered for receiving 216 // VM events. 217 locator.onCompilerCreation(compiler); 218 return compiler; 219 } 220 221 /** 222 * Creates a new {@link HotSpotGraalRuntime} object and a new {@link HotSpotGraalCompiler} and 223 * returns the latter. 224 * 225 * @param runtime the JVMCI runtime on which the {@link HotSpotGraalRuntime} is built 226 * @param compilerConfigurationFactory factory for the {@link CompilerConfiguration} 227 */ 228 @SuppressWarnings("try") 229 public static HotSpotGraalCompiler createCompiler(JVMCIRuntime runtime, CompilerConfigurationFactory compilerConfigurationFactory) { 230 HotSpotJVMCIRuntime jvmciRuntime = (HotSpotJVMCIRuntime) runtime; |