mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8202714: Create a MacroAssembler::access_load/store_at wrapper for AArch64
Reviewed-by: adinn, smonteith
This commit is contained in:
parent
d64c38aab2
commit
14291ba72a
9 changed files with 80 additions and 47 deletions
|
@ -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 */,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue