[vm, compiler] Use AMOs in the RISC-V write barrier.

AMOs are more efficient than a LR/SC pair.

TEST=ci
Change-Id: I74915669bf4d13b92c04ed6ef21d61dd58df36ee
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/240142
Reviewed-by: Alexander Aprelev <aam@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
Ryan Macnak 2022-04-05 00:01:32 +00:00 committed by Commit Bot
parent 8fdd773096
commit 1af37bd92a

View file

@ -1675,18 +1675,17 @@ static void GenerateWriteBarrierStubHelper(Assembler* assembler,
__ sx(T4, Address(SP, 0 * target::kWordSize));
// Atomically clear kOldAndNotRememberedBit.
// TODO(riscv): Use amoand instead of lr/sc.
ASSERT(target::Object::tags_offset() == 0);
__ subi(T3, A0, kHeapObjectTag);
// T3: Untagged address of header word (lr/sc do not support offsets).
Label retry;
__ Bind(&retry);
__ lr(T2, Address(T3, 0));
__ andi(TMP2, T2, 1 << target::UntaggedObject::kOldAndNotRememberedBit);
__ beqz(TMP2, &lost_race);
__ andi(T2, T2, ~(1 << target::UntaggedObject::kOldAndNotRememberedBit));
__ sc(T4, T2, Address(T3, 0));
__ bnez(T4, &retry);
// T3: Untagged address of header word (amo's do not support offsets).
__ li(TMP2, ~(1 << target::UntaggedObject::kOldAndNotRememberedBit));
#if XLEN == 32
__ amoandw(TMP2, TMP2, Address(T3, 0));
#else
__ amoandd(TMP2, TMP2, Address(T3, 0));
#endif
__ andi(TMP2, TMP2, 1 << target::UntaggedObject::kOldAndNotRememberedBit);
__ beqz(TMP2, &lost_race); // Was already clear -> lost race.
// Load the StoreBuffer block out of the thread. Then load top_ out of the
// StoreBufferBlock and add the address to the pointers_.
@ -1738,18 +1737,18 @@ static void GenerateWriteBarrierStubHelper(Assembler* assembler,
__ sx(T4, Address(SP, 0 * target::kWordSize));
// Atomically clear kOldAndNotMarkedBit.
// TODO(riscv): Use amoand instead of lr/sc.
Label marking_retry, marking_overflow;
Label marking_overflow;
ASSERT(target::Object::tags_offset() == 0);
__ subi(T3, A1, kHeapObjectTag);
// T3: Untagged address of header word (lr/sc do not support offsets).
__ Bind(&marking_retry);
__ lr(T2, Address(T3, 0));
__ andi(TMP2, T2, 1 << target::UntaggedObject::kOldAndNotMarkedBit);
__ beqz(TMP2, &lost_race);
__ andi(T2, T2, ~(1 << target::UntaggedObject::kOldAndNotMarkedBit));
__ sc(T4, T2, Address(T3, 0));
__ bnez(T4, &marking_retry);
// T3: Untagged address of header word (amo's do not support offsets).
__ li(TMP2, ~(1 << target::UntaggedObject::kOldAndNotMarkedBit));
#if XLEN == 32
__ amoandw(TMP2, TMP2, Address(T3, 0));
#else
__ amoandd(TMP2, TMP2, Address(T3, 0));
#endif
__ andi(TMP2, TMP2, 1 << target::UntaggedObject::kOldAndNotMarkedBit);
__ beqz(TMP2, &lost_race); // Was already clear -> lost race.
__ LoadFromOffset(T4, THR, target::Thread::marking_stack_block_offset());
__ LoadFromOffset(T2, T4, target::MarkingStackBlock::top_offset(),