Mercurial > hg > graal-jvmci-8
diff src/share/vm/graal/graalRuntime.cpp @ 15870:fe608a56e3f7
made HotSpotOptions processing faster by removing use of service loader in VM startup and only doing work for options specified on the command line
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Fri, 23 May 2014 19:36:34 +0200 |
parents | b7fb36e57da8 |
children | a9810ed7cad2 |
line wrap: on
line diff
--- 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=<value>' 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"