< prev index next >
src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp
Print this page
rev 56771 : 8233339: Shenandoah: Centralize load barrier decisions into ShenandoahBarrierSet
*** 344,398 ****
load_reference_barrier_not_null(masm, dst, load_addr);
__ bind(is_null);
}
}
void ShenandoahBarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
Register dst, Address src, Register tmp1, Register tmp_thread) {
- bool on_oop = is_reference_type(type);
- bool not_in_heap = (decorators & IN_NATIVE) != 0;
- bool on_weak = (decorators & ON_WEAK_OOP_REF) != 0;
- bool on_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0;
- bool on_reference = on_weak || on_phantom;
- bool is_traversal_mode = ShenandoahHeap::heap()->is_traversal_mode();
- bool keep_alive = (decorators & AS_NO_KEEPALIVE) == 0 || is_traversal_mode;
Register result_dst = dst;
! if (on_oop) {
! // We want to preserve src
if (dst == src.base() || dst == src.index()) {
dst = rscratch1;
}
assert_different_registers(dst, src.base(), src.index());
}
BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread);
! if (on_oop) {
! if (not_in_heap && !is_traversal_mode) {
load_reference_barrier_native(masm, dst, src);
} else {
load_reference_barrier(masm, dst, src);
}
if (dst != result_dst) {
__ mov(result_dst, dst);
dst = result_dst;
}
! if (ShenandoahKeepAliveBarrier && on_reference && keep_alive) {
__ enter();
satb_write_barrier_pre(masm /* masm */,
noreg /* obj */,
dst /* pre_val */,
rthread /* thread */,
tmp1 /* tmp */,
true /* tosca_live */,
true /* expand_call */);
__ leave();
}
- }
}
void ShenandoahBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
Address dst, Register val, Register tmp1, Register tmp2) {
bool on_oop = is_reference_type(type);
--- 344,414 ----
load_reference_barrier_not_null(masm, dst, load_addr);
__ bind(is_null);
}
}
+
+ //
+ // Arguments:
+ //
+ // Inputs:
+ // src: oop location to load from, might be clobbered
+ // tmp1: unused
+ // tmp_thread: unused
+ //
+ // Output:
+ // dst: oop loaded from src location
+ //
+ // Kill:
+ // rscratch1 (scratch reg)
+ //
+ // Alias:
+ // dst: rscratch1 (might use rscratch1 as temporary output register to avoid clobbering src)
+ //
void ShenandoahBarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
Register dst, Address src, Register tmp1, Register tmp_thread) {
Register result_dst = dst;
+ bool need_load_reference_barrier = ShenandoahBarrierSet::need_load_reference_barrier(decorators, type);
! // Only preserve src address if we need load reference barrier
! if (need_load_reference_barrier) {
! // Use rscratch1 as temporary output register to avoid clobbering src
if (dst == src.base() || dst == src.index()) {
dst = rscratch1;
}
assert_different_registers(dst, src.base(), src.index());
}
BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread);
! if (!need_load_reference_barrier) {
! return;
! }
!
! if (ShenandoahBarrierSet::use_native_load_reference_barrier(decorators, type)) {
load_reference_barrier_native(masm, dst, src);
} else {
load_reference_barrier(masm, dst, src);
}
+ // Move loaded oop to final destination
if (dst != result_dst) {
__ mov(result_dst, dst);
dst = result_dst;
}
! if (ShenandoahBarrierSet::need_keep_alive_barrier(decorators, type)) {
__ enter();
satb_write_barrier_pre(masm /* masm */,
noreg /* obj */,
dst /* pre_val */,
rthread /* thread */,
tmp1 /* tmp */,
true /* tosca_live */,
true /* expand_call */);
__ leave();
}
}
void ShenandoahBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
Address dst, Register val, Register tmp1, Register tmp2) {
bool on_oop = is_reference_type(type);
< prev index next >