8302070: Factor null-check into load_klass() calls
Reviewed-by: phh, coleenp
This commit is contained in:
parent
e731695217
commit
7cf7e0a20b
@ -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.
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 {");
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 {");
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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())) {
|
||||
|
@ -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) {
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 {");
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 {");
|
||||
|
@ -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);
|
||||
|
@ -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()));
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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 {");
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user