mirror of
https://github.com/dart-lang/sdk
synced 2024-10-06 15:39:54 +00:00
[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:
parent
f97004f639
commit
4242ff536f
|
@ -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.
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue