Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 50 additions & 5 deletions src/hotspot/cpu/riscv/methodHandles_riscv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,14 +93,60 @@ void MethodHandles::verify_klass(MacroAssembler* _masm,

void MethodHandles::verify_ref_kind(MacroAssembler* _masm, int ref_kind, Register member_reg, Register temp) {}

void MethodHandles::verify_method(MacroAssembler* _masm, Register method, vmIntrinsics::ID iid) {
BLOCK_COMMENT("verify_method {");
__ verify_method_ptr(method);
if (VerifyMethodHandles) {
Label L_ok;
assert_different_registers(method, t0, t1);
const Register method_holder = t1;
__ load_method_holder(method_holder, method);

switch (iid) {
case vmIntrinsicID::_invokeBasic:
// Require compiled LambdaForm class to be fully initialized.
__ lbu(t0, Address(method_holder, InstanceKlass::init_state_offset()));
__ membar(MacroAssembler::LoadLoad | MacroAssembler::LoadStore);
__ mv(t1, InstanceKlass::fully_initialized);
__ beq(t0, t1, L_ok);
break;
case vmIntrinsicID::_linkToStatic:
__ clinit_barrier(method_holder, t0, &L_ok);
break;

case vmIntrinsicID::_linkToVirtual:
case vmIntrinsicID::_linkToSpecial:
case vmIntrinsicID::_linkToInterface:
// Class initialization check is too strong here. Just ensure that class initialization has been initiated.
__ lbu(t0, Address(method_holder, InstanceKlass::init_state_offset()));
__ membar(MacroAssembler::LoadLoad | MacroAssembler::LoadStore);
__ mv(t1, InstanceKlass::being_initialized);
__ bge(t0, t1, L_ok);

// init_state check failed, but it may be an abstract interface method
__ lhu(t0, Address(method, Method::access_flags_offset()));
__ test_bit(t1, t0, exact_log2(JVM_ACC_ABSTRACT));
__ bnez(t1, L_ok);
break;

default:
fatal("unexpected intrinsic %d: %s", vmIntrinsics::as_int(iid), vmIntrinsics::name_at(iid));
}

// Method holder init state check failed for a concrete method.
__ stop("Method holder klass is not initialized");
__ BIND(L_ok);
}
BLOCK_COMMENT("} verify_method");
}
#endif //ASSERT

void MethodHandles::jump_from_method_handle(MacroAssembler* _masm, Register method, Register temp,
bool for_compiler_entry) {
bool for_compiler_entry, vmIntrinsics::ID iid) {
assert(method == xmethod, "interpreter calling convention");
Label L_no_such_method;
__ beqz(xmethod, L_no_such_method);
__ verify_method_ptr(method);
verify_method(_masm, method, iid);

if (!for_compiler_entry && JvmtiExport::can_post_interpreter_events()) {
Label run_compiled_code;
Expand Down Expand Up @@ -158,7 +204,7 @@ void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm,
__ BIND(L);
}

jump_from_method_handle(_masm, method_temp, temp2, for_compiler_entry);
jump_from_method_handle(_masm, method_temp, temp2, for_compiler_entry, vmIntrinsics::_invokeBasic);
BLOCK_COMMENT("} jump_to_lambda_form");
}

Expand Down Expand Up @@ -437,8 +483,7 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
// After figuring out which concrete method to call, jump into it.
// Note that this works in the interpreter with no data motion.
// But the compiled version will require that r2_recv be shifted out.
__ verify_method_ptr(xmethod);
jump_from_method_handle(_masm, xmethod, temp1, for_compiler_entry);
jump_from_method_handle(_masm, xmethod, temp1, for_compiler_entry, iid);
if (iid == vmIntrinsics::_linkToInterface) {
__ bind(L_incompatible_class_change_error);
__ far_jump(RuntimeAddress(SharedRuntime::throw_IncompatibleClassChangeError_entry()));
Expand Down
4 changes: 3 additions & 1 deletion src/hotspot/cpu/riscv/methodHandles_riscv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ enum /* platform_dependent_constants */ {
Register obj, vmClassID klass_id,
const char* error_message = "wrong klass") NOT_DEBUG_RETURN;

static void verify_method(MacroAssembler* _masm, Register method, vmIntrinsics::ID iid) NOT_DEBUG_RETURN;

static void verify_method_handle(MacroAssembler* _masm, Register mh_reg) {
verify_klass(_masm, mh_reg, VM_CLASS_ID(java_lang_invoke_MethodHandle),
"reference is a MH");
Expand All @@ -49,7 +51,7 @@ enum /* platform_dependent_constants */ {
// Similar to InterpreterMacroAssembler::jump_from_interpreted.
// Takes care of special dispatch from single stepping too.
static void jump_from_method_handle(MacroAssembler* _masm, Register method, Register temp,
bool for_compiler_entry);
bool for_compiler_entry, vmIntrinsics::ID iid);

static void jump_to_lambda_form(MacroAssembler* _masm,
Register recv, Register method_temp,
Expand Down