8302070: Factor null-check into load_klass() calls

Reviewed-by: phh, coleenp
This commit is contained in:
Roman Kennke 2023-02-20 15:13:36 +00:00
parent e731695217
commit 7cf7e0a20b
28 changed files with 64 additions and 48 deletions

View File

@ -4261,6 +4261,11 @@ void MacroAssembler::load_klass(Register dst, Register src) {
}
}
void MacroAssembler::load_klass_check_null(Register dst, Register src) {
null_check(src, oopDesc::klass_offset_in_bytes());
load_klass(dst, src);
}
// ((OopHandle)result).resolve();
void MacroAssembler::resolve_oop_handle(Register result, Register tmp1, Register tmp2) {
// OopHandle::resolve is an indirection.

View File

@ -843,6 +843,7 @@ public:
// oop manipulations
void load_klass(Register dst, Register src);
void load_klass_check_null(Register dst, Register src);
void store_klass(Register dst, Register src);
void cmp_klass(Register oop, Register trial_klass, Register tmp);

View File

@ -322,8 +322,7 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
__ null_check(receiver_reg);
} else {
// load receiver klass itself
__ null_check(receiver_reg, oopDesc::klass_offset_in_bytes());
__ load_klass(temp1_recv_klass, receiver_reg);
__ load_klass_check_null(temp1_recv_klass, receiver_reg);
__ verify_klass_ptr(temp1_recv_klass);
}
BLOCK_COMMENT("check_receiver {");

View File

