1.1 --- a/src/cpu/x86/vm/methodHandles_x86.cpp Sat Jun 04 10:36:22 2011 -0700 1.2 +++ b/src/cpu/x86/vm/methodHandles_x86.cpp Wed Jun 08 17:04:06 2011 -0700 1.3 @@ -24,6 +24,7 @@ 1.4 1.5 #include "precompiled.hpp" 1.6 #include "interpreter/interpreter.hpp" 1.7 +#include "interpreter/interpreterRuntime.hpp" 1.8 #include "memory/allocation.inline.hpp" 1.9 #include "prims/methodHandles.hpp" 1.10 1.11 @@ -37,6 +38,11 @@ 1.12 1.13 #define BIND(label) bind(label); BLOCK_COMMENT(#label ":") 1.14 1.15 +// Workaround for C++ overloading nastiness on '0' for RegisterOrConstant. 1.16 +static RegisterOrConstant constant(int value) { 1.17 + return RegisterOrConstant(value); 1.18 +} 1.19 + 1.20 address MethodHandleEntry::start_compiled_entry(MacroAssembler* _masm, 1.21 address interpreted_entry) { 1.22 // Just before the actual machine code entry point, allocate space 1.23 @@ -556,13 +562,11 @@ 1.24 // emit WrongMethodType path first, to enable jccb back-branch from main path 1.25 Label wrong_method_type; 1.26 __ bind(wrong_method_type); 1.27 - Label invoke_generic_slow_path; 1.28 + Label invoke_generic_slow_path, invoke_exact_error_path; 1.29 assert(methodOopDesc::intrinsic_id_size_in_bytes() == sizeof(u1), "");; 1.30 __ cmpb(Address(rbx_method, methodOopDesc::intrinsic_id_offset_in_bytes()), (int) vmIntrinsics::_invokeExact); 1.31 __ jcc(Assembler::notEqual, invoke_generic_slow_path); 1.32 - __ push(rax_mtype); // required mtype 1.33 - __ push(rcx_recv); // bad mh (1st stacked argument) 1.34 - __ jump(ExternalAddress(Interpreter::throw_WrongMethodType_entry())); 1.35 + __ jmp(invoke_exact_error_path); 1.36 1.37 // here's where control starts out: 1.38 __ align(CodeEntryAlignment); 1.39 @@ -596,6 +600,18 @@ 1.40 1.41 __ jump_to_method_handle_entry(rcx_recv, rdi_temp); 1.42 1.43 + // error path for invokeExact (only) 1.44 + __ bind(invoke_exact_error_path); 1.45 + // jump(ExternalAddress(Interpreter::throw_WrongMethodType_entry())); 1.46 + Register rdx_last_Java_sp = rdx_temp; 1.47 + __ lea(rdx_last_Java_sp, __ argument_address(constant(0))); 1.48 + __ super_call_VM(noreg, 1.49 + rdx_last_Java_sp, 1.50 + CAST_FROM_FN_PTR(address, 1.51 + InterpreterRuntime::throw_WrongMethodTypeException), 1.52 + // pass required type, then failing mh object 1.53 + rax_mtype, rcx_recv); 1.54 + 1.55 // for invokeGeneric (only), apply argument and result conversions on the fly 1.56 __ bind(invoke_generic_slow_path); 1.57 #ifdef ASSERT 1.58 @@ -633,11 +649,6 @@ 1.59 return entry_point; 1.60 } 1.61 1.62 -// Workaround for C++ overloading nastiness on '0' for RegisterOrConstant. 1.63 -static RegisterOrConstant constant(int value) { 1.64 - return RegisterOrConstant(value); 1.65 -} 1.66 - 1.67 // Helper to insert argument slots into the stack. 1.68 // arg_slots must be a multiple of stack_move_unit() and < 0 1.69 // rax_argslot is decremented to point to the new (shifted) location of the argslot