7055355: JSR 292: crash while throwing WrongMethodTypeException
authornever
Thu, 16 Jun 2011 13:46:55 -0700
changeset 10004 190e88f7edd1
parent 9982 edcf2d7e7b84
child 10005 ce4ea81a1329
7055355: JSR 292: crash while throwing WrongMethodTypeException Reviewed-by: jrose, twisti, bdelsart
hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp
hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp
hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp
hotspot/src/cpu/x86/vm/methodHandles_x86.cpp
hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp
hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp
hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp
hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp
hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp
hotspot/src/share/vm/interpreter/interpreterRuntime.cpp
hotspot/src/share/vm/interpreter/interpreterRuntime.hpp
hotspot/src/share/vm/interpreter/templateInterpreter.cpp
hotspot/src/share/vm/interpreter/templateInterpreterGenerator.hpp
hotspot/src/share/vm/prims/methodHandles.cpp
hotspot/src/share/vm/runtime/sharedRuntime.cpp
hotspot/src/share/vm/runtime/sharedRuntime.hpp
hotspot/src/share/vm/runtime/stubRoutines.cpp
hotspot/src/share/vm/runtime/stubRoutines.hpp
--- a/hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp	Wed Jun 15 10:20:03 2011 -0700
+++ b/hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp	Thu Jun 16 13:46:55 2011 -0700
@@ -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;
 
--- a/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Wed Jun 15 10:20:03 2011 -0700
+++ b/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Thu Jun 16 13:46:55 2011 -0700
@@ -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);
   }
 
 
--- a/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp	Wed Jun 15 10:20:03 2011 -0700
+++ b/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp	Thu Jun 16 13:46:55 2011 -0700
@@ -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
--- a/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp	Wed Jun 15 10:20:03 2011 -0700
+++ b/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp	Thu Jun 16 13:46:55 2011 -0700
@@ -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;
 
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Wed Jun 15 10:20:03 2011 -0700
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Thu Jun 16 13:46:55 2011 -0700
@@ -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);
   }
 
 
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Wed Jun 15 10:20:03 2011 -0700
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Thu Jun 16 13:46:55 2011 -0700
@@ -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() {
--- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp	Wed Jun 15 10:20:03 2011 -0700
+++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp	Thu Jun 16 13:46:55 2011 -0700
@@ -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();
--- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp	Wed Jun 15 10:20:03 2011 -0700
+++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp	Thu Jun 16 13:46:55 2011 -0700
@@ -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");
--- a/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp	Wed Jun 15 10:20:03 2011 -0700
+++ b/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp	Thu Jun 16 13:46:55 2011 -0700
@@ -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");
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp	Wed Jun 15 10:20:03 2011 -0700
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp	Thu Jun 16 13:46:55 2011 -0700
@@ -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
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp	Wed Jun 15 10:20:03 2011 -0700
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp	Thu Jun 16 13:46:55 2011 -0700
@@ -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);
--- a/hotspot/src/share/vm/interpreter/templateInterpreter.cpp	Wed Jun 15 10:20:03 2011 -0700
+++ b/hotspot/src/share/vm/interpreter/templateInterpreter.cpp	Thu Jun 16 13:46:55 2011 -0700
@@ -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();
   }
--- a/hotspot/src/share/vm/interpreter/templateInterpreterGenerator.hpp	Wed Jun 15 10:20:03 2011 -0700
+++ b/hotspot/src/share/vm/interpreter/templateInterpreterGenerator.hpp	Thu Jun 16 13:46:55 2011 -0700
@@ -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);
--- a/hotspot/src/share/vm/prims/methodHandles.cpp	Wed Jun 15 10:20:03 2011 -0700
+++ b/hotspot/src/share/vm/prims/methodHandles.cpp	Thu Jun 16 13:46:55 2011 -0700
@@ -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;
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Wed Jun 15 10:20:03 2011 -0700
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Thu Jun 16 13:46:55 2011 -0700
@@ -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)
--- a/hotspot/src/share/vm/runtime/sharedRuntime.hpp	Wed Jun 15 10:20:03 2011 -0700
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.hpp	Thu Jun 16 13:46:55 2011 -0700
@@ -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);
--- a/hotspot/src/share/vm/runtime/stubRoutines.cpp	Wed Jun 15 10:20:03 2011 -0700
+++ b/hotspot/src/share/vm/runtime/stubRoutines.cpp	Thu Jun 16 13:46:55 2011 -0700
@@ -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;
--- a/hotspot/src/share/vm/runtime/stubRoutines.hpp	Wed Jun 15 10:20:03 2011 -0700
+++ b/hotspot/src/share/vm/runtime/stubRoutines.hpp	Thu Jun 16 13:46:55 2011 -0700
@@ -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.