Mercurial > hg > truffle
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 |