提交 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,
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,
Register java_thread,
Register last_java_sp,
......
......@@ -1660,6 +1660,14 @@ class MacroAssembler: public Assembler {
Register arg_1, Register arg_2, Register arg_3,
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,
int number_of_arguments = 0);
void call_VM_leaf(address entry_point,
......
......@@ -45,6 +45,7 @@ inline frame::frame(intptr_t* sp, intptr_t* fp, address pc) {
_pc = pc;
assert(pc != NULL, "no pc?");
_cb = CodeCache::find_blob(pc);
adjust_unextended_sp();
address original_pc = nmethod::get_deopt_original_pc(this);
if (original_pc != NULL) {
......@@ -92,6 +93,7 @@ inline frame::frame(intptr_t* sp, intptr_t* fp) {
// assert(_pc != NULL, "no pc?");
_cb = CodeCache::find_blob(_pc);
adjust_unextended_sp();
address original_pc = nmethod::get_deopt_original_pc(this);
if (original_pc != NULL) {
......
......@@ -24,6 +24,7 @@
#include "precompiled.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/interpreterRuntime.hpp"
#include "memory/allocation.inline.hpp"
#include "prims/methodHandles.hpp"
......@@ -37,6 +38,11 @@
#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 interpreted_entry) {
// Just before the actual machine code entry point, allocate space
......@@ -556,13 +562,11 @@ address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler*
// emit WrongMethodType path first, to enable jccb back-branch from main path
Label 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), "");;
__ cmpb(Address(rbx_method, methodOopDesc::intrinsic_id_offset_in_bytes()), (int) vmIntrinsics::_invokeExact);
__ jcc(Assembler::notEqual, invoke_generic_slow_path);
__ push(rax_mtype); // required mtype
__ push(rcx_recv); // bad mh (1st stacked argument)
__ jump(ExternalAddress(Interpreter::throw_WrongMethodType_entry()));
__ jmp(invoke_exact_error_path);
// here's where control starts out:
__ align(CodeEntryAlignment);
......@@ -596,6 +600,18 @@ address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler*
__ 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
__ bind(invoke_generic_slow_path);
#ifdef ASSERT
......@@ -633,11 +649,6 @@ address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler*
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.
// 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
......
......@@ -44,7 +44,7 @@ address PcDesc::real_pc(const nmethod* code) const {
void PcDesc::print(nmethod* code) {
#ifndef PRODUCT
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) {
return;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册