mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-15 08:34:30 +02:00
7047697: MethodHandle.invokeExact call for wrong method causes VM failure if run with -Xcomp
Reviewed-by: never, twisti
This commit is contained in:
parent
18dd7131d0
commit
bb3a527f9a
5 changed files with 78 additions and 10 deletions
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue