diff -r a6fe94b9759f -r 2cb2f30450c7 src/cpu/x86/vm/methodHandles_x86.cpp --- a/src/cpu/x86/vm/methodHandles_x86.cpp Fri Sep 14 22:00:41 2012 -0700 +++ b/src/cpu/x86/vm/methodHandles_x86.cpp Mon Sep 17 12:57:58 2012 -0700 @@ -327,10 +327,11 @@ assert_different_registers(temp3, rcx, rdx); } #endif + else { + assert_different_registers(temp1, temp2, temp3, saved_last_sp_register()); // don't trash lastSP + } assert_different_registers(temp1, temp2, temp3, receiver_reg); assert_different_registers(temp1, temp2, temp3, member_reg); - if (!for_compiler_entry) - assert_different_registers(temp1, temp2, temp3, saved_last_sp_register()); // don't trash lastSP if (iid == vmIntrinsics::_invokeBasic) { // indirect through MH.form.vmentry.vmtarget @@ -392,14 +393,13 @@ // rsi/r13 - interpreter linkage (if interpreted) // rcx, rdx, rsi, rdi, r8, r8 - compiler arguments (if compiled) - bool method_is_live = false; + Label L_incompatible_class_change_error; switch (iid) { case vmIntrinsics::_linkToSpecial: if (VerifyMethodHandles) { verify_ref_kind(_masm, JVM_REF_invokeSpecial, member_reg, temp3); } __ movptr(rbx_method, member_vmtarget); - method_is_live = true; break; case vmIntrinsics::_linkToStatic: @@ -407,7 +407,6 @@ verify_ref_kind(_masm, JVM_REF_invokeStatic, member_reg, temp3); } __ movptr(rbx_method, member_vmtarget); - method_is_live = true; break; case vmIntrinsics::_linkToVirtual: @@ -436,7 +435,6 @@ // get target Method* & entry point __ lookup_virtual_method(temp1_recv_klass, temp2_index, rbx_method); - method_is_live = true; break; } @@ -464,35 +462,32 @@ } // given intf, index, and recv klass, dispatch to the implementation method - Label L_no_such_interface; __ lookup_interface_method(temp1_recv_klass, temp3_intf, // note: next two args must be the same: rbx_index, rbx_method, temp2, - L_no_such_interface); - - __ verify_method_ptr(rbx_method); - jump_from_method_handle(_masm, rbx_method, temp2, for_compiler_entry); - __ hlt(); - - __ bind(L_no_such_interface); - __ jump(RuntimeAddress(StubRoutines::throw_IncompatibleClassChangeError_entry())); + L_incompatible_class_change_error); break; } default: - fatal(err_msg("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid))); + fatal(err_msg_res("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid))); break; } - if (method_is_live) { - // live at this point: rbx_method, rsi/r13 (if interpreted) + // Live at this point: + // rbx_method + // rsi/r13 (if interpreted) - // After figuring out which concrete method to call, jump into it. - // Note that this works in the interpreter with no data motion. - // But the compiled version will require that rcx_recv be shifted out. - __ verify_method_ptr(rbx_method); - jump_from_method_handle(_masm, rbx_method, temp1, for_compiler_entry); + // After figuring out which concrete method to call, jump into it. + // Note that this works in the interpreter with no data motion. + // But the compiled version will require that rcx_recv be shifted out. + __ verify_method_ptr(rbx_method); + jump_from_method_handle(_masm, rbx_method, temp1, for_compiler_entry); + + if (iid == vmIntrinsics::_linkToInterface) { + __ bind(L_incompatible_class_change_error); + __ jump(RuntimeAddress(StubRoutines::throw_IncompatibleClassChangeError_entry())); } } }