Index: src/arm64/simulator-arm64.cc |
diff --git a/src/arm64/simulator-arm64.cc b/src/arm64/simulator-arm64.cc |
index 3c49b21e52d274373ce07b2c548162aa4d7f5981..83b4cf7ee8954f0838a8389eb3a5c971558eb5a2 100644 |
--- a/src/arm64/simulator-arm64.cc |
+++ b/src/arm64/simulator-arm64.cc |
@@ -55,9 +55,6 @@ |
TEXT_COLOUR clr_debug_message = FLAG_log_colour ? COLOUR(YELLOW) : ""; |
TEXT_COLOUR clr_printf = FLAG_log_colour ? COLOUR(GREEN) : ""; |
-// static |
-base::LazyInstance<Simulator::GlobalMonitor>::type Simulator::global_monitor_ = |
- LAZY_INSTANCE_INITIALIZER; |
// This is basically the same as PrintF, with a guard for FLAG_trace_sim. |
void Simulator::TraceSim(const char* format, ...) { |
@@ -432,7 +429,6 @@ |
Simulator::~Simulator() { |
- global_monitor_.Pointer()->RemoveProcessor(&global_monitor_processor_); |
delete[] reinterpret_cast<byte*>(stack_); |
if (FLAG_log_instruction_stats) { |
delete instrument_; |
@@ -1632,15 +1628,6 @@ |
uintptr_t address = LoadStoreAddress(addr_reg, offset, addrmode); |
uintptr_t stack = 0; |
- base::LockGuard<base::Mutex> lock_guard(&global_monitor_.Pointer()->mutex); |
- if (instr->IsLoad()) { |
- local_monitor_.NotifyLoad(address); |
- } else { |
- local_monitor_.NotifyStore(address); |
- global_monitor_.Pointer()->NotifyStore_Locked(address, |
- &global_monitor_processor_); |
- } |
- |
// Handle the writeback for stores before the store. On a CPU the writeback |
// and the store are atomic, but when running on the simulator it is possible |
// to be interrupted in between. The simulator is not thread safe and V8 does |
@@ -1743,19 +1730,6 @@ |
uintptr_t address2 = address + access_size; |
uintptr_t stack = 0; |
- base::LockGuard<base::Mutex> lock_guard(&global_monitor_.Pointer()->mutex); |
- if (instr->IsLoad()) { |
- local_monitor_.NotifyLoad(address); |
- local_monitor_.NotifyLoad(address2); |
- } else { |
- local_monitor_.NotifyStore(address); |
- local_monitor_.NotifyStore(address2); |
- global_monitor_.Pointer()->NotifyStore_Locked(address, |
- &global_monitor_processor_); |
- global_monitor_.Pointer()->NotifyStore_Locked(address2, |
- &global_monitor_processor_); |
- } |
- |
// Handle the writeback for stores before the store. On a CPU the writeback |
// and the store are atomic, but when running on the simulator it is possible |
// to be interrupted in between. The simulator is not thread safe and V8 does |
@@ -1879,9 +1853,6 @@ |
uintptr_t address = instr->LiteralAddress(); |
unsigned rt = instr->Rt(); |
- base::LockGuard<base::Mutex> lock_guard(&global_monitor_.Pointer()->mutex); |
- local_monitor_.NotifyLoad(address); |
- |
switch (instr->Mask(LoadLiteralMask)) { |
// Use _no_log variants to suppress the register trace (LOG_REGS, |
// LOG_FP_REGS), then print a more detailed log. |
@@ -1935,81 +1906,8 @@ |
} |
} |
-Simulator::TransactionSize Simulator::get_transaction_size(unsigned size) { |
- switch (size) { |
- case 0: |
- return TransactionSize::None; |
- case 1: |
- return TransactionSize::Byte; |
- case 2: |
- return TransactionSize::HalfWord; |
- case 4: |
- return TransactionSize::Word; |
- default: |
- UNREACHABLE(); |
- } |
- return TransactionSize::None; |
-} |
- |
void Simulator::VisitLoadStoreAcquireRelease(Instruction* instr) { |
- unsigned rs = instr->Rs(); |
- unsigned rt = instr->Rt(); |
- unsigned rn = instr->Rn(); |
- LoadStoreAcquireReleaseOp op = static_cast<LoadStoreAcquireReleaseOp>( |
- instr->Mask(LoadStoreAcquireReleaseMask)); |
- int32_t is_acquire_release = instr->LoadStoreXAcquireRelease(); |
- int32_t is_not_exclusive = instr->LoadStoreXNotExclusive(); |
- int32_t is_load = instr->LoadStoreXLoad(); |
- int32_t is_pair = instr->LoadStoreXPair(); |
- DCHECK_NE(is_acquire_release, 0); |
- DCHECK_EQ(is_not_exclusive, 0); // Non exclusive unimplemented. |
- DCHECK_EQ(is_pair, 0); // Pair unimplemented. |
- unsigned access_size = 1 << instr->LoadStoreXSizeLog2(); |
- uintptr_t address = LoadStoreAddress(rn, 0, AddrMode::Offset); |
- DCHECK(address % access_size == 0); |
- base::LockGuard<base::Mutex> lock_guard(&global_monitor_.Pointer()->mutex); |
- if (is_load != 0) { |
- local_monitor_.NotifyLoadExcl(address, get_transaction_size(access_size)); |
- global_monitor_.Pointer()->NotifyLoadExcl_Locked( |
- address, &global_monitor_processor_); |
- switch (op) { |
- case LDAXR_b: |
- set_wreg_no_log(rt, MemoryRead<uint8_t>(address)); |
- break; |
- case LDAXR_h: |
- set_wreg_no_log(rt, MemoryRead<uint16_t>(address)); |
- break; |
- case LDAXR_w: |
- set_wreg_no_log(rt, MemoryRead<uint32_t>(address)); |
- break; |
- default: |
- UNIMPLEMENTED(); |
- } |
- LogRead(address, access_size, rt); |
- } else { |
- if (local_monitor_.NotifyStoreExcl(address, |
- get_transaction_size(access_size)) && |
- global_monitor_.Pointer()->NotifyStoreExcl_Locked( |
- address, &global_monitor_processor_)) { |
- switch (op) { |
- case STLXR_b: |
- MemoryWrite<uint8_t>(address, wreg(rt)); |
- break; |
- case STLXR_h: |
- MemoryWrite<uint16_t>(address, wreg(rt)); |
- break; |
- case STLXR_w: |
- MemoryWrite<uint32_t>(address, wreg(rt)); |
- break; |
- default: |
- UNIMPLEMENTED(); |
- } |
- LogWrite(address, access_size, rt); |
- set_wreg(rs, 0); |
- } else { |
- set_wreg(rs, 1); |
- } |
- } |
+ // TODO(binji) |
} |
void Simulator::CheckMemoryAccess(uintptr_t address, uintptr_t stack) { |
@@ -3979,186 +3877,6 @@ |
delete[] format; |
} |
-Simulator::LocalMonitor::LocalMonitor() |
- : access_state_(MonitorAccess::Open), |
- tagged_addr_(0), |
- size_(TransactionSize::None) {} |
- |
-void Simulator::LocalMonitor::Clear() { |
- access_state_ = MonitorAccess::Open; |
- tagged_addr_ = 0; |
- size_ = TransactionSize::None; |
-} |
- |
-void Simulator::LocalMonitor::NotifyLoad(uintptr_t addr) { |
- if (access_state_ == MonitorAccess::Exclusive) { |
- // A non exclusive load could clear the local monitor. As a result, it's |
- // most strict to unconditionally clear the local monitor on load. |
- Clear(); |
- } |
-} |
- |
-void Simulator::LocalMonitor::NotifyLoadExcl(uintptr_t addr, |
- TransactionSize size) { |
- access_state_ = MonitorAccess::Exclusive; |
- tagged_addr_ = addr; |
- size_ = size; |
-} |
- |
-void Simulator::LocalMonitor::NotifyStore(uintptr_t addr) { |
- if (access_state_ == MonitorAccess::Exclusive) { |
- // A non exclusive store could clear the local monitor. As a result, it's |
- // most strict to unconditionally clear the local monitor on store. |
- Clear(); |
- } |
-} |
- |
-bool Simulator::LocalMonitor::NotifyStoreExcl(uintptr_t addr, |
- TransactionSize size) { |
- if (access_state_ == MonitorAccess::Exclusive) { |
- // It is allowed for a processor to require that the address matches |
- // exactly (B2.10.1), so this comparison does not mask addr. |
- if (addr == tagged_addr_ && size_ == size) { |
- Clear(); |
- return true; |
- } else { |
- // It is implementation-defined whether an exclusive store to a |
- // non-tagged address will update memory. As a result, it's most strict |
- // to unconditionally clear the local monitor. |
- Clear(); |
- return false; |
- } |
- } else { |
- DCHECK(access_state_ == MonitorAccess::Open); |
- return false; |
- } |
-} |
- |
-Simulator::GlobalMonitor::Processor::Processor() |
- : access_state_(MonitorAccess::Open), |
- tagged_addr_(0), |
- next_(nullptr), |
- prev_(nullptr), |
- failure_counter_(0) {} |
- |
-void Simulator::GlobalMonitor::Processor::Clear_Locked() { |
- access_state_ = MonitorAccess::Open; |
- tagged_addr_ = 0; |
-} |
- |
-void Simulator::GlobalMonitor::Processor::NotifyLoadExcl_Locked( |
- uintptr_t addr) { |
- access_state_ = MonitorAccess::Exclusive; |
- tagged_addr_ = addr; |
-} |
- |
-void Simulator::GlobalMonitor::Processor::NotifyStore_Locked( |
- uintptr_t addr, bool is_requesting_processor) { |
- if (access_state_ == MonitorAccess::Exclusive) { |
- // A non exclusive store could clear the global monitor. As a result, it's |
- // most strict to unconditionally clear global monitors on store. |
- Clear_Locked(); |
- } |
-} |
- |
-bool Simulator::GlobalMonitor::Processor::NotifyStoreExcl_Locked( |
- uintptr_t addr, bool is_requesting_processor) { |
- if (access_state_ == MonitorAccess::Exclusive) { |
- if (is_requesting_processor) { |
- // It is allowed for a processor to require that the address matches |
- // exactly (B2.10.2), so this comparison does not mask addr. |
- if (addr == tagged_addr_) { |
- Clear_Locked(); |
- // Introduce occasional stxr failures. This is to simulate the |
- // behavior of hardware, which can randomly fail due to background |
- // cache evictions. |
- if (failure_counter_++ >= kMaxFailureCounter) { |
- failure_counter_ = 0; |
- return false; |
- } else { |
- return true; |
- } |
- } |
- } else if ((addr & kExclusiveTaggedAddrMask) == |
- (tagged_addr_ & kExclusiveTaggedAddrMask)) { |
- // Check the masked addresses when responding to a successful lock by |
- // another processor so the implementation is more conservative (i.e. the |
- // granularity of locking is as large as possible.) |
- Clear_Locked(); |
- return false; |
- } |
- } |
- return false; |
-} |
- |
-Simulator::GlobalMonitor::GlobalMonitor() : head_(nullptr) {} |
- |
-void Simulator::GlobalMonitor::NotifyLoadExcl_Locked(uintptr_t addr, |
- Processor* processor) { |
- processor->NotifyLoadExcl_Locked(addr); |
- PrependProcessor_Locked(processor); |
-} |
- |
-void Simulator::GlobalMonitor::NotifyStore_Locked(uintptr_t addr, |
- Processor* processor) { |
- // Notify each processor of the store operation. |
- for (Processor* iter = head_; iter; iter = iter->next_) { |
- bool is_requesting_processor = iter == processor; |
- iter->NotifyStore_Locked(addr, is_requesting_processor); |
- } |
-} |
- |
-bool Simulator::GlobalMonitor::NotifyStoreExcl_Locked(uintptr_t addr, |
- Processor* processor) { |
- DCHECK(IsProcessorInLinkedList_Locked(processor)); |
- if (processor->NotifyStoreExcl_Locked(addr, true)) { |
- // Notify the other processors that this StoreExcl succeeded. |
- for (Processor* iter = head_; iter; iter = iter->next_) { |
- if (iter != processor) { |
- iter->NotifyStoreExcl_Locked(addr, false); |
- } |
- } |
- return true; |
- } else { |
- return false; |
- } |
-} |
- |
-bool Simulator::GlobalMonitor::IsProcessorInLinkedList_Locked( |
- Processor* processor) const { |
- return head_ == processor || processor->next_ || processor->prev_; |
-} |
- |
-void Simulator::GlobalMonitor::PrependProcessor_Locked(Processor* processor) { |
- if (IsProcessorInLinkedList_Locked(processor)) { |
- return; |
- } |
- |
- if (head_) { |
- head_->prev_ = processor; |
- } |
- processor->prev_ = nullptr; |
- processor->next_ = head_; |
- head_ = processor; |
-} |
- |
-void Simulator::GlobalMonitor::RemoveProcessor(Processor* processor) { |
- base::LockGuard<base::Mutex> lock_guard(&mutex); |
- if (!IsProcessorInLinkedList_Locked(processor)) { |
- return; |
- } |
- |
- if (processor->prev_) { |
- processor->prev_->next_ = processor->next_; |
- } else { |
- head_ = processor->next_; |
- } |
- if (processor->next_) { |
- processor->next_->prev_ = processor->prev_; |
- } |
- processor->prev_ = nullptr; |
- processor->next_ = nullptr; |
-} |
#endif // USE_SIMULATOR |