< prev index next >
src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp
Print this page
rev 56771 : 8233401: Shenandoah: Refactor/cleanup Shenandoah load barrier code
*** 21,30 ****
--- 21,31 ----
*
*/
#include "precompiled.hpp"
#include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp"
+ #include "gc/shenandoah/shenandoahConcurrentRoots.hpp"
#include "gc/shenandoah/shenandoahForwarding.hpp"
#include "gc/shenandoah/shenandoahHeap.inline.hpp"
#include "gc/shenandoah/shenandoahHeapRegion.hpp"
#include "gc/shenandoah/shenandoahHeuristics.hpp"
#include "gc/shenandoah/shenandoahRuntime.hpp"
*** 443,500 ****
load_reference_barrier_not_null(masm, dst, src);
__ bind(done);
}
}
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 on_weak = (decorators & ON_WEAK_OOP_REF) != 0;
! bool on_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0;
! bool not_in_heap = (decorators & IN_NATIVE) != 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;
bool use_tmp1_for_dst = false;
! if (on_oop) {
! // We want to preserve src
if (dst == src.base() || dst == src.index()) {
// Use tmp1 for dst if possible, as it is not used in BarrierAssembler::load_at()
if (tmp1->is_valid() && tmp1 != src.base() && tmp1 != src.index()) {
dst = tmp1;
use_tmp1_for_dst = true;
} else {
dst = rdi;
__ push(dst);
}
- }
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) {
__ movptr(result_dst, dst);
if (!use_tmp1_for_dst) {
__ pop(dst);
}
dst = result_dst;
}
! if (ShenandoahKeepAliveBarrier && on_reference && keep_alive) {
const Register thread = NOT_LP64(tmp_thread) LP64_ONLY(r15_thread);
assert_different_registers(dst, tmp1, tmp_thread);
NOT_LP64(__ get_thread(thread));
// Generate the SATB pre-barrier code to log the value of
// the referent field in an SATB buffer.
--- 444,525 ----
load_reference_barrier_not_null(masm, dst, src);
__ bind(done);
}
}
+ //
+ // Arguments:
+ //
+ // Inputs:
+ // src: oop location, might be clobbered
+ // tmp1: scratch register, might not be valid.
+ // tmp_thread: unused
+ //
+ // Output:
+ // dst: oop loaded from src location
+ //
+ // Kill:
+ // tmp1 (if it is valid)
+ //
void ShenandoahBarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
Register dst, Address src, Register tmp1, Register tmp_thread) {
! // 1: none-reference load, no additional barrier is needed
! if (!is_reference_type(type)) {
! BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread);
! return;
! }
+ // 2: load a reference from src location and apply LRB if ShenandoahLoadRefBarrier is set
+ if (ShenandoahLoadRefBarrier) {
Register result_dst = dst;
bool use_tmp1_for_dst = false;
! // Preserve src location for LRB
if (dst == src.base() || dst == src.index()) {
// Use tmp1 for dst if possible, as it is not used in BarrierAssembler::load_at()
if (tmp1->is_valid() && tmp1 != src.base() && tmp1 != src.index()) {
dst = tmp1;
use_tmp1_for_dst = true;
} else {
dst = rdi;
__ push(dst);
}
assert_different_registers(dst, src.base(), src.index());
}
BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread);
! // Native barrier is for concurrent root processing
! if ((decorators & IN_NATIVE) != 0 && ShenandoahConcurrentRoots::can_do_concurrent_roots()) {
load_reference_barrier_native(masm, dst, src);
} else {
load_reference_barrier(masm, dst, src);
}
+ // Move loaded oop to final destination
if (dst != result_dst) {
__ movptr(result_dst, dst);
if (!use_tmp1_for_dst) {
__ pop(dst);
}
dst = result_dst;
}
+ } else {
+ BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread);
+ }
+
+ // 3: apply keep-alive barrier if ShenandoahKeepAliveBarrier is set
+ if (ShenandoahKeepAliveBarrier) {
+ 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;
! if (on_reference && keep_alive) {
const Register thread = NOT_LP64(tmp_thread) LP64_ONLY(r15_thread);
assert_different_registers(dst, tmp1, tmp_thread);
NOT_LP64(__ get_thread(thread));
// Generate the SATB pre-barrier code to log the value of
// the referent field in an SATB buffer.
< prev index next >