# HG changeset patch # User twisti # Date 1344375128 25200 # Node ID 93c71eb288664b1dece32d31aaff0447511ff842 # Parent b72784e722ff2287009e0b8d70cda706e7fa5747 7188911: nightly failures after JSR 292 lazy method handle update (round 2) Reviewed-by: kvn, jrose diff -r b72784e722ff -r 93c71eb28866 src/share/vm/classfile/verifier.cpp --- a/src/share/vm/classfile/verifier.cpp Wed Aug 01 14:44:26 2012 -0700 +++ b/src/share/vm/classfile/verifier.cpp Tue Aug 07 14:32:08 2012 -0700 @@ -327,7 +327,7 @@ const char* bad_type_msg = "Bad type on operand stack in %s"; - int32_t max_stack = m->max_stack(); + int32_t max_stack = m->verifier_max_stack(); int32_t max_locals = m->max_locals(); constantPoolHandle cp(THREAD, m->constants()); diff -r b72784e722ff -r 93c71eb28866 src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Wed Aug 01 14:44:26 2012 -0700 +++ b/src/share/vm/classfile/vmSymbols.hpp Tue Aug 07 14:32:08 2012 -0700 @@ -160,6 +160,7 @@ template(java_lang_NoSuchMethodException, "java/lang/NoSuchMethodException") \ template(java_lang_NullPointerException, "java/lang/NullPointerException") \ template(java_lang_StringIndexOutOfBoundsException, "java/lang/StringIndexOutOfBoundsException")\ + template(java_lang_UnsupportedOperationException, "java/lang/UnsupportedOperationException") \ template(java_lang_InvalidClassException, "java/lang/InvalidClassException") \ template(java_lang_reflect_InvocationTargetException, "java/lang/reflect/InvocationTargetException") \ template(java_lang_Exception, "java/lang/Exception") \ diff -r b72784e722ff -r 93c71eb28866 src/share/vm/interpreter/linkResolver.cpp --- a/src/share/vm/interpreter/linkResolver.cpp Wed Aug 01 14:44:26 2012 -0700 +++ b/src/share/vm/interpreter/linkResolver.cpp Tue Aug 07 14:32:08 2012 -0700 @@ -1265,7 +1265,7 @@ bootstrap_specifier, method_name, method_signature, &resolved_appendix, - CHECK); + THREAD); if (HAS_PENDING_EXCEPTION) { if (TraceMethodHandles) { tty->print_cr("invokedynamic throws BSME for "INTPTR_FORMAT, PENDING_EXCEPTION); @@ -1282,8 +1282,7 @@ // See the "Linking Exceptions" section for the invokedynamic instruction in the JVMS. Handle nested_exception(THREAD, PENDING_EXCEPTION); CLEAR_PENDING_EXCEPTION; - THROW_MSG_CAUSE(vmSymbols::java_lang_BootstrapMethodError(), - "BootstrapMethodError", nested_exception) + THROW_CAUSE(vmSymbols::java_lang_BootstrapMethodError(), nested_exception) } result.set_handle(resolved_method, resolved_appendix, CHECK); } diff -r b72784e722ff -r 93c71eb28866 src/share/vm/oops/methodOop.hpp --- a/src/share/vm/oops/methodOop.hpp Wed Aug 01 14:44:26 2012 -0700 +++ b/src/share/vm/oops/methodOop.hpp Tue Aug 07 14:32:08 2012 -0700 @@ -247,8 +247,10 @@ void set_constants(constantPoolOop c) { constMethod()->set_constants(c); } // max stack - int max_stack() const { return _max_stack + extra_stack_entries(); } - void set_max_stack(int size) { _max_stack = size; } + // return original max stack size for method verification + int verifier_max_stack() const { return _max_stack; } + int max_stack() const { return _max_stack + extra_stack_entries(); } + void set_max_stack(int size) { _max_stack = size; } // max locals int max_locals() const { return _max_locals; } diff -r b72784e722ff -r 93c71eb28866 src/share/vm/prims/jvm.cpp --- a/src/share/vm/prims/jvm.cpp Wed Aug 01 14:44:26 2012 -0700 +++ b/src/share/vm/prims/jvm.cpp Tue Aug 07 14:32:08 2012 -0700 @@ -2241,7 +2241,7 @@ klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls)); k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread); oop method = instanceKlass::cast(k)->methods()->obj_at(method_index); - return methodOop(method)->max_stack(); + return methodOop(method)->verifier_max_stack(); JVM_END diff -r b72784e722ff -r 93c71eb28866 src/share/vm/prims/methodHandles.cpp --- a/src/share/vm/prims/methodHandles.cpp Wed Aug 01 14:44:26 2012 -0700 +++ b/src/share/vm/prims/methodHandles.cpp Tue Aug 07 14:32:08 2012 -0700 @@ -1196,21 +1196,6 @@ } JVM_END -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"); - return NULL; -} -JVM_END - -JVM_ENTRY(jobject, MH_invokeExact_UOE(JNIEnv *env, jobject igmh, jobjectArray igargs)) { - TempNewSymbol UOE_name = SymbolTable::new_symbol("java/lang/UnsupportedOperationException", CHECK_NULL); - THROW_MSG_NULL(UOE_name, "MethodHandle.invokeExact cannot be invoked reflectively"); - return NULL; -} -JVM_END - - /// JVM_RegisterMethodHandleMethods #undef CS // Solaris builds complain @@ -1248,11 +1233,6 @@ {CC"getMemberVMInfo", CC"("MEM")"OBJ, FN_PTR(MHN_getMemberVMInfo)} }; -static JNINativeMethod invoke_methods[] = { - {CC"invoke", CC"(["OBJ")"OBJ, FN_PTR(MH_invoke_UOE)}, - {CC"invokeExact", CC"(["OBJ")"OBJ, FN_PTR(MH_invokeExact_UOE)} -}; - // This one function is exported, used by NativeLookup. JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class)) { @@ -1278,9 +1258,6 @@ ThreadToNativeFromVM ttnfv(thread); status = env->RegisterNatives(MHN_class, required_methods_JDK8, sizeof(required_methods_JDK8)/sizeof(JNINativeMethod)); - if (status == JNI_OK && !env->ExceptionOccurred()) { - status = env->RegisterNatives(MH_class, invoke_methods, sizeof(invoke_methods)/sizeof(JNINativeMethod)); - } if (status != JNI_OK || env->ExceptionOccurred()) { warning("JSR 292 method handle code is mismatched to this JVM. Disabling support."); enable_MH = false; diff -r b72784e722ff -r 93c71eb28866 src/share/vm/prims/nativeLookup.cpp --- a/src/share/vm/prims/nativeLookup.cpp Wed Aug 01 14:44:26 2012 -0700 +++ b/src/share/vm/prims/nativeLookup.cpp Tue Aug 07 14:32:08 2012 -0700 @@ -381,7 +381,10 @@ address NativeLookup::lookup(methodHandle method, bool& in_base_library, TRAPS) { if (!method->has_native_function()) { - address entry = lookup_base(method, in_base_library, CHECK_NULL); + address entry = + method->intrinsic_id() == vmIntrinsics::_invokeGeneric ? + SharedRuntime::native_method_throw_unsupported_operation_exception_entry() : + lookup_base(method, in_base_library, CHECK_NULL); method->set_native_function(entry, methodOopDesc::native_bind_event_is_interesting); // -verbose:jni printing diff -r b72784e722ff -r 93c71eb28866 src/share/vm/runtime/sharedRuntime.cpp --- a/src/share/vm/runtime/sharedRuntime.cpp Wed Aug 01 14:44:26 2012 -0700 +++ b/src/share/vm/runtime/sharedRuntime.cpp Tue Aug 07 14:32:08 2012 -0700 @@ -874,11 +874,20 @@ } JNI_END +JNI_ENTRY(void, throw_unsupported_operation_exception(JNIEnv* env, ...)) +{ + THROW(vmSymbols::java_lang_UnsupportedOperationException()); +} +JNI_END address SharedRuntime::native_method_throw_unsatisfied_link_error_entry() { return CAST_FROM_FN_PTR(address, &throw_unsatisfied_link_error); } +address SharedRuntime::native_method_throw_unsupported_operation_exception_entry() { + return CAST_FROM_FN_PTR(address, &throw_unsupported_operation_exception); +} + #ifndef PRODUCT JRT_ENTRY(intptr_t, SharedRuntime::trace_bytecode(JavaThread* thread, intptr_t preserve_this_value, intptr_t tos, intptr_t tos2)) diff -r b72784e722ff -r 93c71eb28866 src/share/vm/runtime/sharedRuntime.hpp --- a/src/share/vm/runtime/sharedRuntime.hpp Wed Aug 01 14:44:26 2012 -0700 +++ b/src/share/vm/runtime/sharedRuntime.hpp Tue Aug 07 14:32:08 2012 -0700 @@ -238,6 +238,7 @@ // To be used as the entry point for unresolved native methods. static address native_method_throw_unsatisfied_link_error_entry(); + static address native_method_throw_unsupported_operation_exception_entry(); // bytecode tracing is only used by the TraceBytecodes static intptr_t trace_bytecode(JavaThread* thread, intptr_t preserve_this_value, intptr_t tos, intptr_t tos2) PRODUCT_RETURN0; diff -r b72784e722ff -r 93c71eb28866 src/share/vm/utilities/exceptions.cpp --- a/src/share/vm/utilities/exceptions.cpp Wed Aug 01 14:44:26 2012 -0700 +++ b/src/share/vm/utilities/exceptions.cpp Tue Aug 07 14:32:08 2012 -0700 @@ -164,52 +164,58 @@ } -void Exceptions::_throw_msg(Thread* thread, const char* file, int line, Symbol* h_name, const char* message, Handle h_loader, Handle h_protection_domain) { +void Exceptions::_throw_msg(Thread* thread, const char* file, int line, Symbol* name, const char* message, + Handle h_loader, Handle h_protection_domain) { // Check for special boot-strapping/vm-thread handling - if (special_exception(thread, file, line, h_name, message)) return; + if (special_exception(thread, file, line, name, message)) return; // Create and throw exception Handle h_cause(thread, NULL); - Handle h_exception = new_exception(thread, h_name, message, h_cause, h_loader, h_protection_domain); + Handle h_exception = new_exception(thread, name, message, h_cause, h_loader, h_protection_domain); _throw(thread, file, line, h_exception, message); } -// Throw an exception with a message and a cause -void Exceptions::_throw_msg_cause(Thread* thread, const char* file, int line, Symbol* h_name, const char* message, Handle h_cause, Handle h_loader, Handle h_protection_domain) { +void Exceptions::_throw_msg_cause(Thread* thread, const char* file, int line, Symbol* name, const char* message, Handle h_cause, + Handle h_loader, Handle h_protection_domain) { // Check for special boot-strapping/vm-thread handling - if (special_exception(thread, file, line, h_name, message)) return; + if (special_exception(thread, file, line, name, message)) return; // Create and throw exception and init cause - Handle h_exception = new_exception(thread, h_name, message, h_cause, h_loader, h_protection_domain); + Handle h_exception = new_exception(thread, name, message, h_cause, h_loader, h_protection_domain); _throw(thread, file, line, h_exception, message); } -// This version already has a handle for name -void Exceptions::_throw_msg(Thread* thread, const char* file, int line, - Symbol* name, const char* message) { - Handle h_loader(thread, NULL); - Handle h_protection_domain(thread, NULL); - Exceptions::_throw_msg(thread, file, line, name, message, h_loader, h_protection_domain); +void Exceptions::_throw_cause(Thread* thread, const char* file, int line, Symbol* name, Handle h_cause, + Handle h_loader, Handle h_protection_domain) { + // Check for special boot-strapping/vm-thread handling + if (special_exception(thread, file, line, h_cause)) return; + // Create and throw exception + Handle h_exception = new_exception(thread, name, h_cause, h_loader, h_protection_domain); + _throw(thread, file, line, h_exception, NULL); } -// This version already has a handle for name -void Exceptions::_throw_msg_cause(Thread* thread, const char* file, int line, - Symbol* name, const char* message, Handle cause) { - Handle h_loader(thread, NULL); - Handle h_protection_domain(thread, NULL); - Exceptions::_throw_msg_cause(thread, file, line, name, message, cause, h_loader, h_protection_domain); -} - -void Exceptions::_throw_args(Thread* thread, const char* file, int line, Symbol* h_name, Symbol* h_signature, JavaCallArguments *args) { +void Exceptions::_throw_args(Thread* thread, const char* file, int line, Symbol* name, Symbol* signature, JavaCallArguments *args) { // Check for special boot-strapping/vm-thread handling - if (special_exception(thread, file, line, h_name, NULL)) return; + if (special_exception(thread, file, line, name, NULL)) return; // Create and throw exception Handle h_loader(thread, NULL); Handle h_prot(thread, NULL); - Handle h_cause(thread, NULL); - Handle exception = new_exception(thread, h_name, h_signature, args, h_cause, h_loader, h_prot); + Handle exception = new_exception(thread, name, signature, args, h_loader, h_prot); _throw(thread, file, line, exception); } +// Methods for default parameters. +// NOTE: These must be here (and not in the header file) because of include circularities. +void Exceptions::_throw_msg_cause(Thread* thread, const char* file, int line, Symbol* name, const char* message, Handle h_cause) { + _throw_msg_cause(thread, file, line, name, message, h_cause, Handle(thread, NULL), Handle(thread, NULL)); +} +void Exceptions::_throw_msg(Thread* thread, const char* file, int line, Symbol* name, const char* message) { + _throw_msg(thread, file, line, name, message, Handle(thread, NULL), Handle(thread, NULL)); +} +void Exceptions::_throw_cause(Thread* thread, const char* file, int line, Symbol* name, Handle h_cause) { + _throw_cause(thread, file, line, name, h_cause, Handle(thread, NULL), Handle(thread, NULL)); +} + + void Exceptions::throw_stack_overflow_exception(Thread* THREAD, const char* file, int line, methodHandle method) { Handle exception; if (!THREAD->has_pending_exception()) { @@ -240,12 +246,9 @@ // Creates an exception oop, calls the method with the given signature. // and returns a Handle -// Initializes the cause if cause non-null -Handle Exceptions::new_exception(Thread *thread, Symbol* h_name, - Symbol* signature, - JavaCallArguments *args, - Handle h_cause, Handle h_loader, - Handle h_protection_domain) { +Handle Exceptions::new_exception(Thread *thread, Symbol* name, + Symbol* signature, JavaCallArguments *args, + Handle h_loader, Handle h_protection_domain) { assert(Universe::is_fully_initialized(), "cannot be called during initialization"); assert(thread->is_Java_thread(), "can only be called by a Java thread"); @@ -254,8 +257,8 @@ Handle h_exception; // Resolve exception klass - klassOop ik = SystemDictionary::resolve_or_fail(h_name, h_loader, h_protection_domain, true, thread); - instanceKlassHandle klass (thread, ik); + klassOop ik = SystemDictionary::resolve_or_fail(name, h_loader, h_protection_domain, true, thread); + instanceKlassHandle klass(thread, ik); if (!thread->has_pending_exception()) { assert(klass.not_null(), "klass must exist"); @@ -273,24 +276,8 @@ signature, args, thread); - } } - - // Future: object initializer should take a cause argument - if (h_cause() != NULL) { - assert(h_cause->is_a(SystemDictionary::Throwable_klass()), - "exception cause is not a subclass of java/lang/Throwable"); - JavaValue result1(T_OBJECT); - JavaCallArguments args1; - args1.set_receiver(h_exception); - args1.push_oop(h_cause); - JavaCalls::call_virtual(&result1, klass, - vmSymbols::initCause_name(), - vmSymbols::throwable_throwable_signature(), - &args1, - thread); - } } // Check if another exception was thrown in the process, if so rethrow that one @@ -301,12 +288,60 @@ return h_exception; } +// Creates an exception oop, calls the method with the given signature. +// and returns a Handle +// Initializes the cause if cause non-null +Handle Exceptions::new_exception(Thread *thread, Symbol* name, + Symbol* signature, JavaCallArguments *args, + Handle h_cause, + Handle h_loader, Handle h_protection_domain) { + Handle h_exception = new_exception(thread, name, signature, args, h_loader, h_protection_domain); + + // Future: object initializer should take a cause argument + if (h_cause.not_null()) { + assert(h_cause->is_a(SystemDictionary::Throwable_klass()), + "exception cause is not a subclass of java/lang/Throwable"); + JavaValue result1(T_OBJECT); + JavaCallArguments args1; + args1.set_receiver(h_exception); + args1.push_oop(h_cause); + JavaCalls::call_virtual(&result1, h_exception->klass(), + vmSymbols::initCause_name(), + vmSymbols::throwable_throwable_signature(), + &args1, + thread); + } + + // Check if another exception was thrown in the process, if so rethrow that one + if (thread->has_pending_exception()) { + h_exception = Handle(thread, thread->pending_exception()); + thread->clear_pending_exception(); + } + return h_exception; +} + +// Convenience method. Calls either the () or (Throwable) method when +// creating a new exception +Handle Exceptions::new_exception(Thread* thread, Symbol* name, + Handle h_cause, + Handle h_loader, Handle h_protection_domain, + ExceptionMsgToUtf8Mode to_utf8_safe) { + JavaCallArguments args; + Symbol* signature = NULL; + if (h_cause.is_null()) { + signature = vmSymbols::void_method_signature(); + } else { + signature = vmSymbols::throwable_void_signature(); + args.push_oop(h_cause); + } + return new_exception(thread, name, signature, &args, h_loader, h_protection_domain); +} + // Convenience method. Calls either the () or (String) method when // creating a new exception -Handle Exceptions::new_exception(Thread* thread, Symbol* h_name, +Handle Exceptions::new_exception(Thread* thread, Symbol* name, const char* message, Handle h_cause, - Handle h_loader, - Handle h_protection_domain, + Handle h_loader, Handle h_protection_domain, ExceptionMsgToUtf8Mode to_utf8_safe) { JavaCallArguments args; Symbol* signature = NULL; @@ -320,7 +355,7 @@ // the exception we are trying to build, or the pending exception. // This is sort of like what PRESERVE_EXCEPTION_MARK does, except // for the preferencing and the early returns. - Handle incoming_exception (thread, NULL); + Handle incoming_exception(thread, NULL); if (thread->has_pending_exception()) { incoming_exception = Handle(thread, thread->pending_exception()); thread->clear_pending_exception(); @@ -344,7 +379,7 @@ args.push_oop(msg); signature = vmSymbols::string_void_signature(); } - return new_exception(thread, h_name, signature, &args, h_cause, h_loader, h_protection_domain); + return new_exception(thread, name, signature, &args, h_cause, h_loader, h_protection_domain); } // Another convenience method that creates handles for null class loaders and @@ -355,8 +390,7 @@ // encoding scheme of the string into account. One thing we should do at some // point is to push this flag down to class java_lang_String since other // classes may need similar functionalities. -Handle Exceptions::new_exception(Thread* thread, - Symbol* name, +Handle Exceptions::new_exception(Thread* thread, Symbol* name, const char* message, ExceptionMsgToUtf8Mode to_utf8_safe) { diff -r b72784e722ff -r 93c71eb28866 src/share/vm/utilities/exceptions.hpp --- a/src/share/vm/utilities/exceptions.hpp Wed Aug 01 14:44:26 2012 -0700 +++ b/src/share/vm/utilities/exceptions.hpp Tue Aug 07 14:32:08 2012 -0700 @@ -112,19 +112,22 @@ // Throw exceptions: w/o message, w/ message & with formatted message. static void _throw_oop(Thread* thread, const char* file, int line, oop exception); static void _throw(Thread* thread, const char* file, int line, Handle exception, const char* msg = NULL); - static void _throw_msg(Thread* thread, const char* file, int line, - Symbol* name, const char* message, Handle loader, - Handle protection_domain); - static void _throw_msg(Thread* thread, const char* file, int line, - Symbol* name, const char* message); + + static void _throw_msg(Thread* thread, const char* file, int line, Symbol* name, const char* message); + static void _throw_msg(Thread* thread, const char* file, int line, Symbol* name, const char* message, + Handle loader, Handle protection_domain); + + static void _throw_msg_cause(Thread* thread, const char* file, int line, Symbol* name, const char* message, Handle h_cause); + static void _throw_msg_cause(Thread* thread, const char* file, int line, Symbol* name, const char* message, Handle h_cause, + Handle h_loader, Handle h_protection_domain); + + static void _throw_cause(Thread* thread, const char* file, int line, Symbol* name, Handle h_cause); + static void _throw_cause(Thread* thread, const char* file, int line, Symbol* name, Handle h_cause, + Handle h_loader, Handle h_protection_domain); + static void _throw_args(Thread* thread, const char* file, int line, Symbol* name, Symbol* signature, JavaCallArguments* args); - static void _throw_msg_cause(Thread* thread, const char* file, - int line, Symbol* h_name, const char* message, - Handle h_cause, Handle h_loader, Handle h_protection_domain); - static void _throw_msg_cause(Thread* thread, const char* file, int line, - Symbol* name, const char* message, Handle cause); // There is no THROW... macro for this method. Caller should remember // to do a return after calling it. @@ -134,17 +137,26 @@ // Create and initialize a new exception static Handle new_exception(Thread* thread, Symbol* name, Symbol* signature, JavaCallArguments* args, - Handle cause, Handle loader, - Handle protection_domain); + Handle loader, Handle protection_domain); + + static Handle new_exception(Thread* thread, Symbol* name, + Symbol* signature, JavaCallArguments* args, + Handle cause, + Handle loader, Handle protection_domain); static Handle new_exception(Thread* thread, Symbol* name, - const char* message, Handle cause, Handle loader, - Handle protection_domain, + Handle cause, + Handle loader, Handle protection_domain, ExceptionMsgToUtf8Mode to_utf8_safe = safe_to_utf8); - static Handle new_exception(Thread* thread, Symbol* name, - const char* message, - ExceptionMsgToUtf8Mode to_utf8_safe = safe_to_utf8); + static Handle new_exception(Thread* thread, Symbol* name, + const char* message, Handle cause, + Handle loader, Handle protection_domain, + ExceptionMsgToUtf8Mode to_utf8_safe = safe_to_utf8); + + static Handle new_exception(Thread* thread, Symbol* name, + const char* message, + ExceptionMsgToUtf8Mode to_utf8_safe = safe_to_utf8); static void throw_stack_overflow_exception(Thread* thread, const char* file, int line, methodHandle method); @@ -214,15 +226,15 @@ #define THROW_MSG(name, message) \ { Exceptions::_throw_msg(THREAD_AND_LOCATION, name, message); return; } +#define THROW_CAUSE(name, cause) \ + { Exceptions::_throw_cause(THREAD_AND_LOCATION, name, cause); return; } + #define THROW_MSG_LOADER(name, message, loader, protection_domain) \ { Exceptions::_throw_msg(THREAD_AND_LOCATION, name, message, loader, protection_domain); return; } #define THROW_ARG(name, signature, args) \ { Exceptions::_throw_args(THREAD_AND_LOCATION, name, signature, args); return; } -#define THROW_MSG_CAUSE(name, message, cause) \ - { Exceptions::_throw_msg_cause(THREAD_AND_LOCATION, name, message, cause); return; } - #define THROW_OOP_(e, result) \ { Exceptions::_throw_oop(THREAD_AND_LOCATION, e); return result; }