Mercurial > hg > truffle
diff src/share/vm/graal/graalRuntime.cpp @ 16270:d56a09df1a1f
implemented eager checking of Graal options (GRAAL-807)
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Fri, 27 Jun 2014 19:55:54 +0200 |
parents | 66a9286203a2 |
children | d6ffc6164830 |
line wrap: on
line diff
--- a/src/share/vm/graal/graalRuntime.cpp Fri Jun 27 17:24:28 2014 +0200 +++ b/src/share/vm/graal/graalRuntime.cpp Fri Jun 27 19:55:54 2014 +0200 @@ -701,6 +701,31 @@ JVM_END #endif +jint GraalRuntime::check_arguments(TRAPS) { + KlassHandle nullHandle; + parse_arguments(nullHandle, THREAD); + if (HAS_PENDING_EXCEPTION) { + // Errors in parsing Graal arguments cause exceptions. + // We now load and initialize HotSpotOptions which in turn + // causes argument parsing to be redone with better error messages. + CLEAR_PENDING_EXCEPTION; + TempNewSymbol name = SymbolTable::new_symbol("Lcom/oracle/graal/hotspot/HotSpotOptions;", THREAD); + instanceKlassHandle hotSpotOptionsClass = SystemDictionary::resolve_or_fail(name, true, THREAD); + GUARANTEE_NO_PENDING_EXCEPTION("Error in check_arguments"); + + parse_arguments(hotSpotOptionsClass, THREAD); + assert(HAS_PENDING_EXCEPTION, "must be"); + + ResourceMark rm; + oop message = java_lang_Throwable::message(PENDING_EXCEPTION); + assert(message != NULL, "Graal argument parsing exception is expected to hava message"); + tty->print_cr("Error parsing Graal options: %s", java_lang_String::as_utf8_string(message)); + CLEAR_PENDING_EXCEPTION; + return JNI_ERR; + } + return JNI_OK; +} + bool GraalRuntime::parse_arguments(KlassHandle hotSpotOptionsClass, TRAPS) { ResourceMark rm(THREAD); @@ -716,43 +741,52 @@ return CITime || CITimeEach; } +void GraalRuntime::check_required_value(const char* name, int name_len, const char* value, TRAPS) { + if (value == NULL) { + char buf[200]; + jio_snprintf(buf, sizeof(buf), "Value for option %.*s must use '-G:%.*s=<value>' format", name_len, name, name_len, name); + THROW_MSG(vmSymbols::java_lang_InternalError(), buf); + } +} + 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; + bool recognized = 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, (int)name_len, name_handle, arg, CHECK); + recognized = set_option(hotSpotOptionsClass, name, (int)name_len, arg, CHECK); } else { char* sep = strchr(arg, '='); + name = arg; + char* value = NULL; 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; + value = sep + 1; + } else { + name_len = strlen(name); + } + recognized = set_option(hotSpotOptionsClass, name, (int)name_len, value, CHECK); + } + + if (!recognized) { + bool throw_err = hotSpotOptionsClass.is_null(); + if (!hotSpotOptionsClass.is_null()) { + instanceKlassHandle ikh(hotSpotOptionsClass()); + if (!ikh->is_reentrant_initialization(THREAD)) { + set_option_helper(hotSpotOptionsClass, name, name_len, Handle(), ' ', Handle(), 0L); + throw_err = true; } - valid = set_option(hotSpotOptionsClass, name, (int)name_len, name_handle, sep + 1, CHECK); - } else { + } + + if (throw_err) { char buf[200]; - jio_snprintf(buf, sizeof(buf), "Value for option %s must use '-G:%s=<value>' format", arg, arg); + jio_snprintf(buf, sizeof(buf), "Unrecognized Graal option %.*s", name_len, name); THROW_MSG(vmSymbols::java_lang_InternalError(), buf); } } - - if (!valid) { - set_option_helper(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); - } } void GraalRuntime::parse_graal_options_file(KlassHandle hotSpotOptionsClass, TRAPS) { @@ -802,7 +836,8 @@ } } -jlong GraalRuntime::parse_primitive_option_value(char spec, Handle name, const char* value, TRAPS) { +jlong GraalRuntime::parse_primitive_option_value(char spec, const char* name, int name_len, const char* value, TRAPS) { + check_required_value(name, name_len, value, CHECK_(0L)); union { jint i; jlong l; @@ -829,23 +864,39 @@ } 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); + jio_snprintf(buf, sizeof(buf), "Invalid %s value for Graal option %.*s: %s", (spec == 'i' ? "numeric" : "float/double"), name, name_len, value); THROW_MSG_(vmSymbols::java_lang_InternalError(), buf, 0L); } -void GraalRuntime::set_option_helper(KlassHandle hotSpotOptionsClass, Handle name, Handle option, jchar spec, Handle stringValue, jlong primitiveValue) { +void GraalRuntime::set_option_helper(KlassHandle hotSpotOptionsClass, char* name, int name_len, Handle option, jchar spec, Handle stringValue, jlong primitiveValue) { Thread* THREAD = Thread::current(); + Handle name_handle; + if (name != NULL) { + if ((int) strlen(name) > name_len) { + // Temporarily replace '=' with NULL to create the Java string for the option name + char save = name[name_len]; + name[name_len] = '\0'; + name_handle = java_lang_String::create_from_str(name, THREAD); + name[name_len] = '='; + if (HAS_PENDING_EXCEPTION) { + return; + } + } else { + assert((int) strlen(name) == name_len, "must be"); + name_handle = java_lang_String::create_from_str(name, CHECK); + } + } + TempNewSymbol setOption = SymbolTable::new_symbol("setOption", THREAD); 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_oop(name()); + args.push_oop(name_handle()); 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); - GUARANTEE_NO_PENDING_EXCEPTION("Error while calling set_option_helper"); + JavaCalls::call_static(&result, hotSpotOptionsClass, setOption, sig, &args, CHECK); } Handle GraalRuntime::get_OptionValue(const char* declaringClass, const char* fieldName, const char* fieldSig, TRAPS) { @@ -906,6 +957,7 @@ assert(exception->is_a(SystemDictionary::Throwable_klass()), "Throwable instance expected"); JavaValue result(T_VOID); + tty->print_cr(message); JavaCalls::call_virtual(&result, exception, KlassHandle(THREAD,