# HG changeset patch # User jrose # Date 1306995920 25200 # Node ID ba550512d3b2a88469269c5994b0500118f0ee49 # Parent f88fb2fa90cf92088890d601c13046546df61cb0 7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError Summary: Delegate invokedynamic linkage errors to MethodHandleNatives.raiseException. Reviewed-by: never diff -r f88fb2fa90cf -r ba550512d3b2 src/share/vm/classfile/systemDictionary.hpp --- a/src/share/vm/classfile/systemDictionary.hpp Tue May 31 10:05:36 2011 -0700 +++ b/src/share/vm/classfile/systemDictionary.hpp Wed Jun 01 23:25:20 2011 -0700 @@ -152,6 +152,7 @@ template(DirectMethodHandle_klass, java_lang_invoke_DirectMethodHandle, Pre_JSR292) \ template(MethodType_klass, java_lang_invoke_MethodType, Pre_JSR292) \ template(MethodTypeForm_klass, java_lang_invoke_MethodTypeForm, Pre_JSR292) \ + template(BootstrapMethodError_klass, java_lang_BootstrapMethodError, Pre_JSR292) \ template(WrongMethodTypeException_klass, java_lang_invoke_WrongMethodTypeException, Pre_JSR292) \ template(CallSite_klass, java_lang_invoke_CallSite, Pre_JSR292) \ /* Note: MethodHandle must be first, and CallSite last in group */ \ diff -r f88fb2fa90cf -r ba550512d3b2 src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Tue May 31 10:05:36 2011 -0700 +++ b/src/share/vm/classfile/vmSymbols.hpp Wed Jun 01 23:25:20 2011 -0700 @@ -148,6 +148,7 @@ template(java_lang_InstantiationException, "java/lang/InstantiationException") \ template(java_lang_InstantiationError, "java/lang/InstantiationError") \ template(java_lang_InterruptedException, "java/lang/InterruptedException") \ + template(java_lang_BootstrapMethodError, "java/lang/BootstrapMethodError") \ template(java_lang_LinkageError, "java/lang/LinkageError") \ template(java_lang_NegativeArraySizeException, "java/lang/NegativeArraySizeException") \ template(java_lang_NoSuchFieldException, "java/lang/NoSuchFieldException") \ diff -r f88fb2fa90cf -r ba550512d3b2 src/share/vm/interpreter/linkResolver.cpp --- a/src/share/vm/interpreter/linkResolver.cpp Tue May 31 10:05:36 2011 -0700 +++ b/src/share/vm/interpreter/linkResolver.cpp Wed Jun 01 23:25:20 2011 -0700 @@ -1117,7 +1117,24 @@ // The extra MH receiver will be inserted into the stack on every call. methodHandle resolved_method; KlassHandle current_klass(THREAD, pool->pool_holder()); - lookup_implicit_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, CHECK); + lookup_implicit_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, THREAD); + if (HAS_PENDING_EXCEPTION) { + if (PENDING_EXCEPTION->is_a(SystemDictionary::BootstrapMethodError_klass())) { + // throw these guys, since they are already wrapped + return; + } + if (!PENDING_EXCEPTION->is_a(SystemDictionary::LinkageError_klass())) { + // intercept only LinkageErrors which might have failed to wrap + return; + } + // See the "Linking Exceptions" section for the invokedynamic instruction in the JVMS. + Handle ex(THREAD, PENDING_EXCEPTION); + CLEAR_PENDING_EXCEPTION; + oop bsme = Klass::cast(SystemDictionary::BootstrapMethodError_klass())->java_mirror(); + MethodHandles::raise_exception(Bytecodes::_athrow, ex(), bsme, CHECK); + // java code should not return, but if it does throw out anyway + THROW(vmSymbols::java_lang_InternalError()); + } if (resolved_method.is_null()) { THROW(vmSymbols::java_lang_InternalError()); } diff -r f88fb2fa90cf -r ba550512d3b2 src/share/vm/prims/methodHandles.cpp --- a/src/share/vm/prims/methodHandles.cpp Tue May 31 10:05:36 2011 -0700 +++ b/src/share/vm/prims/methodHandles.cpp Wed Jun 01 23:25:20 2011 -0700 @@ -2970,6 +2970,45 @@ } JVM_END +methodOop MethodHandles::resolve_raise_exception_method(TRAPS) { + if (_raise_exception_method != NULL) { + // no need to do it twice + return raise_exception_method(); + } + // LinkResolver::resolve_invokedynamic can reach this point + // because an invokedynamic has failed very early (7049415) + KlassHandle MHN_klass = SystemDictionaryHandles::MethodHandleNatives_klass(); + if (MHN_klass.not_null()) { + TempNewSymbol raiseException_name = SymbolTable::new_symbol("raiseException", CHECK_NULL); + TempNewSymbol raiseException_sig = SymbolTable::new_symbol("(ILjava/lang/Object;Ljava/lang/Object;)V", CHECK_NULL); + methodOop raiseException_method = instanceKlass::cast(MHN_klass->as_klassOop()) + ->find_method(raiseException_name, raiseException_sig); + if (raiseException_method != NULL && raiseException_method->is_static()) { + return raiseException_method; + } + } + // not found; let the caller deal with it + return NULL; +} +void MethodHandles::raise_exception(int code, oop actual, oop required, TRAPS) { + methodOop raiseException_method = resolve_raise_exception_method(CHECK); + if (raiseException_method != NULL && + instanceKlass::cast(raiseException_method->method_holder())->is_not_initialized()) { + instanceKlass::cast(raiseException_method->method_holder())->initialize(CHECK); + // it had better be resolved by now, or maybe JSR 292 failed to load + raiseException_method = raise_exception_method(); + } + if (raiseException_method == NULL) { + THROW_MSG(vmSymbols::java_lang_InternalError(), "no raiseException method"); + } + JavaCallArguments args; + args.push_int(code); + args.push_oop(actual); + args.push_oop(required); + JavaValue result(T_VOID); + JavaCalls::call(&result, raiseException_method, &args, CHECK); +} + JVM_ENTRY(jobject, MH_invoke_UOE(JNIEnv *env, jobject igmh, jobjectArray igargs)) { TempNewSymbol UOE_name = SymbolTable::new_symbol("java/lang/UnsupportedOperationException", CHECK_NULL); THROW_MSG_NULL(UOE_name, "MethodHandle.invoke cannot be invoked reflectively"); @@ -3059,19 +3098,11 @@ } if (enable_MH) { - KlassHandle MHN_klass = SystemDictionaryHandles::MethodHandleNatives_klass(); - if (MHN_klass.not_null()) { - TempNewSymbol raiseException_name = SymbolTable::new_symbol("raiseException", CHECK); - TempNewSymbol raiseException_sig = SymbolTable::new_symbol("(ILjava/lang/Object;Ljava/lang/Object;)V", CHECK); - methodOop raiseException_method = instanceKlass::cast(MHN_klass->as_klassOop()) - ->find_method(raiseException_name, raiseException_sig); - if (raiseException_method != NULL && raiseException_method->is_static()) { - MethodHandles::set_raise_exception_method(raiseException_method); - } else { - warning("JSR 292 method handle code is mismatched to this JVM. Disabling support."); - enable_MH = false; - } + methodOop raiseException_method = MethodHandles::resolve_raise_exception_method(CHECK); + if (raiseException_method != NULL) { + MethodHandles::set_raise_exception_method(raiseException_method); } else { + warning("JSR 292 method handle code is mismatched to this JVM. Disabling support."); enable_MH = false; } } diff -r f88fb2fa90cf -r ba550512d3b2 src/share/vm/prims/methodHandles.hpp --- a/src/share/vm/prims/methodHandles.hpp Tue May 31 10:05:36 2011 -0700 +++ b/src/share/vm/prims/methodHandles.hpp Wed Jun 01 23:25:20 2011 -0700 @@ -439,6 +439,9 @@ assert(_raise_exception_method == NULL, ""); _raise_exception_method = JNIHandles::make_global(Handle(rem)); } + static methodOop resolve_raise_exception_method(TRAPS); + // call raise_exception_method from C code: + static void raise_exception(int code, oop actual, oop required, TRAPS); static jint adapter_conversion(int conv_op, BasicType src, BasicType dest, int stack_move = 0, int vminfo = 0) {