提交 acff0e3b 编写于 作者: J jrose

7047697: MethodHandle.invokeExact call for wrong method causes VM failure if run with -Xcomp

Reviewed-by: never, twisti
上级 cb60707e
...@@ -5891,6 +5891,53 @@ void MacroAssembler::call_VM(Register oop_result, ...@@ -5891,6 +5891,53 @@ void MacroAssembler::call_VM(Register oop_result,
call_VM(oop_result, last_java_sp, entry_point, 3, check_exceptions); call_VM(oop_result, last_java_sp, entry_point, 3, check_exceptions);
} }
void MacroAssembler::super_call_VM(Register oop_result,
Register last_java_sp,
address entry_point,
int number_of_arguments,
bool check_exceptions) {
Register thread = LP64_ONLY(r15_thread) NOT_LP64(noreg);
MacroAssembler::call_VM_base(oop_result, thread, last_java_sp, entry_point, number_of_arguments, check_exceptions);
}
void MacroAssembler::super_call_VM(Register oop_result,
Register last_java_sp,
address entry_point,
Register arg_1,
bool check_exceptions) {
pass_arg1(this, arg_1);
super_call_VM(oop_result, last_java_sp, entry_point, 1, check_exceptions);
}
void MacroAssembler::super_call_VM(Register oop_result,
Register last_java_sp,
address entry_point,
Register arg_1,
Register arg_2,
bool check_exceptions) {
LP64_ONLY(assert(arg_1 != c_rarg2, "smashed arg"));
pass_arg2(this, arg_2);
pass_arg1(this, arg_1);
super_call_VM(oop_result, last_java_sp, entry_point, 2, check_exceptions);
}
void MacroAssembler::super_call_VM(Register oop_result,
Register last_java_sp,
address entry_point,
Register arg_1,
Register arg_2,
Register arg_3,
bool check_exceptions) {
LP64_ONLY(assert(arg_1 != c_rarg3, "smashed arg"));
LP64_ONLY(assert(arg_2 != c_rarg3, "smashed arg"));
pass_arg3(this, arg_3);
LP64_ONLY(assert(arg_1 != c_rarg2, "smashed arg"));
pass_arg2(this, arg_2);
pass_arg1(this, arg_1);
super_call_VM(oop_result, last_java_sp, entry_point, 3, check_exceptions);
}
void MacroAssembler::call_VM_base(Register oop_result, void MacroAssembler::call_VM_base(Register oop_result,
Register java_thread, Register java_thread,
Register last_java_sp, Register last_java_sp,
......
...@@ -1660,6 +1660,14 @@ class MacroAssembler: public Assembler { ...@@ -1660,6 +1660,14 @@ class MacroAssembler: public Assembler {
Register arg_1, Register arg_2, Register arg_3, Register arg_1, Register arg_2, Register arg_3,
bool check_exceptions = true); bool check_exceptions = true);
// These always tightly bind to MacroAssembler::call_VM_base
// bypassing the virtual implementation
void super_call_VM(Register oop_result, Register last_java_sp, address entry_point, int number_of_arguments = 0, bool check_exceptions = true);
void super_call_VM(Register oop_result, Register last_java_sp, address entry_point, Register arg_1, bool check_exceptions = true);
void super_call_VM(Register oop_result, Register last_java_sp, address entry_point, Register arg_1, Register arg_2, bool check_exceptions = true);
void super_call_VM(Register oop_result, Register last_java_sp, address entry_point, Register arg_1, Register arg_2, Register arg_3, bool check_exceptions = true);
void super_call_VM(Register oop_result, Register last_java_sp, address entry_point, Register arg_1, Register arg_2, Register arg_3, Register arg_4, bool check_exceptions = true);
void call_VM_leaf(address entry_point, void call_VM_leaf(address entry_point,
int number_of_arguments = 0); int number_of_arguments = 0);
void call_VM_leaf(address entry_point, void call_VM_leaf(address entry_point,
......
...@@ -45,6 +45,7 @@ inline frame::frame(intptr_t* sp, intptr_t* fp, address pc) { ...@@ -45,6 +45,7 @@ inline frame::frame(intptr_t* sp, intptr_t* fp, address pc) {
_pc = pc; _pc = pc;
assert(pc != NULL, "no pc?"); assert(pc != NULL, "no pc?");
_cb = CodeCache::find_blob(pc); _cb = CodeCache::find_blob(pc);
adjust_unextended_sp();
address original_pc = nmethod::get_deopt_original_pc(this); address original_pc = nmethod::get_deopt_original_pc(this);
if (original_pc != NULL) { if (original_pc != NULL) {
...@@ -92,6 +93,7 @@ inline frame::frame(intptr_t* sp, intptr_t* fp) { ...@@ -92,6 +93,7 @@ inline frame::frame(intptr_t* sp, intptr_t* fp) {
// assert(_pc != NULL, "no pc?"); // assert(_pc != NULL, "no pc?");
_cb = CodeCache::find_blob(_pc); _cb = CodeCache::find_blob(_pc);
adjust_unextended_sp();
address original_pc = nmethod::get_deopt_original_pc(this); address original_pc = nmethod::get_deopt_original_pc(this);
if (original_pc != NULL) { if (original_pc != NULL) {
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "precompiled.hpp" #include "precompiled.hpp"
#include "interpreter/interpreter.hpp" #include "interpreter/interpreter.hpp"
#include "interpreter/interpreterRuntime.hpp"
#include "memory/allocation.inline.hpp" #include "memory/allocation.inline.hpp"
#include "prims/methodHandles.hpp" #include "prims/methodHandles.hpp"
...@@ -37,6 +38,11 @@ ...@@ -37,6 +38,11 @@
#define BIND(label) bind(label); BLOCK_COMMENT(#label ":") #define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
// Workaround for C++ overloading nastiness on '0' for RegisterOrConstant.
static RegisterOrConstant constant(int value) {
return RegisterOrConstant(value);
}
address MethodHandleEntry::start_compiled_entry(MacroAssembler* _masm, address MethodHandleEntry::start_compiled_entry(MacroAssembler* _masm,
address interpreted_entry) { address interpreted_entry) {
// Just before the actual machine code entry point, allocate space // Just before the actual machine code entry point, allocate space
...@@ -556,13 +562,11 @@ address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler* ...@@ -556,13 +562,11 @@ address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler*
// emit WrongMethodType path first, to enable jccb back-branch from main path // emit WrongMethodType path first, to enable jccb back-branch from main path
Label wrong_method_type; Label wrong_method_type;
__ bind(wrong_method_type); __ bind(wrong_method_type);
Label invoke_generic_slow_path; Label invoke_generic_slow_path, invoke_exact_error_path;
assert(methodOopDesc::intrinsic_id_size_in_bytes() == sizeof(u1), "");; assert(methodOopDesc::intrinsic_id_size_in_bytes() == sizeof(u1), "");;
__ cmpb(Address(rbx_method, methodOopDesc::intrinsic_id_offset_in_bytes()), (int) vmIntrinsics::_invokeExact); __ cmpb(Address(rbx_method, methodOopDesc::intrinsic_id_offset_in_bytes()), (int) vmIntrinsics::_invokeExact);
__ jcc(Assembler::notEqual, invoke_generic_slow_path); __ jcc(Assembler::notEqual, invoke_generic_slow_path);
__ push(rax_mtype); // required mtype __ jmp(invoke_exact_error_path);
__ push(rcx_recv); // bad mh (1st stacked argument)
__ jump(ExternalAddress(Interpreter::throw_WrongMethodType_entry()));
// here's where control starts out: // here's where control starts out:
__ align(CodeEntryAlignment); __ align(CodeEntryAlignment);
...@@ -596,6 +600,18 @@ address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler* ...@@ -596,6 +600,18 @@ address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler*
__ jump_to_method_handle_entry(rcx_recv, rdi_temp); __ jump_to_method_handle_entry(rcx_recv, rdi_temp);
// 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);
// for invokeGeneric (only), apply argument and result conversions on the fly // for invokeGeneric (only), apply argument and result conversions on the fly
__ bind(invoke_generic_slow_path); __ bind(invoke_generic_slow_path);
#ifdef ASSERT #ifdef ASSERT
...@@ -633,11 +649,6 @@ address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler* ...@@ -633,11 +649,6 @@ address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler*
return entry_point; return entry_point;
} }
// Workaround for C++ overloading nastiness on '0' for RegisterOrConstant.
static RegisterOrConstant constant(int value) {
return RegisterOrConstant(value);
}
// Helper to insert argument slots into the stack. // Helper to insert argument slots into the stack.
// arg_slots must be a multiple of stack_move_unit() and < 0 // arg_slots must be a multiple of stack_move_unit() and < 0
// rax_argslot is decremented to point to the new (shifted) location of the argslot // rax_argslot is decremented to point to the new (shifted) location of the argslot
......
...@@ -44,7 +44,7 @@ address PcDesc::real_pc(const nmethod* code) const { ...@@ -44,7 +44,7 @@ address PcDesc::real_pc(const nmethod* code) const {
void PcDesc::print(nmethod* code) { void PcDesc::print(nmethod* code) {
#ifndef PRODUCT #ifndef PRODUCT
ResourceMark rm; ResourceMark rm;
tty->print_cr("PcDesc(pc=0x%lx offset=%x):", real_pc(code), pc_offset()); tty->print_cr("PcDesc(pc=0x%lx offset=%x bits=%x):", real_pc(code), pc_offset(), _flags.bits);
if (scope_decode_offset() == DebugInformationRecorder::serialized_null) { if (scope_decode_offset() == DebugInformationRecorder::serialized_null) {
return; return;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册