[vm, compiler] Fix clobbered register on strex failure path when dirtying cards.

Add spurious store-conditional failures to the simulators.

TEST=golem
Change-Id: Ice3d18145cbb883cf868ad4ee077a2d1e56b15ae
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/370962
Reviewed-by: Siva Annamalai <asiva@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
Ryan Macnak 2024-06-11 18:00:35 +00:00 committed by Commit Queue
parent f97004f639
commit 4242ff536f
7 changed files with 26 additions and 7 deletions

View file

@ -1720,7 +1720,7 @@ static void GenerateWriteBarrierStubHelper(Assembler* assembler, bool cards) {
__ b(&remember_card_slow, EQ);
// Atomically dirty the card.
__ PushList((1 << R0) | (1 << R1));
__ PushList((1 << R0) | (1 << R1) | (1 << R2));
__ AndImmediate(TMP, R1, target::kPageMask); // Page.
__ sub(R9, R9, Operand(TMP)); // Offset in page.
__ Lsr(R9, R9, Operand(target::Page::kBytesPerCardLog2)); // Card index.
@ -1735,10 +1735,10 @@ static void GenerateWriteBarrierStubHelper(Assembler* assembler, bool cards) {
__ Bind(&retry);
__ ldrex(R1, TMP);
__ orr(R1, R1, Operand(R0));
__ strex(R0, R1, TMP);
__ cmp(R0, Operand(1));
__ strex(R2, R1, TMP);
__ cmp(R2, Operand(1));
__ b(&retry, EQ);
__ PopList((1 << R0) | (1 << R1));
__ PopList((1 << R0) | (1 << R1) | (1 << R2));
__ Ret();
// Card table not yet allocated.

View file

@ -1049,6 +1049,10 @@ intptr_t Simulator::WriteExclusiveW(uword addr, intptr_t value, Instr* instr) {
int32_t old_value = static_cast<uint32_t>(exclusive_access_value_);
ClearExclusive();
if ((random_.NextUInt32() % 16) == 0) {
return 1; // Spurious failure.
}
auto atomic_addr = reinterpret_cast<RelaxedAtomic<int32_t>*>(addr);
if (atomic_addr->compare_exchange_weak(old_value, value)) {
return 0; // Success.
@ -1508,7 +1512,7 @@ void Simulator::ClobberVolatileRegisters() {
for (intptr_t i = 0; i < kNumberOfCpuRegisters; i++) {
if ((kAbiVolatileCpuRegs & (1 << i)) != 0) {
registers_[i] = icount_;
registers_[i] = random_.NextUInt32();
}
}

View file

@ -17,6 +17,7 @@
#endif
#include "vm/constants.h"
#include "vm/random.h"
namespace dart {
@ -158,6 +159,7 @@ class Simulator {
bool pc_modified_;
uint64_t icount_;
static int32_t flag_stop_sim_at_;
Random random_;
SimulatorSetjmpBuffer* last_setjmp_buffer_;
// Registered breakpoints.

View file

@ -1219,6 +1219,10 @@ intptr_t Simulator::WriteExclusiveX(uword addr, intptr_t value, Instr* instr) {
int64_t old_value = exclusive_access_value_;
ClearExclusive();
if ((random_.NextUInt32() % 16) == 0) {
return 1; // Suprious failure.
}
auto atomic_addr = reinterpret_cast<RelaxedAtomic<int64_t>*>(addr);
if (atomic_addr->compare_exchange_weak(old_value, value)) {
return 0; // Success.
@ -1237,6 +1241,10 @@ intptr_t Simulator::WriteExclusiveW(uword addr, intptr_t value, Instr* instr) {
int32_t old_value = static_cast<uint32_t>(exclusive_access_value_);
ClearExclusive();
if ((random_.NextUInt32() % 16) == 0) {
return 1; // Spurious failure.
}
auto atomic_addr = reinterpret_cast<RelaxedAtomic<int32_t>*>(addr);
if (atomic_addr->compare_exchange_weak(old_value, value)) {
return 0; // Success.
@ -1763,7 +1771,7 @@ void Simulator::ClobberVolatileRegisters() {
for (intptr_t i = 0; i < kNumberOfCpuRegisters; i++) {
if ((kAbiVolatileCpuRegs & (1 << i)) != 0) {
registers_[i] = icount_;
registers_[i] = random_.NextUInt64();
}
}

View file

@ -17,6 +17,7 @@
#endif
#include "vm/constants.h"
#include "vm/random.h"
namespace dart {
@ -142,6 +143,7 @@ class Simulator {
bool pc_modified_;
uint64_t icount_;
static int64_t flag_stop_sim_at_;
Random random_;
SimulatorSetjmpBuffer* last_setjmp_buffer_;
// Registered breakpoints.

View file

@ -2131,6 +2131,10 @@ void Simulator::InterpretSC(Instr instr) {
set_xreg(instr.rd(), 1);
return;
}
if ((random_.NextUInt32() % 16) == 0) { // Spurious failure.
set_xreg(instr.rd(), 1);
return;
}
type expected = reserved_value_;
type desired = get_xreg(instr.rs2());
bool success =

View file

@ -19,7 +19,6 @@ class Mutex;
class SimulatorSetjmpBuffer;
class Thread;
// TODO(riscv): Introduce random LR/SC failures.
// TODO(riscv): Dynamic rounding mode and other FSCR state.
class Simulator {
public: