8332082: Shenandoah: Use consistent tests to determine when pre-write barrier is active

Reviewed-by: kdnilsen, shade
This commit is contained in:
William Kemper 2024-05-23 22:33:24 +00:00
parent 0a9d1f8c89
commit ddd73b4583
6 changed files with 35 additions and 40 deletions

View File

@ -109,18 +109,13 @@ void ShenandoahBarrierSetAssembler::satb_write_barrier_pre(MacroAssembler* masm,
assert_different_registers(obj, pre_val, tmp1, tmp2);
assert(pre_val != noreg && tmp1 != noreg && tmp2 != noreg, "expecting a register");
Address in_progress(thread, in_bytes(ShenandoahThreadLocalData::satb_mark_queue_active_offset()));
Address index(thread, in_bytes(ShenandoahThreadLocalData::satb_mark_queue_index_offset()));
Address buffer(thread, in_bytes(ShenandoahThreadLocalData::satb_mark_queue_buffer_offset()));
// Is marking active?
if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
__ ldrw(tmp1, in_progress);
} else {
assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
__ ldrb(tmp1, in_progress);
}
__ cbzw(tmp1, done);
Address gc_state(thread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
__ ldrb(tmp1, gc_state);
__ tbz(tmp1, ShenandoahHeap::MARKING_BITPOS, done);
// Do we need to load the previous value?
if (obj != noreg) {

View File

@ -112,18 +112,14 @@ void ShenandoahBarrierSetAssembler::satb_write_barrier_pre(MacroAssembler* masm,
assert_different_registers(obj, pre_val, tmp1, tmp2);
assert(pre_val != noreg && tmp1 != noreg && tmp2 != noreg, "expecting a register");
Address in_progress(thread, in_bytes(ShenandoahThreadLocalData::satb_mark_queue_active_offset()));
Address index(thread, in_bytes(ShenandoahThreadLocalData::satb_mark_queue_index_offset()));
Address buffer(thread, in_bytes(ShenandoahThreadLocalData::satb_mark_queue_buffer_offset()));
// Is marking active?
if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
__ lwu(tmp1, in_progress);
} else {
assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
__ lbu(tmp1, in_progress);
}
__ beqz(tmp1, done);
Address gc_state(xthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
__ lbu(t1, gc_state);
__ test_bit(t1, t1, ShenandoahHeap::MARKING_BITPOS);
__ beqz(t1, done);
// Do we need to load the previous value?
if (obj != noreg) {

View File

@ -219,7 +219,6 @@ void ShenandoahBarrierSetAssembler::satb_write_barrier_pre(MacroAssembler* masm,
assert(pre_val != rax, "check this code");
}
Address in_progress(thread, in_bytes(ShenandoahThreadLocalData::satb_mark_queue_active_offset()));
Address index(thread, in_bytes(ShenandoahThreadLocalData::satb_mark_queue_index_offset()));
Address buffer(thread, in_bytes(ShenandoahThreadLocalData::satb_mark_queue_buffer_offset()));

View File

@ -58,26 +58,32 @@ ShenandoahBarrierSetC1::ShenandoahBarrierSetC1() :
void ShenandoahBarrierSetC1::pre_barrier(LIRGenerator* gen, CodeEmitInfo* info, DecoratorSet decorators, LIR_Opr addr_opr, LIR_Opr pre_val) {
// First we test whether marking is in progress.
BasicType flag_type;
bool patch = (decorators & C1_NEEDS_PATCHING) != 0;
bool do_load = pre_val == LIR_OprFact::illegalOpr;
if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
flag_type = T_INT;
} else {
guarantee(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1,
"Assumption");
// Use unsigned type T_BOOLEAN here rather than signed T_BYTE since some platforms, eg. ARM,
// need to use unsigned instructions to use the large offset to load the satb_mark_queue.
flag_type = T_BOOLEAN;
}
LIR_Opr thrd = gen->getThreadPointer();
LIR_Address* mark_active_flag_addr =
new LIR_Address(thrd,
in_bytes(ShenandoahThreadLocalData::satb_mark_queue_active_offset()),
flag_type);
// Read the marking-in-progress flag.
LIR_Address* gc_state_addr =
new LIR_Address(thrd,
in_bytes(ShenandoahThreadLocalData::gc_state_offset()),
T_BYTE);
// Read the gc_state flag.
LIR_Opr flag_val = gen->new_register(T_INT);
__ load(mark_active_flag_addr, flag_val);
__ load(gc_state_addr, flag_val);
// Create a mask to test if the marking bit is set.
// TODO: can we directly test if bit is set?
LIR_Opr mask = LIR_OprFact::intConst(ShenandoahHeap::MARKING);
LIR_Opr mask_reg = gen->new_register(T_INT);
__ move(mask, mask_reg);
if (two_operand_lir_form) {
__ logical_and(flag_val, mask_reg, flag_val);
} else {
LIR_Opr masked_flag = gen->new_register(T_INT);
__ logical_and(flag_val, mask_reg, masked_flag);
flag_val = masked_flag;
}
__ cmp(lir_cond_notEqual, flag_val, LIR_OprFact::intConst(0));
LIR_PatchCode pre_val_patch_code = lir_patch_none;

View File

@ -980,7 +980,7 @@ void ShenandoahBarrierSetC2::verify_gc_barriers(Compile* compile, CompilePhase p
ShenandoahBarrierC2Support::verify(Compile::current()->root());
} else if (phase == BarrierSetC2::BeforeCodeGen) {
// Verify Shenandoah pre-barriers
const int marking_offset = in_bytes(ShenandoahThreadLocalData::satb_mark_queue_active_offset());
const int gc_state_offset = in_bytes(ShenandoahThreadLocalData::gc_state_offset());
Unique_Node_List visited;
Node_List worklist;
@ -988,7 +988,10 @@ void ShenandoahBarrierSetC2::verify_gc_barriers(Compile* compile, CompilePhase p
worklist.push(compile->root());
while (worklist.size() > 0) {
Node *x = worklist.pop();
if (x == nullptr || x == compile->top()) continue;
if (x == nullptr || x == compile->top()) {
continue;
}
if (visited.member(x)) {
continue;
} else {
@ -1016,7 +1019,7 @@ void ShenandoahBarrierSetC2::verify_gc_barriers(Compile* compile, CompilePhase p
LoadNode *load = cmp->in(1)->as_Load();
if (load->Opcode() == Op_LoadB && load->in(2)->is_AddP() && load->in(2)->in(2)->Opcode() == Op_ThreadLocal
&& load->in(2)->in(3)->is_Con()
&& load->in(2)->in(3)->bottom_type()->is_intptr_t()->get_con() == marking_offset) {
&& load->in(2)->in(3)->bottom_type()->is_intptr_t()->get_con() == gc_state_offset) {
Node *if_ctrl = iff->in(0);
Node *load_ctrl = load->in(0);

View File

@ -158,10 +158,6 @@ public:
}
// Offsets
static ByteSize satb_mark_queue_active_offset() {
return satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_active();
}
static ByteSize satb_mark_queue_index_offset() {
return satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_index();
}