comparison src/cpu/x86/vm/methodHandles_x86.cpp @ 3755:5cf771a79037

7047697: MethodHandle.invokeExact call for wrong method causes VM failure if run with -Xcomp Reviewed-by: never, twisti
author jrose
date Wed, 08 Jun 2011 17:04:06 -0700
parents cba7b5c2d53f
children a9b8b43b115f
comparison
equal deleted inserted replaced
3754:642c68c75db9 3755:5cf771a79037
22 * 22 *
23 */ 23 */
24 24
25 #include "precompiled.hpp" 25 #include "precompiled.hpp"
26 #include "interpreter/interpreter.hpp" 26 #include "interpreter/interpreter.hpp"
27 #include "interpreter/interpreterRuntime.hpp"
27 #include "memory/allocation.inline.hpp" 28 #include "memory/allocation.inline.hpp"
28 #include "prims/methodHandles.hpp" 29 #include "prims/methodHandles.hpp"
29 30
30 #define __ _masm-> 31 #define __ _masm->
31 32
34 #else 35 #else
35 #define BLOCK_COMMENT(str) __ block_comment(str) 36 #define BLOCK_COMMENT(str) __ block_comment(str)
36 #endif 37 #endif
37 38
38 #define BIND(label) bind(label); BLOCK_COMMENT(#label ":") 39 #define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
40
41 // Workaround for C++ overloading nastiness on '0' for RegisterOrConstant.
42 static RegisterOrConstant constant(int value) {
43 return RegisterOrConstant(value);
44 }
39 45
40 address MethodHandleEntry::start_compiled_entry(MacroAssembler* _masm, 46 address MethodHandleEntry::start_compiled_entry(MacroAssembler* _masm,
41 address interpreted_entry) { 47 address interpreted_entry) {
42 // Just before the actual machine code entry point, allocate space 48 // Just before the actual machine code entry point, allocate space
43 // for a MethodHandleEntry::Data record, so that we can manage everything 49 // for a MethodHandleEntry::Data record, so that we can manage everything
554 Register rdi_temp = rdi; 560 Register rdi_temp = rdi;
555 561
556 // emit WrongMethodType path first, to enable jccb back-branch from main path 562 // emit WrongMethodType path first, to enable jccb back-branch from main path
557 Label wrong_method_type; 563 Label wrong_method_type;
558 __ bind(wrong_method_type); 564 __ bind(wrong_method_type);
559 Label invoke_generic_slow_path; 565 Label invoke_generic_slow_path, invoke_exact_error_path;
560 assert(methodOopDesc::intrinsic_id_size_in_bytes() == sizeof(u1), "");; 566 assert(methodOopDesc::intrinsic_id_size_in_bytes() == sizeof(u1), "");;
561 __ cmpb(Address(rbx_method, methodOopDesc::intrinsic_id_offset_in_bytes()), (int) vmIntrinsics::_invokeExact); 567 __ cmpb(Address(rbx_method, methodOopDesc::intrinsic_id_offset_in_bytes()), (int) vmIntrinsics::_invokeExact);
562 __ jcc(Assembler::notEqual, invoke_generic_slow_path); 568 __ jcc(Assembler::notEqual, invoke_generic_slow_path);
563 __ push(rax_mtype); // required mtype 569 __ jmp(invoke_exact_error_path);
564 __ push(rcx_recv); // bad mh (1st stacked argument)
565 __ jump(ExternalAddress(Interpreter::throw_WrongMethodType_entry()));
566 570
567 // here's where control starts out: 571 // here's where control starts out:
568 __ align(CodeEntryAlignment); 572 __ align(CodeEntryAlignment);
569 address entry_point = __ pc(); 573 address entry_point = __ pc();
570 574
593 597
594 // Nobody uses the MH receiver slot after this. Make sure. 598 // Nobody uses the MH receiver slot after this. Make sure.
595 DEBUG_ONLY(__ movptr(mh_receiver_slot_addr, (int32_t)0x999999)); 599 DEBUG_ONLY(__ movptr(mh_receiver_slot_addr, (int32_t)0x999999));
596 600
597 __ jump_to_method_handle_entry(rcx_recv, rdi_temp); 601 __ jump_to_method_handle_entry(rcx_recv, rdi_temp);
602
603 // error path for invokeExact (only)
604 __ bind(invoke_exact_error_path);
605 // jump(ExternalAddress(Interpreter::throw_WrongMethodType_entry()));
606 Register rdx_last_Java_sp = rdx_temp;
607 __ lea(rdx_last_Java_sp, __ argument_address(constant(0)));
608 __ super_call_VM(noreg,
609 rdx_last_Java_sp,
610 CAST_FROM_FN_PTR(address,
611 InterpreterRuntime::throw_WrongMethodTypeException),
612 // pass required type, then failing mh object
613 rax_mtype, rcx_recv);
598 614
599 // for invokeGeneric (only), apply argument and result conversions on the fly 615 // for invokeGeneric (only), apply argument and result conversions on the fly
600 __ bind(invoke_generic_slow_path); 616 __ bind(invoke_generic_slow_path);
601 #ifdef ASSERT 617 #ifdef ASSERT
602 if (VerifyMethodHandles) { 618 if (VerifyMethodHandles) {
629 __ mov(rcx, rdx_adapter); 645 __ mov(rcx, rdx_adapter);
630 trace_method_handle(_masm, "invokeGeneric"); 646 trace_method_handle(_masm, "invokeGeneric");
631 __ jump_to_method_handle_entry(rcx, rdi_temp); 647 __ jump_to_method_handle_entry(rcx, rdi_temp);
632 648
633 return entry_point; 649 return entry_point;
634 }
635
636 // Workaround for C++ overloading nastiness on '0' for RegisterOrConstant.
637 static RegisterOrConstant constant(int value) {
638 return RegisterOrConstant(value);
639 } 650 }
640 651
641 // Helper to insert argument slots into the stack. 652 // Helper to insert argument slots into the stack.
642 // arg_slots must be a multiple of stack_move_unit() and < 0 653 // arg_slots must be a multiple of stack_move_unit() and < 0
643 // rax_argslot is decremented to point to the new (shifted) location of the argslot 654 // rax_argslot is decremented to point to the new (shifted) location of the argslot