--- old/src/share/vm/runtime/sharedRuntime.hpp Thu Jun 16 10:41:29 2011 +++ new/src/share/vm/runtime/sharedRuntime.hpp Thu Jun 16 10:41:29 2011 @@ -185,6 +185,7 @@ static void throw_NullPointerException(JavaThread* thread); static void throw_NullPointerException_at_call(JavaThread* thread); static void throw_StackOverflowError(JavaThread* thread); + static void throw_WrongMethodTypeException(JavaThread* thread, oopDesc* required, oopDesc* actual); static address continuation_for_implicit_exception(JavaThread* thread, address faulting_pc, ImplicitExceptionKind exception_kind); --- old/src/share/vm/runtime/sharedRuntime.cpp Thu Jun 16 10:41:30 2011 +++ new/src/share/vm/runtime/sharedRuntime.cpp Thu Jun 16 10:41:30 2011 @@ -763,6 +763,13 @@ throw_and_post_jvmti_exception(thread, exception); JRT_END +JRT_ENTRY(void, SharedRuntime::throw_WrongMethodTypeException(JavaThread* thread, oopDesc* required, oopDesc* actual)) + assert(thread == JavaThread::current() && required->is_oop() && actual->is_oop(), "bad args"); + ResourceMark rm; + char* message = SharedRuntime::generate_wrong_method_type_message(thread, required, actual); + throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_invoke_WrongMethodTypeException(), message); +JRT_END + address SharedRuntime::continuation_for_implicit_exception(JavaThread* thread, address pc, SharedRuntime::ImplicitExceptionKind exception_kind) --- old/src/share/vm/runtime/stubRoutines.hpp Thu Jun 16 10:41:31 2011 +++ new/src/share/vm/runtime/stubRoutines.hpp Thu Jun 16 10:41:31 2011 @@ -132,6 +132,7 @@ static address _throw_NullPointerException_entry; static address _throw_NullPointerException_at_call_entry; static address _throw_StackOverflowError_entry; + static address _throw_WrongMethodTypeException_entry; static address _handler_for_unsafe_access_entry; static address _atomic_xchg_entry; @@ -254,6 +255,7 @@ static address throw_NullPointerException_entry() { return _throw_NullPointerException_entry; } static address throw_NullPointerException_at_call_entry(){ return _throw_NullPointerException_at_call_entry; } static address throw_StackOverflowError_entry() { return _throw_StackOverflowError_entry; } + static address throw_WrongMethodTypeException_entry() { return _throw_WrongMethodTypeException_entry; } // Exceptions during unsafe access - should throw Java exception rather // than crash. --- old/src/share/vm/runtime/stubRoutines.cpp Thu Jun 16 10:41:32 2011 +++ new/src/share/vm/runtime/stubRoutines.cpp Thu Jun 16 10:41:32 2011 @@ -55,6 +55,7 @@ address StubRoutines::_throw_NullPointerException_entry = NULL; address StubRoutines::_throw_NullPointerException_at_call_entry = NULL; address StubRoutines::_throw_StackOverflowError_entry = NULL; +address StubRoutines::_throw_WrongMethodTypeException_entry = NULL; address StubRoutines::_handler_for_unsafe_access_entry = NULL; jint StubRoutines::_verify_oop_count = 0; address StubRoutines::_verify_oop_subroutine_entry = NULL; --- old/src/share/vm/interpreter/interpreterRuntime.hpp Thu Jun 16 10:41:33 2011 +++ new/src/share/vm/interpreter/interpreterRuntime.hpp Thu Jun 16 10:41:33 2011 @@ -98,7 +98,6 @@ static void throw_StackOverflowError(JavaThread* thread); static void throw_ArrayIndexOutOfBoundsException(JavaThread* thread, char* name, jint index); static void throw_ClassCastException(JavaThread* thread, oopDesc* obj); - static void throw_WrongMethodTypeException(JavaThread* thread, oopDesc* mtype = NULL, oopDesc* mhandle = NULL); static void create_exception(JavaThread* thread, char* name, char* message); static void create_klass_exception(JavaThread* thread, char* name, oopDesc* obj); static address exception_handler_for_exception(JavaThread* thread, oopDesc* exception); --- old/src/share/vm/interpreter/interpreterRuntime.cpp Thu Jun 16 10:41:34 2011 +++ new/src/share/vm/interpreter/interpreterRuntime.cpp Thu Jun 16 10:41:33 2011 @@ -362,25 +362,6 @@ THROW_MSG(vmSymbols::java_lang_ClassCastException(), message); IRT_END -// required can be either a MethodType, or a Class (for a single argument) -// actual (if not null) can be either a MethodHandle, or an arbitrary value (for a single argument) -IRT_ENTRY(void, InterpreterRuntime::throw_WrongMethodTypeException(JavaThread* thread, - oopDesc* required, - oopDesc* actual)) { - ResourceMark rm(thread); - char* message = SharedRuntime::generate_wrong_method_type_message(thread, required, actual); - - if (ProfileTraps) { - note_trap(thread, Deoptimization::Reason_constraint, CHECK); - } - - // create exception - THROW_MSG(vmSymbols::java_lang_invoke_WrongMethodTypeException(), message); -} -IRT_END - - - // exception_handler_for_exception(...) returns the continuation address, // the exception oop (via TLS) and sets the bci/bcp for the continuation. // The exception oop is returned to make sure it is preserved over GC (it --- old/src/share/vm/interpreter/templateInterpreter.cpp Thu Jun 16 10:41:34 2011 +++ new/src/share/vm/interpreter/templateInterpreter.cpp Thu Jun 16 10:41:34 2011 @@ -171,7 +171,6 @@ address TemplateInterpreter::_throw_ArrayStoreException_entry = NULL; address TemplateInterpreter::_throw_ArithmeticException_entry = NULL; address TemplateInterpreter::_throw_ClassCastException_entry = NULL; -address TemplateInterpreter::_throw_WrongMethodType_entry = NULL; address TemplateInterpreter::_throw_NullPointerException_entry = NULL; address TemplateInterpreter::_throw_StackOverflowError_entry = NULL; address TemplateInterpreter::_throw_exception_entry = NULL; @@ -346,7 +345,6 @@ Interpreter::_throw_ArrayStoreException_entry = generate_klass_exception_handler("java/lang/ArrayStoreException" ); Interpreter::_throw_ArithmeticException_entry = generate_exception_handler("java/lang/ArithmeticException" , "/ by zero"); Interpreter::_throw_ClassCastException_entry = generate_ClassCastException_handler(); - Interpreter::_throw_WrongMethodType_entry = generate_WrongMethodType_handler(); Interpreter::_throw_NullPointerException_entry = generate_exception_handler("java/lang/NullPointerException" , NULL ); Interpreter::_throw_StackOverflowError_entry = generate_StackOverflowError_handler(); } --- old/src/share/vm/interpreter/templateInterpreterGenerator.hpp Thu Jun 16 10:41:35 2011 +++ new/src/share/vm/interpreter/templateInterpreterGenerator.hpp Thu Jun 16 10:41:35 2011 @@ -51,7 +51,6 @@ } address generate_exception_handler_common(const char* name, const char* message, bool pass_oop); address generate_ClassCastException_handler(); - address generate_WrongMethodType_handler(); address generate_ArrayIndexOutOfBounds_handler(const char* name); address generate_continuation_for(TosState state); address generate_return_entry_for(TosState state, int step); --- old/src/share/vm/prims/methodHandles.cpp Thu Jun 16 10:41:36 2011 +++ new/src/share/vm/prims/methodHandles.cpp Thu Jun 16 10:41:36 2011 @@ -629,6 +629,8 @@ // convert the external string name to an internal symbol TempNewSymbol name = java_lang_String::as_symbol_or_null(name_str()); if (name == NULL) return; // no such name + if (name == vmSymbols::class_initializer_name()) + return; // illegal name Handle polymorphic_method_type; bool polymorphic_signature = false; --- old/src/cpu/sparc/vm/methodHandles_sparc.cpp Thu Jun 16 10:41:37 2011 +++ new/src/cpu/sparc/vm/methodHandles_sparc.cpp Thu Jun 16 10:41:37 2011 @@ -307,11 +307,12 @@ __ stop("damaged ricochet frame: L4 < FP"); __ BIND(L_ok_2); - __ sub(L4_saved_args_base, UNREASONABLE_STACK_MOVE * Interpreter::stackElementSize, O7_temp); - __ cmp(O7_temp, FP_temp); - __ br(Assembler::lessEqualUnsigned, false, Assembler::pt, L_ok_3); - __ delayed()->nop(); - __ stop("damaged ricochet frame: (L4 - UNREASONABLE_STACK_MOVE) > FP"); + // Disable until we decide on it's fate + // __ sub(L4_saved_args_base, UNREASONABLE_STACK_MOVE * Interpreter::stackElementSize, O7_temp); + // __ cmp(O7_temp, FP_temp); + // __ br(Assembler::lessEqualUnsigned, false, Assembler::pt, L_ok_3); + // __ delayed()->nop(); + // __ stop("damaged ricochet frame: (L4 - UNREASONABLE_STACK_MOVE) > FP"); __ BIND(L_ok_3); extract_conversion_dest_type(_masm, L5_conversion, O7_temp); @@ -547,8 +548,9 @@ __ brx(Assembler::notEqual, false, Assembler::pt, invoke_generic_slow_path); __ delayed()->nop(); __ mov(O0_mtype, G5_method_type); // required by throw_WrongMethodType - // mov(G3_method_handle, G3_method_handle); // already in this register - __ jump_to(AddressLiteral(Interpreter::throw_WrongMethodType_entry()), O1_scratch); + __ mov(G3_method_handle, G3_method_handle); // already in this register + // O0 will be filled in with JavaThread in stub + __ jump_to(AddressLiteral(StubRoutines::throw_WrongMethodTypeException_entry()), O3_scratch); __ delayed()->nop(); // here's where control starts out: @@ -1145,23 +1147,13 @@ // FIXME: fill in _raise_exception_method with a suitable java.lang.invoke method __ set(AddressLiteral((address) &_raise_exception_method), G5_method); __ ld_ptr(Address(G5_method, 0), G5_method); - __ tst(G5_method); - __ brx(Assembler::zero, false, Assembler::pn, L_no_method); - __ delayed()->nop(); const int jobject_oop_offset = 0; __ ld_ptr(Address(G5_method, jobject_oop_offset), G5_method); - __ tst(G5_method); - __ brx(Assembler::zero, false, Assembler::pn, L_no_method); - __ delayed()->nop(); __ verify_oop(G5_method); __ jump_indirect_to(G5_method_fce, O3_scratch); // jump to compiled entry __ delayed()->nop(); - - // Do something that is at least causes a valid throw from the interpreter. - __ bind(L_no_method); - __ unimplemented("call throw_WrongMethodType_entry"); } break; --- old/src/cpu/sparc/vm/stubGenerator_sparc.cpp Thu Jun 16 10:41:38 2011 +++ new/src/cpu/sparc/vm/stubGenerator_sparc.cpp Thu Jun 16 10:41:37 2011 @@ -440,7 +440,8 @@ #undef __ #define __ masm-> - address generate_throw_exception(const char* name, address runtime_entry, bool restore_saved_exception_pc) { + address generate_throw_exception(const char* name, address runtime_entry, bool restore_saved_exception_pc, + Register arg1 = noreg, Register arg2 = noreg) { #ifdef ASSERT int insts_size = VerifyThread ? 1 * K : 600; #else @@ -476,6 +477,13 @@ __ set_last_Java_frame(last_java_sp, G0); if (VerifyThread) __ mov(G2_thread, O0); // about to be smashed; pass early __ save_thread(noreg); + if (arg1 != noreg) { + assert(arg2 != O1, "clobbered"); + __ mov(arg1, O1); + } + if (arg2 != noreg) { + __ mov(arg2, O2); + } // do the call BLOCK_COMMENT("call runtime_entry"); __ call(runtime_entry, relocInfo::runtime_call_type); @@ -3240,6 +3248,14 @@ StubRoutines::_atomic_cmpxchg_long_entry = generate_atomic_cmpxchg_long(); StubRoutines::_atomic_add_ptr_entry = StubRoutines::_atomic_add_entry; #endif // COMPILER2 !=> _LP64 + + // Build this early so it's available for the interpreter. The + // stub expects the required and actual type to already be in O1 + // and O2 respectively. + StubRoutines::_throw_WrongMethodTypeException_entry = + generate_throw_exception("WrongMethodTypeException throw_exception", + CAST_FROM_FN_PTR(address, SharedRuntime::throw_WrongMethodTypeException), + false, G5_method_type, G3_method_handle); } --- old/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Thu Jun 16 10:41:38 2011 +++ new/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Thu Jun 16 10:41:38 2011 @@ -128,24 +128,6 @@ } -// Arguments are: required type in G5_method_type, and -// failing object (or NULL) in G3_method_handle. -address TemplateInterpreterGenerator::generate_WrongMethodType_handler() { - address entry = __ pc(); - // expression stack must be empty before entering the VM if an exception - // happened - __ empty_expression_stack(); - // load exception object - __ call_VM(Oexception, - CAST_FROM_FN_PTR(address, - InterpreterRuntime::throw_WrongMethodTypeException), - G5_method_type, // required - G3_method_handle); // actual - __ should_not_reach_here(); - return entry; -} - - address TemplateInterpreterGenerator::generate_ArrayIndexOutOfBounds_handler(const char* name) { address entry = __ pc(); // expression stack must be empty before entering the VM if an exception happened --- old/src/cpu/x86/vm/methodHandles_x86.cpp Thu Jun 16 10:41:39 2011 +++ new/src/cpu/x86/vm/methodHandles_x86.cpp Thu Jun 16 10:41:39 2011 @@ -602,15 +602,8 @@ // error path for invokeExact (only) __ bind(invoke_exact_error_path); - // jump(ExternalAddress(Interpreter::throw_WrongMethodType_entry())); - Register rdx_last_Java_sp = rdx_temp; - __ lea(rdx_last_Java_sp, __ argument_address(constant(0))); - __ super_call_VM(noreg, - rdx_last_Java_sp, - CAST_FROM_FN_PTR(address, - InterpreterRuntime::throw_WrongMethodTypeException), - // pass required type, then failing mh object - rax_mtype, rcx_recv); + // Stub wants expected type in rax and the actual type in rcx + __ jump(ExternalAddress(StubRoutines::throw_WrongMethodTypeException_entry())); // for invokeGeneric (only), apply argument and result conversions on the fly __ bind(invoke_generic_slow_path); @@ -1175,27 +1168,15 @@ __ mov(rsp, saved_last_sp); // cut the stack back to where the caller started Register rbx_method = rbx_temp; - Label L_no_method; - // FIXME: fill in _raise_exception_method with a suitable java.lang.invoke method __ movptr(rbx_method, ExternalAddress((address) &_raise_exception_method)); - __ testptr(rbx_method, rbx_method); - __ jccb(Assembler::zero, L_no_method); const int jobject_oop_offset = 0; __ movptr(rbx_method, Address(rbx_method, jobject_oop_offset)); // dereference the jobject - __ testptr(rbx_method, rbx_method); - __ jccb(Assembler::zero, L_no_method); __ verify_oop(rbx_method); NOT_LP64(__ push(rarg2_required)); __ push(rdi_pc); // restore caller PC __ jmp(rbx_method_fce); // jump to compiled entry - - // Do something that is at least causes a valid throw from the interpreter. - __ bind(L_no_method); - __ push(rarg2_required); - __ push(rarg1_actual); - __ jump(ExternalAddress(Interpreter::throw_WrongMethodType_entry())); } break; --- old/src/cpu/x86/vm/stubGenerator_x86_32.cpp Thu Jun 16 10:41:40 2011 +++ new/src/cpu/x86/vm/stubGenerator_x86_32.cpp Thu Jun 16 10:41:40 2011 @@ -2151,6 +2151,8 @@ // if they expect all registers to be preserved. enum layout { thread_off, // last_java_sp + arg1_off, + arg2_off, rbp_off, // callee saved register ret_pc, framesize @@ -2185,7 +2187,7 @@ // either at call sites or otherwise assume that stack unwinding will be initiated, // so caller saved registers were assumed volatile in the compiler. address generate_throw_exception(const char* name, address runtime_entry, - bool restore_saved_exception_pc) { + bool restore_saved_exception_pc, Register arg1 = noreg, Register arg2 = noreg) { int insts_size = 256; int locs_size = 32; @@ -2218,6 +2220,13 @@ // push java thread (becomes first argument of C function) __ movptr(Address(rsp, thread_off * wordSize), java_thread); + if (arg1 != noreg) { + __ movptr(Address(rsp, arg1_off * wordSize), arg1); + } + if (arg2 != noreg) { + assert(arg1 != noreg, "missing reg arg"); + __ movptr(Address(rsp, arg2_off * wordSize), arg2); + } // Set up last_Java_sp and last_Java_fp __ set_last_Java_frame(java_thread, rsp, rbp, NULL); @@ -2309,6 +2318,12 @@ CAST_FROM_FN_PTR(address, SharedRuntime::d2i)); StubRoutines::_d2l_wrapper = generate_d2i_wrapper(T_LONG, CAST_FROM_FN_PTR(address, SharedRuntime::d2l)); + + // Build this early so it's available for the interpreter + StubRoutines::_throw_WrongMethodTypeException_entry = + generate_throw_exception("WrongMethodTypeException throw_exception", + CAST_FROM_FN_PTR(address, SharedRuntime::throw_WrongMethodTypeException), + false, rax, rcx); } --- old/src/cpu/x86/vm/stubGenerator_x86_64.cpp Thu Jun 16 10:41:41 2011 +++ new/src/cpu/x86/vm/stubGenerator_x86_64.cpp Thu Jun 16 10:41:41 2011 @@ -2934,7 +2934,9 @@ // caller saved registers were assumed volatile in the compiler. address generate_throw_exception(const char* name, address runtime_entry, - bool restore_saved_exception_pc) { + bool restore_saved_exception_pc, + Register arg1 = noreg, + Register arg2 = noreg) { // Information about frame layout at time of blocking runtime call. // Note that we only have to preserve callee-saved registers since // the compilers are responsible for supplying a continuation point @@ -2980,6 +2982,13 @@ __ set_last_Java_frame(rsp, rbp, NULL); // Call runtime + if (arg1 != noreg) { + assert(arg2 != c_rarg1, "clobbered"); + __ movptr(c_rarg1, arg1); + } + if (arg2 != noreg) { + __ movptr(c_rarg2, arg2); + } __ movptr(c_rarg0, r15_thread); BLOCK_COMMENT("call runtime_entry"); __ call(RuntimeAddress(runtime_entry)); @@ -3052,6 +3061,14 @@ StubRoutines::x86::_get_previous_fp_entry = generate_get_previous_fp(); StubRoutines::x86::_verify_mxcsr_entry = generate_verify_mxcsr(); + + // Build this early so it's available for the interpreter. Stub + // expects the required and actual types as register arguments in + // j_rarg0 and j_rarg1 respectively. + StubRoutines::_throw_WrongMethodTypeException_entry = + generate_throw_exception("WrongMethodTypeException throw_exception", + CAST_FROM_FN_PTR(address, SharedRuntime::throw_WrongMethodTypeException), + false, rax, rcx); } void generate_all() { --- old/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Thu Jun 16 10:41:42 2011 +++ new/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Thu Jun 16 10:41:42 2011 @@ -112,32 +112,6 @@ return entry; } -// Arguments are: required type at TOS+4, failing object (or NULL) at TOS. -address TemplateInterpreterGenerator::generate_WrongMethodType_handler() { - address entry = __ pc(); - - __ pop(rbx); // actual failing object is at TOS - __ pop(rax); // required type is at TOS+4 - - __ verify_oop(rbx); - __ verify_oop(rax); - - // Various method handle types use interpreter registers as temps. - __ restore_bcp(); - __ restore_locals(); - - // Expression stack must be empty before entering the VM for an exception. - __ empty_expression_stack(); - __ empty_FPU_stack(); - __ call_VM(noreg, - CAST_FROM_FN_PTR(address, - InterpreterRuntime::throw_WrongMethodTypeException), - // pass required type, failing object (or NULL) - rax, rbx); - return entry; -} - - address TemplateInterpreterGenerator::generate_exception_handler_common(const char* name, const char* message, bool pass_oop) { assert(!pass_oop || message == NULL, "either oop or message but not both"); address entry = __ pc(); --- old/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Thu Jun 16 10:41:43 2011 +++ new/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Thu Jun 16 10:41:42 2011 @@ -120,31 +120,6 @@ return entry; } -// Arguments are: required type at TOS+8, failing object (or NULL) at TOS+4. -address TemplateInterpreterGenerator::generate_WrongMethodType_handler() { - address entry = __ pc(); - - __ pop(c_rarg2); // failing object is at TOS - __ pop(c_rarg1); // required type is at TOS+8 - - __ verify_oop(c_rarg1); - __ verify_oop(c_rarg2); - - // Various method handle types use interpreter registers as temps. - __ restore_bcp(); - __ restore_locals(); - - // Expression stack must be empty before entering the VM for an exception. - __ empty_expression_stack(); - - __ call_VM(noreg, - CAST_FROM_FN_PTR(address, - InterpreterRuntime::throw_WrongMethodTypeException), - // pass required type, failing object (or NULL) - c_rarg1, c_rarg2); - return entry; -} - address TemplateInterpreterGenerator::generate_exception_handler_common( const char* name, const char* message, bool pass_oop) { assert(!pass_oop || message == NULL, "either oop or message but not both"); --- old/src/cpu/zero/vm/cppInterpreter_zero.cpp Thu Jun 16 10:41:43 2011 +++ new/src/cpu/zero/vm/cppInterpreter_zero.cpp Thu Jun 16 10:41:43 2011 @@ -657,7 +657,7 @@ if (!is_exact) { if (method->intrinsic_id() == vmIntrinsics::_invokeExact) { CALL_VM_NOCHECK_NOFIX( - InterpreterRuntime::throw_WrongMethodTypeException( + SharedRuntime::throw_WrongMethodTypeException( thread, method_type, mhtype)); // NB all oops trashed! assert(HAS_PENDING_EXCEPTION, "should do"); @@ -673,7 +673,7 @@ oop adapter = java_lang_invoke_MethodTypeForm::genericInvoker(form); if (adapter == NULL) { CALL_VM_NOCHECK_NOFIX( - InterpreterRuntime::throw_WrongMethodTypeException( + SharedRuntime::throw_WrongMethodTypeException( thread, method_type, mhtype)); // NB all oops trashed! assert(HAS_PENDING_EXCEPTION, "should do");