Commit 6525976b authored by Junliang Yan's avatar Junliang Yan Committed by Commit Bot

PPC: fix simulator on race condition

R=joransiu@ca.ibm.com

Change-Id: I7d8f430df2f1f35145df7ba2326b3149d3193a60
Reviewed-on: https://chromium-review.googlesource.com/c/1297487
Commit-Queue: Junliang Yan <jyan@ca.ibm.com>
Reviewed-by: 's avatarJoran Siu <joransiu@ca.ibm.com>
Cr-Commit-Position: refs/heads/master@{#57187}
parent 9bd6e601
This diff is collapsed.
......@@ -13,6 +13,8 @@
#define V8_PPC_SIMULATOR_PPC_H_
#include "src/allocation.h"
#include "src/base/lazy-instance.h"
#include "src/base/platform/mutex.h"
#if defined(USE_SIMULATOR)
// Running with a simulator.
......@@ -241,49 +243,61 @@ class Simulator : public SimulatorBase {
void PrintStopInfo(uint32_t code);
// Read and write memory.
inline uint8_t ReadBU(intptr_t addr);
inline uint8_t ReadExBU(intptr_t addr);
inline int8_t ReadB(intptr_t addr);
inline void WriteB(intptr_t addr, uint8_t value);
inline int WriteExB(intptr_t addr, uint8_t value);
inline void WriteB(intptr_t addr, int8_t value);
inline uint16_t ReadHU(intptr_t addr, Instruction* instr);
inline uint16_t ReadExHU(intptr_t addr, Instruction* instr);
inline int16_t ReadH(intptr_t addr, Instruction* instr);
// Note: Overloaded on the sign of the value.
inline void WriteH(intptr_t addr, uint16_t value, Instruction* instr);
inline int WriteExH(intptr_t addr, uint16_t value, Instruction* instr);
inline void WriteH(intptr_t addr, int16_t value, Instruction* instr);
inline uint32_t ReadWU(intptr_t addr, Instruction* instr);
inline uint32_t ReadExWU(intptr_t addr, Instruction* instr);
inline int32_t ReadW(intptr_t addr, Instruction* instr);
inline void WriteW(intptr_t addr, uint32_t value, Instruction* instr);
inline int WriteExW(intptr_t addr, uint32_t value, Instruction* instr);
inline void WriteW(intptr_t addr, int32_t value, Instruction* instr);
intptr_t* ReadDW(intptr_t addr);
void WriteDW(intptr_t addr, int64_t value);
inline int WriteExDW(intptr_t addr, uint64_t value, Instruction* instr);
inline uint64_t ReadExDWU(intptr_t addr, Instruction* instr);
template <typename T>
inline void Read(uintptr_t address, T* value) {
base::MutexGuard lock_guard(&global_monitor_.Pointer()->mutex);
memcpy(value, reinterpret_cast<const char*>(address), sizeof(T));
}
template <typename T>
inline void ReadEx(uintptr_t address, T* value) {
base::MutexGuard lock_guard(&global_monitor_.Pointer()->mutex);
global_monitor_.Pointer()->NotifyLoadExcl(
address, static_cast<TransactionSize>(sizeof(T)),
isolate_->thread_id());
memcpy(value, reinterpret_cast<const char*>(address), sizeof(T));
}
template <typename T>
inline void Write(uintptr_t address, T value) {
base::MutexGuard lock_guard(&global_monitor_.Pointer()->mutex);
global_monitor_.Pointer()->NotifyStore(
address, static_cast<TransactionSize>(sizeof(T)),
isolate_->thread_id());
memcpy(reinterpret_cast<char*>(address), &value, sizeof(T));
}
template <typename T>
inline int32_t WriteEx(uintptr_t address, T value) {
base::MutexGuard lock_guard(&global_monitor_.Pointer()->mutex);
if (global_monitor_.Pointer()->NotifyStoreExcl(
address, static_cast<TransactionSize>(sizeof(T)),
isolate_->thread_id())) {
memcpy(reinterpret_cast<char*>(address), &value, sizeof(T));
return 0;
} else {
return 1;
}
}
#define RW_VAR_LIST(V) \
V(DWU, uint64_t) \
V(DW, int64_t) \
V(WU, uint32_t) \
V(W, int32_t) V(HU, uint16_t) V(H, int16_t) V(BU, uint8_t) V(B, int8_t)
#define GENERATE_RW_FUNC(size, type) \
inline type Read##size(uintptr_t addr); \
inline type ReadEx##size(uintptr_t addr); \
inline void Write##size(uintptr_t addr, type value); \
inline int32_t WriteEx##size(uintptr_t addr, type value);
RW_VAR_LIST(GENERATE_RW_FUNC);
#undef GENERATE_RW_FUNC
void Trace(Instruction* instr);
void SetCR0(intptr_t result, bool setSO = false);
void ExecuteBranchConditional(Instruction* instr, BCType type);
void ExecuteExt1(Instruction* instr);
bool ExecuteExt2_10bit_part1(Instruction* instr);
bool ExecuteExt2_10bit_part2(Instruction* instr);
bool ExecuteExt2_9bit_part1(Instruction* instr);
bool ExecuteExt2_9bit_part2(Instruction* instr);
void ExecuteExt2_5bit(Instruction* instr);
void ExecuteExt2(Instruction* instr);
void ExecuteExt3(Instruction* instr);
void ExecuteExt4(Instruction* instr);
#if V8_TARGET_ARCH_PPC64
void ExecuteExt5(Instruction* instr);
#endif
void ExecuteExt6(Instruction* instr);
void ExecuteGeneric(Instruction* instr);
void SetFPSCR(int bit) { fp_condition_reg_ |= (1 << (31 - bit)); }
......@@ -364,71 +378,31 @@ class Simulator : public SimulatorBase {
Byte = 1,
HalfWord = 2,
Word = 4,
};
class LocalMonitor {
public:
LocalMonitor();
// These functions manage the state machine for the local monitor, but do
// not actually perform loads and stores. NotifyStoreExcl only returns
// true if the exclusive store is allowed; the global monitor will still
// have to be checked to see whether the memory should be updated.
void NotifyLoad(int32_t addr);
void NotifyLoadExcl(int32_t addr, TransactionSize size);
void NotifyStore(int32_t addr);
bool NotifyStoreExcl(int32_t addr, TransactionSize size);
private:
void Clear();
MonitorAccess access_state_;
int32_t tagged_addr_;
TransactionSize size_;
DWord = 8,
};
class GlobalMonitor {
public:
GlobalMonitor();
class Processor {
public:
Processor();
private:
friend class GlobalMonitor;
// These functions manage the state machine for the global monitor, but do
// not actually perform loads and stores.
void Clear_Locked();
void NotifyLoadExcl_Locked(int32_t addr);
void NotifyStore_Locked(int32_t addr, bool is_requesting_processor);
bool NotifyStoreExcl_Locked(int32_t addr, bool is_requesting_processor);
MonitorAccess access_state_;
int32_t tagged_addr_;
Processor* next_;
Processor* prev_;
};
// Exposed so it can be accessed by Simulator::{Read,Write}Ex*.
base::Mutex mutex;
void NotifyLoadExcl_Locked(int32_t addr, Processor* processor);
void NotifyStore_Locked(int32_t addr, Processor* processor);
bool NotifyStoreExcl_Locked(int32_t addr, Processor* processor);
// Called when the simulator is destroyed.
void RemoveProcessor(Processor* processor);
void NotifyLoadExcl(uintptr_t addr, TransactionSize size,
ThreadId thread_id);
void NotifyStore(uintptr_t addr, TransactionSize size, ThreadId thread_id);
bool NotifyStoreExcl(uintptr_t addr, TransactionSize size,
ThreadId thread_id);
private:
bool IsProcessorInLinkedList_Locked(Processor* processor) const;
void PrependProcessor_Locked(Processor* processor);
void Clear();
Processor* head_;
MonitorAccess access_state_;
uintptr_t tagged_addr_;
TransactionSize size_;
ThreadId thread_id_;
};
LocalMonitor local_monitor_;
GlobalMonitor::Processor global_monitor_processor_;
static base::LazyInstance<GlobalMonitor>::type global_monitor_;
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment