8202714: Create a MacroAssembler::access_load/store_at wrapper for AArch64

Reviewed-by: adinn, smonteith
This commit is contained in:
Roman Kennke 2018-05-15 05:33:26 -04:00
parent d64c38aab2
commit 14291ba72a
9 changed files with 80 additions and 47 deletions

View file

@ -116,7 +116,7 @@ void G1BarrierSetAssembler::g1_write_barrier_pre(MacroAssembler* masm,
// Do we need to load the previous value?
if (obj != noreg) {
__ load_heap_oop(pre_val, Address(obj, 0));
__ load_heap_oop(pre_val, Address(obj, 0), noreg, noreg, AS_RAW);
}
// Is the previous value null?
@ -294,7 +294,7 @@ void G1BarrierSetAssembler::oop_store_at(MacroAssembler* masm, DecoratorSet deco
false /* expand_call */);
if (val == noreg) {
__ store_heap_oop_null(Address(r3, 0));
BarrierSetAssembler::store_at(masm, decorators, type, Address(r3, 0), noreg, noreg, noreg);
} else {
// G1 barrier needs uncompressed oop for region cross check.
Register new_val = val;
@ -302,7 +302,7 @@ void G1BarrierSetAssembler::oop_store_at(MacroAssembler* masm, DecoratorSet deco
new_val = rscratch2;
__ mov(new_val, val);
}
__ store_heap_oop(Address(r3, 0), val);
BarrierSetAssembler::store_at(masm, decorators, type, Address(r3, 0), val, noreg, noreg);
g1_write_barrier_post(masm,
r3 /* store_adr */,
new_val /* new_val */,

View file

@ -35,11 +35,21 @@ void BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators,
bool on_heap = (decorators & IN_HEAP) != 0;
bool on_root = (decorators & IN_ROOT) != 0;
bool oop_not_null = (decorators & OOP_NOT_NULL) != 0;
switch (type) {
case T_OBJECT:
case T_ARRAY: {
if (on_heap) {
__ load_heap_oop(dst, src);
if (UseCompressedOops) {
__ ldrw(dst, src);
if (oop_not_null) {
__ decode_heap_oop_not_null(dst);
} else {
__ decode_heap_oop(dst);
}
} else {
__ ldr(dst, src);
}
} else {
assert(on_root, "why else?");
__ ldr(dst, src);
@ -57,8 +67,17 @@ void BarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators
switch (type) {
case T_OBJECT:
case T_ARRAY: {
val = val == noreg ? zr : val;
if (on_heap) {
__ store_heap_oop(dst, val);
if (UseCompressedOops) {
assert(!dst.uses(val), "not enough registers");
if (val != zr) {
__ encode_heap_oop(val);
}
__ strw(val, dst);
} else {
__ str(val, dst);
}
} else {
assert(on_root, "why else?");
__ str(val, dst);

View file

@ -90,13 +90,14 @@ void CardTableBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembl
void CardTableBarrierSetAssembler::oop_store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
Address dst, Register val, Register tmp1, Register tmp2) {
bool in_heap = (decorators & IN_HEAP) != 0;
bool on_array = (decorators & IN_HEAP_ARRAY) != 0;
bool on_anonymous = (decorators & ON_UNKNOWN_OOP_REF) != 0;
bool precise = on_array || on_anonymous;
if (val == noreg) {
__ store_heap_oop_null(dst);
} else {
__ store_heap_oop(dst, val);
bool needs_post_barrier = val != noreg && in_heap;
BarrierSetAssembler::store_at(masm, decorators, type, dst, val, noreg, noreg);
if (needs_post_barrier) {
// flatten object address if needed
if (!precise || (dst.index() == noreg && dst.offset() == 0)) {
store_check(masm, dst.base(), dst);

View file

@ -278,8 +278,7 @@ void InterpreterMacroAssembler::load_resolved_reference_at_index(
resolve_oop_handle(result, tmp);
// Add in the index
add(result, result, index);
BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
bs->load_at(this, IN_HEAP, T_OBJECT, result, Address(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT)), tmp, /*tmp_thread*/ noreg);
load_heap_oop(result, Address(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
}
void InterpreterMacroAssembler::load_resolved_klass_at_offset(

View file

@ -3975,41 +3975,48 @@ void MacroAssembler::set_narrow_klass(Register dst, Klass* k) {
movk(dst, nk & 0xffff);
}
void MacroAssembler::load_heap_oop(Register dst, Address src)
{
if (UseCompressedOops) {
ldrw(dst, src);
decode_heap_oop(dst);
void MacroAssembler::access_load_at(BasicType type, DecoratorSet decorators,
Register dst, Address src,
Register tmp1, Register thread_tmp) {
BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
bool as_raw = (decorators & AS_RAW) != 0;
if (as_raw) {
bs->BarrierSetAssembler::load_at(this, decorators, type, dst, src, tmp1, thread_tmp);
} else {
ldr(dst, src);
bs->load_at(this, decorators, type, dst, src, tmp1, thread_tmp);
}
}
void MacroAssembler::load_heap_oop_not_null(Register dst, Address src)
{
if (UseCompressedOops) {
ldrw(dst, src);
decode_heap_oop_not_null(dst);
void MacroAssembler::access_store_at(BasicType type, DecoratorSet decorators,
Address dst, Register src,
Register tmp1, Register thread_tmp) {
BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
bool as_raw = (decorators & AS_RAW) != 0;
if (as_raw) {
bs->BarrierSetAssembler::store_at(this, decorators, type, dst, src, tmp1, thread_tmp);
} else {
ldr(dst, src);
bs->store_at(this, decorators, type, dst, src, tmp1, thread_tmp);
}
}
void MacroAssembler::store_heap_oop(Address dst, Register src) {
if (UseCompressedOops) {
assert(!dst.uses(src), "not enough registers");
encode_heap_oop(src);
strw(src, dst);
} else
str(src, dst);
void MacroAssembler::load_heap_oop(Register dst, Address src, Register tmp1,
Register thread_tmp, DecoratorSet decorators) {
access_load_at(T_OBJECT, IN_HEAP | decorators, dst, src, tmp1, thread_tmp);
}
void MacroAssembler::load_heap_oop_not_null(Register dst, Address src, Register tmp1,
Register thread_tmp, DecoratorSet decorators) {
access_load_at(T_OBJECT, IN_HEAP | OOP_NOT_NULL | decorators, dst, src, tmp1, thread_tmp);
}
void MacroAssembler::store_heap_oop(Address dst, Register src, Register tmp1,
Register thread_tmp, DecoratorSet decorators) {
access_store_at(T_OBJECT, IN_HEAP | decorators, dst, src, tmp1, thread_tmp);
}
// Used for storing NULLs.
void MacroAssembler::store_heap_oop_null(Address dst) {
if (UseCompressedOops) {
strw(zr, dst);
} else
str(zr, dst);
access_store_at(T_OBJECT, IN_HEAP, dst, noreg, noreg, noreg);
}
Address MacroAssembler::allocate_metadata_address(Metadata* obj) {

View file

@ -789,10 +789,19 @@ public:
void resolve_oop_handle(Register result, Register tmp = r5);
void load_mirror(Register dst, Register method, Register tmp = r5);
void load_heap_oop(Register dst, Address src);
void access_load_at(BasicType type, DecoratorSet decorators, Register dst, Address src,
Register tmp1, Register tmp_thread);
void load_heap_oop_not_null(Register dst, Address src);
void store_heap_oop(Address dst, Register src);
void access_store_at(BasicType type, DecoratorSet decorators, Address dst, Register src,
Register tmp1, Register tmp_thread);
void load_heap_oop(Register dst, Address src, Register tmp1 = noreg,
Register thread_tmp = noreg, DecoratorSet decorators = 0);
void load_heap_oop_not_null(Register dst, Address src, Register tmp1 = noreg,
Register thread_tmp = noreg, DecoratorSet decorators = 0);
void store_heap_oop(Address dst, Register src, Register tmp1 = noreg,
Register tmp_thread = noreg, DecoratorSet decorators = 0);
// currently unimplemented
// Used for storing NULL. All other oop constants should be

View file

@ -135,11 +135,11 @@ void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm,
// Load the invoker, as MH -> MH.form -> LF.vmentry
__ verify_oop(recv);
__ load_heap_oop(method_temp, Address(recv, NONZERO(java_lang_invoke_MethodHandle::form_offset_in_bytes())));
__ load_heap_oop(method_temp, Address(recv, NONZERO(java_lang_invoke_MethodHandle::form_offset_in_bytes())), temp2);
__ verify_oop(method_temp);
__ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes())));
__ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes())), temp2);
__ verify_oop(method_temp);
__ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes())));
__ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes())), temp2);
__ verify_oop(method_temp);
__ ldr(method_temp, Address(method_temp, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset_in_bytes())));
@ -311,7 +311,7 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
if (VerifyMethodHandles && iid != vmIntrinsics::_linkToInterface) {
Label L_ok;
Register temp2_defc = temp2;
__ load_heap_oop(temp2_defc, member_clazz);
__ load_heap_oop(temp2_defc, member_clazz, temp3);
load_klass_from_Class(_masm, temp2_defc);
__ verify_klass_ptr(temp2_defc);
__ check_klass_subtype(temp1_recv_klass, temp2_defc, temp3, L_ok);

View file

@ -1816,13 +1816,13 @@ class StubGenerator: public StubCodeGenerator {
__ align(OptoLoopAlignment);
__ BIND(L_store_element);
__ store_heap_oop(__ post(to, UseCompressedOops ? 4 : 8), copied_oop); // store the oop
__ store_heap_oop(__ post(to, UseCompressedOops ? 4 : 8), copied_oop, noreg, noreg, AS_RAW); // store the oop
__ sub(count, count, 1);
__ cbz(count, L_do_card_marks);
// ======== loop entry is here ========
__ BIND(L_load_element);
__ load_heap_oop(copied_oop, __ post(from, UseCompressedOops ? 4 : 8)); // load the oop
__ load_heap_oop(copied_oop, __ post(from, UseCompressedOops ? 4 : 8), noreg, noreg, AS_RAW); // load the oop
__ cbz(copied_oop, L_store_element);
__ load_klass(r19_klass, copied_oop);// query the object klass

View file

@ -147,16 +147,14 @@ static void do_oop_store(InterpreterMacroAssembler* _masm,
Register val,
DecoratorSet decorators) {
assert(val == noreg || val == r0, "parameter is just for looks");
BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
bs->store_at(_masm, decorators, T_OBJECT, dst, val, /*tmp1*/ r10, /*tmp2*/ r1);
__ store_heap_oop(dst, val, r10, r1, decorators);
}
static void do_oop_load(InterpreterMacroAssembler* _masm,
Address src,
Register dst,
DecoratorSet decorators) {
BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
bs->load_at(_masm, decorators, T_OBJECT, dst, src, /*tmp1*/ r10, /*tmp_thread*/ r1);
__ load_heap_oop(dst, src, r10, r1, decorators);
}
Address TemplateTable::at_bcp(int offset) {