@ -3236,8 +3236,7 @@ void TemplateTable::invokevirtual_helper(Register index,
__ bind(notFinal);
// get receiver klass
__ null_check(recv, oopDesc::klass_offset_in_bytes());
__ load_klass(r0, recv);
__ load_klass_check_null(r0, recv);
// profile this call
__ profile_virtual_call(r0, rlocals, r3);
@ -3326,8 +3325,7 @@ void TemplateTable::invokeinterface(int byte_no) {
__ tbz(r3, ConstantPoolCacheEntry::is_vfinal_shift, notVFinal);
// Get receiver klass into r3 - also a null check
__ null_check(r2, oopDesc::klass_offset_in_bytes());
__ load_klass(r3, r2);
__ load_klass_check_null(r3, r2);
Label subtype;
__ check_klass_subtype(r3, r0, r4, subtype);
@ -3343,8 +3341,7 @@ void TemplateTable::invokeinterface(int byte_no) {
// Get receiver klass into r3 - also a null check
__ restore_locals();
__ null_check(r2, oopDesc::klass_offset_in_bytes());
__ load_klass(r3, r2);
__ load_klass_check_null(r3, r2);
Label no_such_method;

View File

@ -1656,6 +1656,10 @@ void MacroAssembler::load_klass(Register dst_klass, Register src_oop, AsmConditi
ldr(dst_klass, Address(src_oop, oopDesc::klass_offset_in_bytes()), cond);
}
void MacroAssembler::load_klass_check_null(Register dst_klass, Register src_oop, Register tmp, AsmCondition cond) {
null_check(src_oop, tmp, oopDesc::klass_offset_in_bytes());
load_klass(dst_klass, src_oop, cond);
}
// Blows src_klass.
void MacroAssembler::store_klass(Register src_klass, Register dst_oop) {

View File

@ -853,6 +853,7 @@ public:
// klass oop manipulations if compressed
void load_klass(Register dst_klass, Register src_oop, AsmCondition cond = al);
void load_klass_check_null(Register dst_klass, Register src_oop, Register tmp, AsmCondition cond = al);
void store_klass(Register src_klass, Register dst_oop);

View File

@ -331,8 +331,7 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
__ null_check(receiver_reg, temp3);
} else {
// load receiver klass itself
__ null_check(receiver_reg, temp3, oopDesc::klass_offset_in_bytes());
__ load_klass(temp1_recv_klass, receiver_reg);
__ load_klass_check_null(temp1_recv_klass, receiver_reg, temp3);
__ verify_klass_ptr(temp1_recv_klass);
}
BLOCK_COMMENT("check_receiver {");

View File

@ -3625,8 +3625,7 @@ void TemplateTable::invokevirtual_helper(Register index,
__ bind(notFinal);
// get receiver klass
__ null_check(recv, Rtemp, oopDesc::klass_offset_in_bytes());
__ load_klass(recv_klass, recv);
__ load_klass_check_null(recv_klass, recv, Rtemp);
// profile this call
__ profile_virtual_call(R0_tmp, recv_klass);

View File

@ -45,8 +45,7 @@ void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) {
Label Lmiss;
verify_oop(receiver, FILE_AND_LINE);
MacroAssembler::null_check(receiver, oopDesc::klass_offset_in_bytes(), &Lmiss);
load_klass(temp_reg, receiver);
load_klass_check_null(temp_reg, receiver, &Lmiss);
if (TrapBasedICMissChecks && TrapBasedNullChecks) {
trap_ic_miss_check(temp_reg, iCache);

View File

@ -38,6 +38,7 @@ class InterpreterMacroAssembler: public MacroAssembler {
InterpreterMacroAssembler(CodeBuffer* code) : MacroAssembler(code) {}
void null_check_throw(Register a, int offset, Register temp_reg);
void load_klass_check_null_throw(Register dst, Register src, Register temp_reg);
void jump_to_entry(address entry, Register Rscratch);

View File

@ -55,6 +55,11 @@ void InterpreterMacroAssembler::null_check_throw(Register a, int offset, Registe
MacroAssembler::null_check_throw(a, offset, temp_reg, exception_entry);
}
void InterpreterMacroAssembler::load_klass_check_null_throw(Register dst, Register src, Register temp_reg) {
null_check_throw(src, oopDesc::klass_offset_in_bytes(), temp_reg);
load_klass(dst, src);
}
void InterpreterMacroAssembler::jump_to_entry(address entry, Register Rscratch) {
assert(entry, "Entry must have been generated by now");
if (is_within_range_of_b(entry, pc())) {

View File

@ -3058,6 +3058,11 @@ void MacroAssembler::load_klass(Register dst, Register src) {
}
}
void MacroAssembler::load_klass_check_null(Register dst, Register src, Label* is_null) {
null_check(src, oopDesc::klass_offset_in_bytes(), is_null);
load_klass(dst, src);
}
// ((OopHandle)result).resolve();
void MacroAssembler::resolve_oop_handle(Register result, Register tmp1, Register tmp2,
MacroAssembler::PreservationLevel preservation_level) {

View File

@ -732,6 +732,7 @@ class MacroAssembler: public Assembler {
// Load/Store klass oop from klass field. Compress.
void load_klass(Register dst, Register src);
void load_klass_check_null(Register dst, Register src, Label* is_null = NULL);
void store_klass(Register dst_oop, Register klass, Register tmp = R0);
void store_klass_gap(Register dst_oop, Register val = noreg); // Will store 0 if val not specified.

View File

@ -3439,8 +3439,7 @@ void TemplateTable::invokevirtual(int byte_no) {
__ load_dispatch_table(Rtable_addr, Interpreter::invoke_return_entry_table());
__ sldi(Rret_type, Rret_type, LogBytesPerWord);
__ ldx(Rret_addr, Rret_type, Rtable_addr);
__ null_check_throw(Rrecv, oopDesc::klass_offset_in_bytes(), R11_scratch1);
__ load_klass(Rrecv_klass, Rrecv);
__ load_klass_check_null_throw(Rrecv_klass, Rrecv, R11_scratch1);
__ verify_klass_ptr(Rrecv_klass);
__ profile_virtual_call(Rrecv_klass, R11_scratch1, R12_scratch2, false);
@ -3577,8 +3576,7 @@ void TemplateTable::invokeinterface(int byte_no) {
// then regular interface method.
// Get receiver klass - this is also a null check
__ null_check_throw(Rreceiver, oopDesc::klass_offset_in_bytes(), Rscratch2);
__ load_klass(Rrecv_klass, Rreceiver);
__ load_klass_check_null_throw(Rrecv_klass, Rreceiver, Rscratch2);
// Check corner case object method.
// Special case of invokeinterface called for virtual method of

View File

@ -83,10 +83,8 @@ VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
const Register rcvr_klass = R11_scratch1;
address npe_addr = __ pc(); // npe = null pointer exception
// check if we must do an explicit check (implicit checks disabled, offset too large).
__ null_check(R3, oopDesc::klass_offset_in_bytes(), /*implicit only*/NULL);
// Get receiver klass.
__ load_klass(rcvr_klass, R3);
__ load_klass_check_null(rcvr_klass, R3);
#ifndef PRODUCT
if (DebugVtables) {
@ -180,8 +178,7 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) {
tmp2 = R22_tmp2;
address npe_addr = __ pc(); // npe = null pointer exception
__ null_check(R3_ARG1, oopDesc::klass_offset_in_bytes(), /*implicit only*/NULL);
__ load_klass(rcvr_klass, R3_ARG1);
__ load_klass_check_null(rcvr_klass, R3_ARG1);
// Receiver subtype check against REFC.
__ ld(interface, CompiledICHolder::holder_klass_offset(), R19_method);

View File

@ -2079,6 +2079,11 @@ void MacroAssembler::load_klass(Register dst, Register src, Register tmp) {
}
}
void MacroAssembler::load_klass_check_null(Register dst, Register src, Register tmp) {
null_check(src, oopDesc::klass_offset_in_bytes());
load_klass(dst, src, tmp);
}
void MacroAssembler::store_klass(Register dst, Register src, Register tmp) {
// FIXME: Should this be a store release? concurrent gcs assumes
// klass length is valid if klass field is not null.

View File

@ -195,6 +195,7 @@ class MacroAssembler: public Assembler {
void access_store_at(BasicType type, DecoratorSet decorators, Address dst,
Register val, Register tmp1, Register tmp2, Register tmp3);
void load_klass(Register dst, Register src, Register tmp = t0);
void load_klass_check_null(Register dst, Register src, Register tmp = t0);
void store_klass(Register dst, Register src, Register tmp = t0);
void cmp_klass(Register oop, Register trial_klass, Register tmp1, Register tmp2, Label &L);

View File

@ -315,8 +315,7 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
__ null_check(receiver_reg);
} else {
// load receiver klass itself
__ null_check(receiver_reg, oopDesc::klass_offset_in_bytes());
__ load_klass(temp1_recv_klass, receiver_reg);
__ load_klass_check_null(temp1_recv_klass, receiver_reg);
__ verify_klass_ptr(temp1_recv_klass);
}
BLOCK_COMMENT("check_receiver {");

View File

@ -3150,8 +3150,7 @@ void TemplateTable::invokevirtual_helper(Register index,
__ bind(notFinal);
// get receiver klass
__ null_check(recv, oopDesc::klass_offset_in_bytes());
__ load_klass(x10, recv);
__ load_klass_check_null(x10, recv);
// profile this call
__ profile_virtual_call(x10, xlocals, x13);
@ -3236,8 +3235,7 @@ void TemplateTable::invokeinterface(int byte_no) {
__ beqz(t0, notVFinal);
// Check receiver klass into x13 - also a null check
__ null_check(x12, oopDesc::klass_offset_in_bytes());
__ load_klass(x13, x12);
__ load_klass_check_null(x13, x12);
Label subtype;
__ check_klass_subtype(x13, x10, x14, subtype);
@ -3253,8 +3251,7 @@ void TemplateTable::invokeinterface(int byte_no) {
// Get receiver klass into x13 - also a null check
__ restore_locals();
__ null_check(x12, oopDesc::klass_offset_in_bytes());
__ load_klass(x13, x12);
__ load_klass_check_null(x13, x12);
Label no_such_method;

View File

@ -3633,6 +3633,11 @@ void MacroAssembler::load_klass(Register klass, Register src_oop) {
}
}
void MacroAssembler::load_klass_check_null(Register klass, Register src_oop, Register tmp) {
null_check(src_oop, tmp, oopDesc::klass_offset_in_bytes());
load_klass(klass, src_oop);
}
void MacroAssembler::store_klass(Register klass, Register dst_oop, Register ck) {
if (UseCompressedClassPointers) {
assert_different_registers(dst_oop, klass, Z_R0);

View File

@ -766,6 +766,7 @@ class MacroAssembler: public Assembler {
void decode_klass_not_null(Register dst);
void load_klass(Register klass, Address mem);
void load_klass(Register klass, Register src_oop);
void load_klass_check_null(Register klass, Register src_oop, Register tmp);
void store_klass(Register klass, Register dst_oop, Register ck = noreg); // Klass will get compressed if ck not provided.
void store_klass_gap(Register s, Register dst_oop);

View File

@ -411,8 +411,7 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
__ null_check(receiver_reg);
} else {
// Load receiver klass itself.
__ null_check(receiver_reg, Z_R0, oopDesc::klass_offset_in_bytes());
__ load_klass(temp1_recv_klass, receiver_reg);
__ load_klass_check_null(temp1_recv_klass, receiver_reg, Z_R0);
__ verify_klass_ptr(temp1_recv_klass);
}
BLOCK_COMMENT("check_receiver {");

View File

@ -3489,8 +3489,7 @@ void TemplateTable::invokevirtual_helper(Register index,
__ bind(notFinal);
// Get receiver klass.
__ null_check(recv, Z_R0_scratch, oopDesc::klass_offset_in_bytes());
__ load_klass(Z_tmp_2, recv);
__ load_klass_check_null(Z_tmp_2, recv, Z_R0_scratch);
// Profile this call.
__ profile_virtual_call(Z_tmp_2, Z_ARG4, Z_ARG5);

View File

@ -83,10 +83,8 @@ VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
const Register rcvr_klass = Z_R1_scratch;
address npe_addr = __ pc(); // npe == NULL ptr exception
// check if we must do an explicit check (implicit checks disabled, offset too large).
__ null_check(Z_ARG1, Z_R1_scratch, oopDesc::klass_offset_in_bytes());
// Get receiver klass.
__ load_klass(rcvr_klass, Z_ARG1);
__ load_klass_check_null(rcvr_klass, Z_ARG1, Z_R1_scratch);
#ifndef PRODUCT
if (DebugVtables) {
@ -196,8 +194,7 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) {
// Get receiver klass.
// Must do an explicit check if offset too large or implicit checks are disabled.
address npe_addr = __ pc(); // npe == NULL ptr exception
__ null_check(Z_ARG1, Z_R1_scratch, oopDesc::klass_offset_in_bytes());
__ load_klass(rcvr_klass, Z_ARG1);
__ load_klass_check_null(rcvr_klass, Z_ARG1, Z_R1_scratch);
// Receiver subtype check against REFC.
__ z_lg(interface, Address(Z_method, CompiledICHolder::holder_klass_offset()));

View File

@ -5132,6 +5132,11 @@ void MacroAssembler::load_klass(Register dst, Register src, Register tmp) {
movptr(dst, Address(src, oopDesc::klass_offset_in_bytes()));
}
void MacroAssembler::load_klass_check_null(Register dst, Register src, Register tmp) {
null_check(src, oopDesc::klass_offset_in_bytes());
load_klass(dst, src, tmp);
}
void MacroAssembler::store_klass(Register dst, Register src, Register tmp) {
assert_different_registers(src, tmp);
assert_different_registers(dst, tmp);

View File

@ -349,6 +349,7 @@ class MacroAssembler: public Assembler {
// oop manipulations
void load_klass(Register dst, Register src, Register tmp);
void load_klass_check_null(Register dst, Register src, Register tmp);
void store_klass(Register dst, Register src, Register tmp);
void access_load_at(BasicType type, DecoratorSet decorators, Register dst, Address src,

View File

@ -379,8 +379,7 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
__ null_check(receiver_reg);
} else {
// load receiver klass itself
__ null_check(receiver_reg, oopDesc::klass_offset_in_bytes());
__ load_klass(temp1_recv_klass, receiver_reg, temp2);
__ load_klass_check_null(temp1_recv_klass, receiver_reg, temp2);
__ verify_klass_ptr(temp1_recv_klass);
}
BLOCK_COMMENT("check_receiver {");

View File

@ -3661,8 +3661,7 @@ void TemplateTable::invokevirtual_helper(Register index,
__ bind(notFinal);
// get receiver klass
__ null_check(recv, oopDesc::klass_offset_in_bytes());
__ load_klass(rax, recv, rscratch1);
__ load_klass_check_null(rax, recv, rscratch1);
// profile this call
__ profile_virtual_call(rax, rlocals, rdx);
@ -3753,8 +3752,7 @@ void TemplateTable::invokeinterface(int byte_no) {
__ jcc(Assembler::zero, notVFinal);
// Get receiver klass into rlocals - also a null check
__ null_check(rcx, oopDesc::klass_offset_in_bytes());
__ load_klass(rlocals, rcx, rscratch1);
__ load_klass_check_null(rlocals, rcx, rscratch1);
Label subtype;
__ check_klass_subtype(rlocals, rax, rbcp, subtype);
@ -3776,8 +3774,7 @@ void TemplateTable::invokeinterface(int byte_no) {
// Get receiver klass into rdx - also a null check
__ restore_locals(); // restore r14
__ null_check(rcx, oopDesc::klass_offset_in_bytes());
__ load_klass(rdx, rcx, rscratch1);
__ load_klass_check_null(rdx, rcx, rscratch1);
Label no_such_method;