# HG changeset patch # User Doug Simon # Date 1400866594 -7200 # Node ID fe608a56e3f7740f662a60048b1551903f3a0960 # Parent 387b15da0f681ebc48bec0f1b5f07c98eb8bce5a made HotSpotOptions processing faster by removing use of service loader in VM startup and only doing work for options specified on the command line diff -r 387b15da0f68 -r fe608a56e3f7 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java Fri May 23 17:47:44 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java Fri May 23 19:36:34 2014 +0200 @@ -20,103 +20,38 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ - package com.oracle.graal.hotspot; import static com.oracle.graal.compiler.GraalDebugConfig.*; +import static com.oracle.graal.hotspot.HotSpotOptionsLoader.*; import static com.oracle.graal.hotspot.bridge.VMToCompilerImpl.*; -import static java.nio.file.Files.*; +import static java.lang.Double.*; -import java.io.*; import java.lang.reflect.*; -import java.nio.charset.*; -import java.nio.file.*; import java.util.*; import com.oracle.graal.api.runtime.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.debug.*; -import com.oracle.graal.hotspot.logging.*; import com.oracle.graal.options.*; import com.oracle.graal.phases.common.inlining.*; /** - * Called from {@code graalCompiler.cpp} to parse any Graal specific options. Such options are - * (currently) distinguished by a {@code "-G:"} prefix. + * Called from {@code graalCompiler.cpp} to set Graal options from the HotSpot command line. Such + * options are (currently) distinguished by a {@code "-G:"} prefix. */ public class HotSpotOptions { - private static final Map options = new HashMap<>(); - /** - * Initializes {@link #options} from {@link Options} services. - */ - private static void initializeOptions() { - ServiceLoader sl = ServiceLoader.loadInstalled(Options.class); - for (Options opts : sl) { - for (OptionDescriptor desc : opts) { - if (isHotSpotOption(desc)) { - String name = desc.getName(); - OptionDescriptor existing = options.put(name, desc); - assert existing == null : "Option named \"" + name + "\" has multiple definitions: " + existing.getLocation() + " and " + desc.getLocation(); - } - } - } - } - - /** - * Determines if a given option is a HotSpot command line option. + * Parses the Graal specific options specified to HotSpot (e.g., on the command line). + * + * @return true if the CITime or CITimeEach HotSpot VM options are set */ - public static boolean isHotSpotOption(OptionDescriptor desc) { - return desc.getClass().getName().startsWith("com.oracle.graal"); - } - - /** - * Loads default option value overrides from a {@code graal.options} file if it exists. Each - * line in this file starts with {@code "#"} and is ignored or must have the format of a Graal - * command line option without the leading {@code "-G:"} prefix. These option value are set - * prior to processing of any Graal options present on the command line. - */ - private static void loadOptionOverrides() throws InternalError { - String javaHome = System.getProperty("java.home"); - Path graalDotOptions = Paths.get(javaHome, "lib", "graal.options"); - if (!exists(graalDotOptions)) { - graalDotOptions = Paths.get(javaHome, "jre", "lib", "graal.options"); - } - if (exists(graalDotOptions)) { - try { - for (String line : Files.readAllLines(graalDotOptions, Charset.defaultCharset())) { - if (!line.startsWith("#")) { - if (!parseOption(line, null)) { - throw new InternalError("Invalid option \"" + line + "\" specified in " + graalDotOptions); - } - } - } - } catch (IOException e) { - throw (InternalError) new InternalError().initCause(e); - } - } - } - - /** - * Gets the Graal specific options specified to HotSpot (e.g., on the command line). - * - * @param timeCompilations (out) true if the CITime or CITimeEach HotSpot VM options are set - */ - private static native String[] getVMOptions(boolean[] timeCompilations); + private static native boolean parseVMOptions(); static { - initializeOptions(); - loadOptionOverrides(); - - boolean[] timeCompilations = {false}; - for (String option : getVMOptions(timeCompilations)) { - if (!parseOption(option, null)) { - throw new InternalError("Invalid Graal option \"-G:" + option + "\""); - } - } - - if (timeCompilations[0] || PrintCompRate.getValue() != 0) { + boolean timeCompilations = parseVMOptions(); + if (timeCompilations || PrintCompRate.getValue() != 0) { unconditionallyEnableTimerOrMetric(InliningUtil.class, "InlinedBytecodes"); unconditionallyEnableTimerOrMetric(CompilationTask.class, "CompilationTime"); } @@ -138,6 +73,42 @@ } /** + * Helper for the VM code called by {@link #parseVMOptions()}. + * + * @param name the name of a parsed option + * @param option the object encapsulating the option + * @param spec specification of boolean option value, type of option value or action to take + */ + static void setOption(String name, OptionValue option, char spec, String stringValue, long primitiveValue) { + switch (spec) { + case '+': + option.setValue(Boolean.TRUE); + break; + case '-': + option.setValue(Boolean.FALSE); + break; + case '?': + printFlags(); + break; + case ' ': + printNoMatchMessage(name); + break; + case 'i': + option.setValue((int) primitiveValue); + break; + case 'f': + option.setValue((float) longBitsToDouble(primitiveValue)); + break; + case 'd': + option.setValue(longBitsToDouble(primitiveValue)); + break; + case 's': + option.setValue(stringValue); + break; + } + } + + /** * Parses a given option value specification. * * @param option the specification of an option and its value @@ -176,15 +147,7 @@ OptionDescriptor desc = options.get(optionName); if (desc == null) { - Logger.info("Could not find option " + optionName + " (use -G:+PrintFlags to see Graal options)"); - List matches = fuzzyMatch(optionName); - if (!matches.isEmpty()) { - Logger.info("Did you mean one of the following?"); - for (OptionDescriptor match : matches) { - boolean isBoolean = match.getType() == boolean.class; - Logger.info(String.format(" %s%s%s", isBoolean ? "(+/-)" : "", match.getName(), isBoolean ? "" : "=")); - } - } + printNoMatchMessage(optionName); return false; } @@ -192,12 +155,12 @@ if (value == null) { if (optionType == Boolean.TYPE || optionType == Boolean.class) { - Logger.info("Value for boolean option '" + optionName + "' must use '-G:+" + optionName + "' or '-G:-" + optionName + "' format"); + System.out.println("Value for boolean option '" + optionName + "' must use '-G:+" + optionName + "' or '-G:-" + optionName + "' format"); return false; } if (valueString == null) { - Logger.info("Value for option '" + optionName + "' must use '-G:" + optionName + "=' format"); + System.out.println("Value for option '" + optionName + "' must use '-G:" + optionName + "=' format"); return false; } @@ -212,7 +175,7 @@ } } else { if (optionType != Boolean.class) { - Logger.info("Value for option '" + optionName + "' must use '-G:" + optionName + "=' format"); + System.out.println("Value for option '" + optionName + "' must use '-G:" + optionName + "=' format"); return false; } } @@ -223,16 +186,28 @@ } else { OptionValue optionValue = desc.getOptionValue(); optionValue.setValue(value); - // Logger.info("Set option " + desc.getName() + " to " + value); + // System.out.println("Set option " + desc.getName() + " to " + value); } } else { - Logger.info("Wrong value \"" + valueString + "\" for option " + optionName); + System.out.println("Wrong value \"" + valueString + "\" for option " + optionName); return false; } return true; } + protected static void printNoMatchMessage(String optionName) { + System.out.println("Could not find option " + optionName + " (use -G:+PrintFlags to see Graal options)"); + List matches = fuzzyMatch(optionName); + if (!matches.isEmpty()) { + System.out.println("Did you mean one of the following?"); + for (OptionDescriptor match : matches) { + boolean isBoolean = match.getType() == boolean.class; + System.out.println(String.format(" %s%s%s", isBoolean ? "(+/-)" : "", match.getName(), isBoolean ? "" : "=")); + } + } + } + /** * Sets the relevant system property such that a {@link DebugTimer} or {@link DebugMetric} * associated with a field in a class will be unconditionally enabled when it is created. @@ -255,7 +230,7 @@ } String previous = System.setProperty(propertyName, "true"); if (previous != null) { - Logger.info("Overrode value \"" + previous + "\" of system property \"" + propertyName + "\" with \"true\""); + System.out.println("Overrode value \"" + previous + "\" of system property \"" + propertyName + "\" with \"true\""); } } catch (Exception e) { throw new GraalInternalError(e); @@ -305,16 +280,16 @@ } private static void printFlags() { - Logger.info("[Graal flags]"); - SortedMap sortedOptions = new TreeMap<>(options); + System.out.println("[Graal flags]"); + SortedMap sortedOptions = options; for (Map.Entry e : sortedOptions.entrySet()) { e.getKey(); OptionDescriptor desc = e.getValue(); Object value = desc.getOptionValue().getValue(); List helpLines = wrap(desc.getHelp(), 70); - Logger.info(String.format("%9s %-40s = %-14s %s", desc.getType().getSimpleName(), e.getKey(), value, helpLines.get(0))); + System.out.println(String.format("%9s %-40s = %-14s %s", desc.getType().getSimpleName(), e.getKey(), value, helpLines.get(0))); for (int i = 1; i < helpLines.size(); i++) { - Logger.info(String.format("%67s %s", " ", helpLines.get(i))); + System.out.println(String.format("%67s %s", " ", helpLines.get(i))); } } diff -r 387b15da0f68 -r fe608a56e3f7 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptionsLoader.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptionsLoader.java Fri May 23 19:36:34 2014 +0200 @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2014, 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 com.oracle.graal.hotspot; + +import java.io.*; +import java.util.*; + +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.options.*; + +/** + * Helper class for separating loading of options from option initialization at runtime. + */ +class HotSpotOptionsLoader { + static final SortedMap options = new TreeMap<>(); + + /** + * Initializes {@link #options} from {@link Options} services. + */ + static { + ServiceLoader sl = ServiceLoader.load(Options.class); + for (Options opts : sl) { + for (OptionDescriptor desc : opts) { + if (isHotSpotOption(desc)) { + String name = desc.getName(); + OptionDescriptor existing = options.put(name, desc); + assert existing == null : "Option named \"" + name + "\" has multiple definitions: " + existing.getLocation() + " and " + desc.getLocation(); + } + } + } + } + + /** + * Determines if a given option is a HotSpot command line option. + */ + private static boolean isHotSpotOption(OptionDescriptor desc) { + return desc.getClass().getName().startsWith("com.oracle.graal"); + } + + /** + * Command line utility for generating the source code of GraalRuntime::set_option(). + * + * @param args one element array with the path of the source file to be created + */ + public static void main(String[] args) throws Exception { + File outputFile = new File(args[0]); + PrintStream out = new PrintStream(outputFile); + Set lengths = new TreeSet<>(); + for (String s : options.keySet()) { + lengths.add(s.length()); + } + lengths.add("PrintFlags".length()); + + out.println("bool GraalRuntime::set_option(KlassHandle hotSpotOptionsClass, const char* name, int name_len, Handle name_handle, const char* value, TRAPS) {"); + out.println(" if (value[0] == '+' || value[0] == '-') {"); + out.println(" // boolean options"); + genMatchers(out, lengths, true); + out.println(" } else {"); + out.println(" // non-boolean options"); + genMatchers(out, lengths, false); + out.println(" }"); + out.println(" return false;"); + out.println("}"); + + out.flush(); + } + + protected static void genMatchers(PrintStream out, Set lengths, boolean isBoolean) throws Exception { + out.println(" switch (name_len) {"); + for (int len : lengths) { + boolean printedCase = false; + + if (len == "PrintFlags".length() && isBoolean) { + printedCase = true; + out.println(" case " + len + ":"); + out.printf(" if (strncmp(name, \"PrintFlags\", %d) == 0) {\n", len); + out.println(" if (value[0] == '+') {"); + out.println(" VMToCompiler::setOption(hotSpotOptionsClass, name_handle, Handle(), '?', Handle(), 0L);"); + out.println(" }"); + out.println(" return true;"); + out.println(" }"); + } + for (Map.Entry e : options.entrySet()) { + OptionDescriptor desc = e.getValue(); + if (e.getKey().length() == len && ((desc.getType() == Boolean.class) == isBoolean)) { + if (!printedCase) { + printedCase = true; + out.println(" case " + len + ":"); + } + out.printf(" if (strncmp(name, \"%s\", %d) == 0) {\n", e.getKey(), len); + Class declaringClass = desc.getDeclaringClass(); + out.printf(" Handle option = get_OptionValue(\"L%s;\", \"%s\", \"L%s;\", CHECK_(true));\n", toInternalName(declaringClass), desc.getFieldName(), + toInternalName(getFieldType(desc))); + if (isBoolean) { + out.println(" VMToCompiler::setOption(hotSpotOptionsClass, name_handle, option, value[0], Handle(), 0L);"); + } else if (desc.getType() == String.class) { + out.println(" Handle stringValue = java_lang_String::create_from_str(value, CHECK_(true));"); + out.println(" VMToCompiler::setOption(hotSpotOptionsClass, name_handle, option, 's', stringValue, 0L);"); + } else { + char spec = getPrimitiveSpecChar(desc); + out.println(" jlong primitiveValue = parse_primitive_option_value('" + spec + "', name_handle, value, CHECK_(true));"); + out.println(" VMToCompiler::setOption(hotSpotOptionsClass, name_handle, option, '" + spec + "', Handle(), primitiveValue);"); + } + out.println(" return true;"); + out.println(" }"); + } + } + } + out.println(" }"); + } + + private static Class getFieldType(OptionDescriptor desc) throws Exception { + return desc.getDeclaringClass().getDeclaredField(desc.getFieldName()).getType(); + } + + private static String toInternalName(Class c) { + return c.getName().replace('.', '/'); + } + + /** + * @see HotSpotOptions#setOption(String, OptionValue, char, String, long) + */ + private static char getPrimitiveSpecChar(OptionDescriptor desc) { + if (desc.getType() == Integer.class) { + return 'i'; + } + if (desc.getType() == Float.class) { + return 'f'; + } + if (desc.getType() == Double.class) { + return 'd'; + } + throw GraalInternalError.shouldNotReachHere("Unexpected primitive option type: " + desc.getType().getName()); + } +} \ No newline at end of file diff -r 387b15da0f68 -r fe608a56e3f7 mx/mx_graal.py --- a/mx/mx_graal.py Fri May 23 17:47:44 2014 +0200 +++ b/mx/mx_graal.py Fri May 23 19:36:34 2014 +0200 @@ -154,7 +154,7 @@ def handleRemoveReadonly(func, path, exc): excvalue = exc[1] if mx.get_os() == 'windows' and func in (os.rmdir, os.remove) and excvalue.errno == errno.EACCES: - os.chmod(path, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO) # 0777 + os.chmod(path, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO) # 0777 func(path) else: raise @@ -212,7 +212,7 @@ def _genFileName(archivtype, middle): idPrefix = infos['revision'] + '_' idSuffix = '.tar.gz' - return join(_graal_home, "graalvm_" + archivtype + "_" + idPrefix + middle + idSuffix) + return join(_graal_home, "graalvm_" + archivtype + "_" + idPrefix + middle + idSuffix) def _genFileArchPlatformName(archivtype, middle): return _genFileName(archivtype, infos['platform'] + '_' + infos['architecture'] + '_' + middle) @@ -484,8 +484,34 @@ if exists(toDelete): os.unlink(toDelete) +def _update_HotSpotOptions_inline_hpp(graalJar): + p = mx.project('com.oracle.graal.hotspot') + mainClass = 'com.oracle.graal.hotspot.HotSpotOptionsLoader' + assert exists(join(p.source_dirs()[0], mainClass.replace('.', os.sep) + '.java')) + hsSrcGenDir = join(p.source_gen_dir(), 'hotspot') + if not exists(hsSrcGenDir): + os.makedirs(hsSrcGenDir) + path = join(hsSrcGenDir, 'HotSpotOptions.inline.hpp') + fd, tmp = tempfile.mkstemp(suffix='', prefix='HotSpotOptions.inline.hpp', dir=hsSrcGenDir) + os.close(fd) + try: + retcode = mx.run_java(['-cp', graalJar, mainClass, tmp], nonZeroIsFatal=False) + if retcode != 0: + # Suppress the error if it's because the utility class isn't compiled yet + with zipfile.ZipFile(graalJar, 'r') as zf: + mainClassFile = mainClass.replace('.', '/') + '.class' + if mainClassFile not in zf.namelist(): + return + mx.abort(retcode) + with open(tmp) as fp: + content = fp.read() + mx.update_file(path, content) + finally: + os.remove(tmp) + def _installGraalJarInJdks(graalDist): graalJar = graalDist.path + _update_HotSpotOptions_inline_hpp(graalJar) jdks = _jdksDir() if exists(jdks): diff -r 387b15da0f68 -r fe608a56e3f7 src/share/vm/graal/graalRuntime.cpp --- a/src/share/vm/graal/graalRuntime.cpp Fri May 23 17:47:44 2014 +0200 +++ b/src/share/vm/graal/graalRuntime.cpp Fri May 23 19:36:34 2014 +0200 @@ -651,17 +651,166 @@ GraalRuntime::initialize_natives(env, c2vmClass); JVM_END -// private static String[] HotSpotOptions.getVMOptions(boolean[] timeCompilations) -JVM_ENTRY(jobject, JVM_GetGraalOptions(JNIEnv *env, jclass c, jobject timeCompilations)) +// private static boolean HotSpotOptions.parseVMOptions() +JVM_ENTRY(jboolean, JVM_ParseGraalOptions(JNIEnv *env, jclass c)) HandleMark hm; + KlassHandle hotSpotOptionsClass(THREAD, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(c))); + return GraalRuntime::parse_arguments(hotSpotOptionsClass, CHECK_false); +JVM_END + +bool GraalRuntime::parse_arguments(KlassHandle hotSpotOptionsClass, TRAPS) { + ResourceMark rm(THREAD); + + // Process option overrides from graal.options first + parse_graal_options_file(hotSpotOptionsClass, CHECK_false); + + // Now process options on the command line int numOptions = Arguments::num_graal_args(); - objArrayOop options = oopFactory::new_objArray(SystemDictionary::String_klass(), - numOptions, CHECK_NULL); - objArrayHandle optionsHandle(THREAD, options); for (int i = 0; i < numOptions; i++) { - Handle option = java_lang_String::create_from_str(Arguments::graal_args_array()[i], CHECK_NULL); - optionsHandle->obj_at_put(i, option()); + char* arg = Arguments::graal_args_array()[i]; + parse_argument(hotSpotOptionsClass, arg, CHECK_false); + } + return CITime || CITimeEach; +} + +void GraalRuntime::parse_argument(KlassHandle hotSpotOptionsClass, char* arg, TRAPS) { + char first = arg[0]; + char* name; + size_t name_len; + Handle name_handle; + bool valid = true; + if (first == '+' || first == '-') { + name = arg + 1; + name_len = strlen(name); + name_handle = java_lang_String::create_from_str(name, CHECK); + valid = set_option(hotSpotOptionsClass, name, name_len, name_handle, arg, CHECK); + } else { + char* sep = strchr(arg, '='); + if (sep != NULL) { + name = arg; + name_len = sep - name; + // Temporarily replace '=' with NULL to create the Java string for the option name + *sep = '\0'; + name_handle = java_lang_String::create_from_str(arg, THREAD); + *sep = '='; + if (HAS_PENDING_EXCEPTION) { + return; + } + valid = set_option(hotSpotOptionsClass, name, name_len, name_handle, sep + 1, CHECK); + } else { + char buf[200]; + jio_snprintf(buf, sizeof(buf), "Value for option %s must use '-G:%s=' format", arg, arg); + THROW_MSG(vmSymbols::java_lang_InternalError(), buf); + } + } + + if (!valid) { + VMToCompiler::setOption(hotSpotOptionsClass, name_handle, Handle(), ' ', Handle(), 0L); + char buf[200]; + jio_snprintf(buf, sizeof(buf), "Invalid Graal option %s", arg); + THROW_MSG(vmSymbols::java_lang_InternalError(), buf); } - ((typeArrayOop) JNIHandles::resolve(timeCompilations))->bool_at_put(0, CITime || CITimeEach); - return JNIHandles::make_local(THREAD, optionsHandle()); -JVM_END +} + +void GraalRuntime::parse_graal_options_file(KlassHandle hotSpotOptionsClass, TRAPS) { + const char* home = Arguments::get_java_home(); + int path_len = strlen(home) + strlen("/lib/graal.options") + 1; + char* path = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, path_len); + char sep = os::file_separator()[0]; + sprintf(path, "%s%clib%cgraal.options", home, sep, sep); + + struct stat st; + if (os::stat(path, &st) == 0) { + int file_handle = os::open(path, 0, 0); + if (file_handle != -1) { + char* buffer = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, st.st_size); + int num_read = (int) os::read(file_handle, (char*) buffer, st.st_size); + if (num_read == -1) { + warning("Error reading file %s due to %s", path, strerror(errno)); + } else if (num_read != st.st_size) { + warning("Only read %d of %d bytes from %s", num_read, st.st_size, path); + } + os::close(file_handle); + if (num_read == st.st_size) { + char* line = buffer; + int lineNo = 1; + while (line - buffer < num_read) { + char* nl = strchr(line, '\n'); + if (nl != NULL) { + *nl = '\0'; + } + parse_argument(hotSpotOptionsClass, line, THREAD); + if (HAS_PENDING_EXCEPTION) { + warning("Error in %s:%d", path, lineNo); + return; + } + if (nl != NULL) { + line = nl + 1; + lineNo++; + } else { + // File without newline at the end + break; + } + } + } + } else { + warning("Error opening file %s due to %s", path, strerror(errno)); + } + } +} + +jlong GraalRuntime::parse_primitive_option_value(char spec, Handle name, const char* value, TRAPS) { + union { + jint i; + jlong l; + double d; + } uu; + uu.l = 0L; + char dummy; + switch (spec) { + case 'd': + case 'f': { + if (sscanf(value, "%lf%c", &uu.d, &dummy) == 1) { + return uu.l; + } + break; + } + case 'i': { + if (sscanf(value, "%d%c", &uu.i, &dummy) == 1) { + return uu.l; + } + break; + } + default: + ShouldNotReachHere(); + } + ResourceMark rm(THREAD); + char buf[200]; + jio_snprintf(buf, sizeof(buf), "Invalid %s value for Graal option %s: %s", (spec == 'i' ? "numeric" : "float/double"), java_lang_String::as_utf8_string(name()), value); + THROW_MSG_(vmSymbols::java_lang_InternalError(), buf, 0L); +} + +Handle GraalRuntime::get_OptionValue(const char* declaringClass, const char* fieldName, const char* fieldSig, TRAPS) { + TempNewSymbol name = SymbolTable::new_symbol(declaringClass, THREAD); + Klass* klass = SystemDictionary::resolve_or_fail(name, true, CHECK_NH); + + // The class has been loaded so the field and signature should already be in the symbol + // table. If they're not there, the field doesn't exist. + TempNewSymbol fieldname = SymbolTable::probe(fieldName, (int)strlen(fieldName)); + TempNewSymbol signame = SymbolTable::probe(fieldSig, (int)strlen(fieldSig)); + if (fieldname == NULL || signame == NULL) { + THROW_MSG_(vmSymbols::java_lang_NoSuchFieldError(), (char*) fieldName, Handle()); + } + // Make sure class is initialized before handing id's out to fields + klass->initialize(CHECK_NH); + + fieldDescriptor fd; + if (!InstanceKlass::cast(klass)->find_field(fieldname, signame, true, &fd)) { + THROW_MSG_(vmSymbols::java_lang_NoSuchFieldError(), (char*) fieldName, Handle()); + } + + Handle ret = klass->java_mirror()->obj_field(fd.offset()); + return ret; +} + +#include "HotSpotOptions.inline.hpp" diff -r 387b15da0f68 -r fe608a56e3f7 src/share/vm/graal/graalRuntime.hpp --- a/src/share/vm/graal/graalRuntime.hpp Fri May 23 17:47:44 2014 +0200 +++ b/src/share/vm/graal/graalRuntime.hpp Fri May 23 19:36:34 2014 +0200 @@ -31,12 +31,55 @@ class GraalRuntime: public CHeapObj { private: - static address _external_deopt_i2c_entry; + static address _external_deopt_i2c_entry; + + /** + * Reads the OptionValue object from a specified static field. + * + * @throws LinkageError if the field could not be resolved + */ + static Handle get_OptionValue(const char* declaringClass, const char* fieldName, const char* fieldSig, TRAPS); + + /** + * Parses the string form of a numeric, float or double option into a jlong (using raw bits for floats/doubles). + * + * @param spec 'i', 'f' or 'd' (see HotSpotOptions.setOption()) + * @param name name option option + * @param value string value to parse + * @throws InternalError if value could not be parsed according to spec + */ + static jlong parse_primitive_option_value(char spec, Handle name, const char* value, TRAPS); + + /** + * Loads default option value overrides from a /lib/graal.options if it exists. Each + * line in this file must have the format of a Graal command line option without the + * leading "-G:" prefix. These option values are set prior to processing of any Graal + * options present on the command line. + */ + static void parse_graal_options_file(KlassHandle hotSpotOptionsClass, TRAPS); + + /** + * Parses a given argument and sets the denoted Graal option. + * + * @throws InternalError if there was a problem parsing or setting the option + */ + static void parse_argument(KlassHandle hotSpotOptionsClass, char* arg, TRAPS); + + /** + * Searches for a Graal option denoted by a given name and sets it value. + * + * @returns true if the option was found + * @throws InternalError if there was a problem setting the option's value + */ + static bool set_option(KlassHandle hotSpotOptionsClass, const char* name, int name_len, Handle name_handle, const char* value, TRAPS); public: static void initialize_natives(JNIEnv *env, jclass c2vmClass); static BufferBlob* initialize_buffer_blob(); + + static bool parse_arguments(KlassHandle hotSpotOptionsClass, TRAPS); + static BasicType kindToBasicType(jchar ch); static address create_external_deopt_i2c(); static address get_external_deopt_i2c_entry() {return _external_deopt_i2c_entry;} diff -r 387b15da0f68 -r fe608a56e3f7 src/share/vm/graal/graalVMToCompiler.cpp --- a/src/share/vm/graal/graalVMToCompiler.cpp Fri May 23 17:47:44 2014 +0200 +++ b/src/share/vm/graal/graalVMToCompiler.cpp Fri May 23 19:36:34 2014 +0200 @@ -94,48 +94,20 @@ return Handle(JNIHandles::resolve_non_null(_VMToCompiler_instance)); } -void VMToCompiler::initOptions() { +void VMToCompiler::setOption(KlassHandle hotSpotOptionsClass, Handle name, Handle option, jchar spec, Handle stringValue, jlong primitiveValue) { + assert(!option.is_null(), "npe"); Thread* THREAD = Thread::current(); - TempNewSymbol name = SymbolTable::new_symbol("com/oracle/graal/hotspot/HotSpotOptions", THREAD); - KlassHandle optionsKlass = loadClass(name); - optionsKlass->initialize(THREAD); - check_pending_exception("Error while calling initOptions"); -} - -jboolean VMToCompiler::setOption(Handle option) { - assert(!option.is_null(), ""); - Thread* THREAD = Thread::current(); - TempNewSymbol name = SymbolTable::new_symbol("com/oracle/graal/hotspot/HotSpotOptions", THREAD); TempNewSymbol setOption = SymbolTable::new_symbol("setOption", THREAD); - TempNewSymbol sig = SymbolTable::new_symbol("(Ljava/lang/String;)Z", THREAD); - KlassHandle optionsKlass = loadClass(name); - JavaValue result(T_BOOLEAN); - JavaCalls::call_static(&result, optionsKlass, setOption, sig, option, THREAD); - check_pending_exception("Error while calling setOption"); - return result.get_jboolean(); -} - -void VMToCompiler::finalizeOptions(jboolean ciTime) { - Thread* THREAD = Thread::current(); - TempNewSymbol name = SymbolTable::new_symbol("com/oracle/graal/hotspot/HotSpotOptions", THREAD); - TempNewSymbol finalizeOptions = SymbolTable::new_symbol("finalizeOptions", THREAD); - TempNewSymbol sig = SymbolTable::new_symbol("(Ljava/lang/String;)Z", THREAD); - KlassHandle optionsKlass = loadClass(name); + TempNewSymbol sig = SymbolTable::new_symbol("(Ljava/lang/String;Lcom/oracle/graal/options/OptionValue;CLjava/lang/String;J)V", THREAD); JavaValue result(T_VOID); JavaCallArguments args; - args.push_int(ciTime); - JavaCalls::call_static(&result, optionsKlass, finalizeOptions, vmSymbols::bool_void_signature(), &args, THREAD); - check_pending_exception("Error while calling finalizeOptions"); -} - -void VMToCompiler::startRuntime() { - JavaThread* THREAD = JavaThread::current(); - JavaValue result(T_VOID); - JavaCallArguments args; - TempNewSymbol startRuntime = SymbolTable::new_symbol("startRuntime", THREAD); - args.push_oop(VMToCompiler_instance()); - JavaCalls::call_interface(&result, VMToCompiler_klass(), startRuntime, vmSymbols::void_method_signature(), &args, THREAD); - check_pending_exception("Error while calling startRuntime"); + args.push_oop(name()); + args.push_oop(option()); + args.push_int(spec); + args.push_oop(stringValue()); + args.push_long(primitiveValue); + JavaCalls::call_static(&result, hotSpotOptionsClass, setOption, sig, &args, THREAD); + check_pending_exception("Error while calling setOption"); } #ifdef COMPILERGRAAL diff -r 387b15da0f68 -r fe608a56e3f7 src/share/vm/graal/graalVMToCompiler.hpp --- a/src/share/vm/graal/graalVMToCompiler.hpp Fri May 23 17:47:44 2014 +0200 +++ b/src/share/vm/graal/graalVMToCompiler.hpp Fri May 23 19:36:34 2014 +0200 @@ -55,17 +55,8 @@ return _HotSpotGraalRuntime_instance; } - // public static boolean HotSpotOptions.(); - static void initOptions(); - - // public static boolean HotSpotOptions.setOption(String option); - static jboolean setOption(Handle option); - - // public static void HotSpotOptions.finalizeOptions(boolean ciTime); - static void finalizeOptions(jboolean ciTime); - - // public abstract void startRuntime(); - static void startRuntime(); + // public static void HotSpotOptions.setOption(String name, OptionValue option, char spec, String stringValue, long primitiveValue); + static void setOption(KlassHandle hotSpotOptionsClass, Handle name, Handle option, jchar spec, Handle stringValue, jlong primitiveValue); #ifdef COMPILERGRAAL // public abstract void startCompiler(boolean bootstrapEnabled); diff -r 387b15da0f68 -r fe608a56e3f7 src/share/vm/prims/nativeLookup.cpp --- a/src/share/vm/prims/nativeLookup.cpp Fri May 23 17:47:44 2014 +0200 +++ b/src/share/vm/prims/nativeLookup.cpp Fri May 23 19:36:34 2014 +0200 @@ -124,10 +124,10 @@ void JNICALL JVM_RegisterPerfMethods(JNIEnv *env, jclass perfclass); void JNICALL JVM_RegisterWhiteBoxMethods(JNIEnv *env, jclass wbclass); #ifdef GRAAL - void JNICALL JVM_InitializeGraalNatives(JNIEnv *env, jclass c, jclass compilerToVMClass); - jobject JNICALL JVM_GetGraalRuntime(JNIEnv *env, jclass c); - jobject JNICALL JVM_CreateTruffleRuntime(JNIEnv *env, jclass c); - jobject JNICALL JVM_GetGraalOptions(JNIEnv *env, jclass hotspotOptionsClass, jobject timeCompilations); + void JNICALL JVM_InitializeGraalNatives(JNIEnv *env, jclass c, jclass compilerToVMClass); + jobject JNICALL JVM_GetGraalRuntime(JNIEnv *env, jclass c); + jobject JNICALL JVM_CreateTruffleRuntime(JNIEnv *env, jclass c); + jboolean JNICALL JVM_ParseGraalOptions(JNIEnv *env, jclass hotspotOptionsClass); #endif } @@ -140,10 +140,10 @@ { CC"Java_sun_misc_Perf_registerNatives", NULL, FN_PTR(JVM_RegisterPerfMethods) }, { CC"Java_sun_hotspot_WhiteBox_registerNatives", NULL, FN_PTR(JVM_RegisterWhiteBoxMethods) }, #ifdef GRAAL - { CC"Java_com_oracle_graal_api_runtime_Graal_initializeRuntime", NULL, FN_PTR(JVM_GetGraalRuntime) }, - { CC"Java_com_oracle_truffle_api_Truffle_createRuntime", NULL, FN_PTR(JVM_CreateTruffleRuntime) }, - { CC"Java_com_oracle_graal_hotspot_HotSpotGraalRuntime_init", NULL, FN_PTR(JVM_InitializeGraalNatives) }, - { CC"Java_com_oracle_graal_hotspot_HotSpotOptions_getVMOptions", NULL, FN_PTR(JVM_GetGraalOptions) }, + { CC"Java_com_oracle_graal_api_runtime_Graal_initializeRuntime", NULL, FN_PTR(JVM_GetGraalRuntime) }, + { CC"Java_com_oracle_truffle_api_Truffle_createRuntime", NULL, FN_PTR(JVM_CreateTruffleRuntime) }, + { CC"Java_com_oracle_graal_hotspot_HotSpotGraalRuntime_init", NULL, FN_PTR(JVM_InitializeGraalNatives) }, + { CC"Java_com_oracle_graal_hotspot_HotSpotOptions_parseVMOptions", NULL, FN_PTR(JVM_ParseGraalOptions) }, #endif };