Bug 1125837 - smush SimulatorRuntime into Simulator. r=jandem

This commit is contained in:
Lars T Hansen 2015-01-30 09:15:16 +01:00
Родитель 1e523dd28b
Коммит 2e7f093f9d
7 изменённых файлов: 198 добавлений и 387 удалений

Просмотреть файл

@ -352,98 +352,20 @@ class CachePage
char validity_map_[kValidityMapSize]; // One byte per line.
};
class Redirection;
class SimulatorRuntime
{
friend class AutoLockSimulatorRuntime;
Redirection *redirection_;
// ICache checking.
struct ICacheHasher {
typedef void *Key;
typedef void *Lookup;
static HashNumber hash(const Lookup &l);
static bool match(const Key &k, const Lookup &l);
};
public:
typedef HashMap<void *, CachePage *, ICacheHasher, SystemAllocPolicy> ICacheMap;
protected:
ICacheMap icache_;
// Synchronize access between main thread and compilation threads.
PRLock *lock_;
mozilla::DebugOnly<PRThread *> lockOwner_;
public:
SimulatorRuntime()
: redirection_(nullptr),
lock_(nullptr),
lockOwner_(nullptr)
{}
~SimulatorRuntime();
bool init() {
lock_ = PR_NewLock();
if (!lock_)
return false;
if (!icache_.init())
return false;
return true;
}
ICacheMap &icache() {
MOZ_ASSERT(lockOwner_ == PR_GetCurrentThread());
return icache_;
}
Redirection *redirection() const {
MOZ_ASSERT(lockOwner_ == PR_GetCurrentThread());
return redirection_;
}
void setRedirection(js::jit::Redirection *redirection) {
MOZ_ASSERT(lockOwner_ == PR_GetCurrentThread());
redirection_ = redirection;
}
};
class AutoLockSimulatorRuntime
{
protected:
SimulatorRuntime *srt_;
public:
AutoLockSimulatorRuntime(SimulatorRuntime *srt)
: srt_(srt)
{
PR_Lock(srt_->lock_);
MOZ_ASSERT(!srt_->lockOwner_);
#ifdef DEBUG
srt_->lockOwner_ = PR_GetCurrentThread();
#endif
}
~AutoLockSimulatorRuntime() {
MOZ_ASSERT(srt_->lockOwner_ == PR_GetCurrentThread());
srt_->lockOwner_ = nullptr;
PR_Unlock(srt_->lock_);
}
};
bool Simulator::ICacheCheckingEnabled = false;
int64_t Simulator::StopSimAt = -1L;
SimulatorRuntime *
CreateSimulatorRuntime()
Simulator *
Simulator::Create()
{
SimulatorRuntime *srt = js_new<SimulatorRuntime>();
if (!srt)
Simulator *sim = js_new<Simulator>();
if (!sim)
return nullptr;
if (!srt->init()) {
js_delete(srt);
return nullptr;
if (!sim->icache_.init()) {
js_delete(sim);
return false;
}
if (getenv("ARM_SIM_ICACHE_CHECKS"))
@ -456,13 +378,13 @@ CreateSimulatorRuntime()
Simulator::StopSimAt = stopAt;
}
return srt;
return sim;
}
void
DestroySimulatorRuntime(SimulatorRuntime *srt)
Simulator::Destroy(Simulator *sim)
{
js_delete(srt);
js_delete(sim);
}
// The ArmDebugger class is used by the simulator while debugging simulated ARM
@ -1000,11 +922,11 @@ AllOnOnePage(uintptr_t start, int size)
}
static CachePage *
GetCachePage(SimulatorRuntime::ICacheMap &i_cache, void *page)
GetCachePage(Simulator::ICacheMap &i_cache, void *page)
{
MOZ_ASSERT(Simulator::ICacheCheckingEnabled);
SimulatorRuntime::ICacheMap::AddPtr p = i_cache.lookupForAdd(page);
Simulator::ICacheMap::AddPtr p = i_cache.lookupForAdd(page);
if (p)
return p->value();
@ -1016,7 +938,7 @@ GetCachePage(SimulatorRuntime::ICacheMap &i_cache, void *page)
// Flush from start up to and not including start + size.
static void
FlushOnePage(SimulatorRuntime::ICacheMap &i_cache, intptr_t start, int size)
FlushOnePage(Simulator::ICacheMap &i_cache, intptr_t start, int size)
{
MOZ_ASSERT(size <= CachePage::kPageSize);
MOZ_ASSERT(AllOnOnePage(start, size - 1));
@ -1031,7 +953,7 @@ FlushOnePage(SimulatorRuntime::ICacheMap &i_cache, intptr_t start, int size)
}
static void
FlushICache(SimulatorRuntime::ICacheMap &i_cache, void *start_addr, size_t size)
FlushICache(Simulator::ICacheMap &i_cache, void *start_addr, size_t size)
{
intptr_t start = reinterpret_cast<intptr_t>(start_addr);
int intra_line = (start & CachePage::kLineMask);
@ -1052,7 +974,7 @@ FlushICache(SimulatorRuntime::ICacheMap &i_cache, void *start_addr, size_t size)
}
static void
CheckICache(SimulatorRuntime::ICacheMap &i_cache, SimInstruction *instr)
CheckICache(Simulator::ICacheMap &i_cache, SimInstruction *instr)
{
intptr_t address = reinterpret_cast<intptr_t>(instr);
void *page = reinterpret_cast<void*>(address & (~CachePage::kPageMask));
@ -1075,13 +997,13 @@ CheckICache(SimulatorRuntime::ICacheMap &i_cache, SimInstruction *instr)
}
HashNumber
SimulatorRuntime::ICacheHasher::hash(const Lookup &l)
Simulator::ICacheHasher::hash(const Lookup &l)
{
return static_cast<uint32_t>(reinterpret_cast<uintptr_t>(l)) >> 2;
}
bool
SimulatorRuntime::ICacheHasher::match(const Key &k, const Lookup &l)
Simulator::ICacheHasher::match(const Key &k, const Lookup &l)
{
MOZ_ASSERT((reinterpret_cast<intptr_t>(k) & CachePage::kPageMask) == 0);
MOZ_ASSERT((reinterpret_cast<intptr_t>(l) & CachePage::kPageMask) == 0);
@ -1101,30 +1023,24 @@ Simulator::FlushICache(void *start_addr, size_t size)
JitSpewCont(JitSpew_CacheFlush, "[%p %zx]", start_addr, size);
if (!Simulator::ICacheCheckingEnabled)
return;
SimulatorRuntime *srt = TlsPerThreadData.get()->simulatorRuntime();
AutoLockSimulatorRuntime alsr(srt);
js::jit::FlushICache(srt->icache(), start_addr, size);
js::jit::FlushICache(Simulator::Current()->icache(), start_addr, size);
}
Simulator::~Simulator()
{
js_free(stack_);
}
Simulator::Simulator(SimulatorRuntime *srt)
: srt_(srt)
Simulator::Simulator()
{
// Set up simulator support first. Some of this information is needed to
// setup the architecture state.
// Allocate 2MB for the stack. Note that we will only use 1MB, see also
// Simulator::stackLimit().
// Allocate 2MB for the stack. Note that we will only use 1MB, see below.
static const size_t stackSize = 2 * 1024*1024;
stack_ = reinterpret_cast<char*>(js_malloc(stackSize));
if (!stack_) {
MOZ_ReportAssertionFailure("[unhandlable oom] Simulator stack", __FILE__, __LINE__);
MOZ_CRASH();
}
// Leave a safety margin of 1MB to prevent overrunning the stack when
// pushing values (total stack size is 2MB).
stackLimit_ = reinterpret_cast<uintptr_t>(stack_) + 1024 * 1024;
pc_modified_ = false;
icount_ = 0L;
resume_pc_ = 0;
@ -1172,6 +1088,8 @@ Simulator::Simulator(SimulatorRuntime *srt)
registers_[lr] = bad_lr;
lastDebuggerInput_ = nullptr;
redirection_ = nullptr;
}
// When the generated code calls a VM function (masm.callWithABI) we need to
@ -1182,18 +1100,18 @@ Simulator::Simulator(SimulatorRuntime *srt)
// offset from the svc instruction so the simulator knows what to call.
class Redirection
{
friend class SimulatorRuntime;
friend class Simulator;
Redirection(void *nativeFunction, ABIFunctionType type, SimulatorRuntime *srt)
Redirection(void *nativeFunction, ABIFunctionType type, Simulator *sim)
: nativeFunction_(nativeFunction),
swiInstruction_(Assembler::AL | (0xf * (1 << 24)) | kCallRtRedirected),
type_(type),
next_(nullptr)
{
next_ = srt->redirection();
next_ = sim->redirection();
if (Simulator::ICacheCheckingEnabled)
FlushICache(srt->icache(), addressOfSwiInstruction(), SimInstruction::kInstrSize);
srt->setRedirection(this);
FlushICache(sim->icache(), addressOfSwiInstruction(), SimInstruction::kInstrSize);
sim->setRedirection(this);
}
public:
@ -1202,13 +1120,8 @@ class Redirection
ABIFunctionType type() const { return type_; }
static Redirection *Get(void *nativeFunction, ABIFunctionType type) {
PerThreadData *pt = TlsPerThreadData.get();
SimulatorRuntime *srt = pt->simulatorRuntime();
AutoLockSimulatorRuntime alsr(srt);
MOZ_ASSERT_IF(pt->simulator(), pt->simulator()->srt_ == srt);
Redirection *current = srt->redirection();
Simulator *sim = Simulator::Current();
Redirection *current = sim->redirection();
for (; current != nullptr; current = current->next_) {
if (current->nativeFunction_ == nativeFunction) {
MOZ_ASSERT(current->type() == type);
@ -1222,7 +1135,7 @@ class Redirection
__FILE__, __LINE__);
MOZ_CRASH();
}
new(redir) Redirection(nativeFunction, type, srt);
new(redir) Redirection(nativeFunction, type, sim);
return redir;
}
@ -1239,23 +1152,22 @@ class Redirection
Redirection *next_;
};
/* static */ void *
Simulator::RedirectNativeFunction(void *nativeFunction, ABIFunctionType type)
{
Redirection *redirection = Redirection::Get(nativeFunction, type);
return redirection->addressOfSwiInstruction();
}
SimulatorRuntime::~SimulatorRuntime()
Simulator::~Simulator()
{
js_free(stack_);
Redirection *r = redirection_;
while (r) {
Redirection *next = r->next_;
js_delete(r);
r = next;
}
if (lock_)
PR_DestroyLock(lock_);
}
/* static */ void *
Simulator::RedirectNativeFunction(void *nativeFunction, ABIFunctionType type)
{
Redirection *redirection = Redirection::Get(nativeFunction, type);
return redirection->addressOfSwiInstruction();
}
// Sets the register in the architecture state. It will also deal with updating
@ -1630,9 +1542,13 @@ Simulator::writeDW(int32_t addr, int32_t value1, int32_t value2)
uintptr_t
Simulator::stackLimit() const
{
// Leave a safety margin of 1MB to prevent overrunning the stack when
// pushing values (total stack size is 2MB).
return reinterpret_cast<uintptr_t>(stack_) + 1024 * 1024;
return stackLimit_;
}
uintptr_t *
Simulator::addressOfStackLimit()
{
return &stackLimit_;
}
bool
@ -4170,10 +4086,8 @@ Simulator::decodeSpecialCondition(SimInstruction *instr)
void
Simulator::instructionDecode(SimInstruction *instr)
{
if (Simulator::ICacheCheckingEnabled) {
AutoLockSimulatorRuntime alsr(srt_);
CheckICache(srt_->icache(), instr);
}
if (Simulator::ICacheCheckingEnabled)
CheckICache(icache(), instr);
pc_modified_ = false;
@ -4441,14 +4355,7 @@ Simulator::call(uint8_t* entry, int argument_count, ...)
Simulator *
Simulator::Current()
{
PerThreadData *pt = TlsPerThreadData.get();
Simulator *sim = pt->simulator();
if (!sim) {
sim = js_new<Simulator>(pt->simulatorRuntime());
pt->setSimulator(sim);
}
return sim;
return TlsPerThreadData.get()->simulator();
}
} // namespace jit
@ -4460,46 +4367,14 @@ JSRuntime::simulator() const
return simulator_;
}
uintptr_t *
JSRuntime::addressOfSimulatorStackLimit()
{
return simulator_->addressOfStackLimit();
}
js::jit::Simulator *
js::PerThreadData::simulator() const
{
return runtime_->simulator();
}
void
JSRuntime::setSimulator(js::jit::Simulator *sim)
{
simulator_ = sim;
simulatorStackLimit_ = sim->stackLimit();
}
void
js::PerThreadData::setSimulator(js::jit::Simulator *sim)
{
runtime_->setSimulator(sim);
}
uintptr_t *
JSRuntime::addressOfSimulatorStackLimit()
{
return &simulatorStackLimit_;
}
js::jit::SimulatorRuntime *
js::PerThreadData::simulatorRuntime() const
{
return runtime_->simulatorRuntime();
}
js::jit::SimulatorRuntime *
JSRuntime::simulatorRuntime() const
{
return simulatorRuntime_;
}
void
JSRuntime::setSimulatorRuntime(js::jit::SimulatorRuntime *srt)
{
MOZ_ASSERT(!simulatorRuntime_);
simulatorRuntime_ = srt;
}

Просмотреть файл

@ -38,9 +38,8 @@ namespace js {
namespace jit {
class Simulator;
class SimulatorRuntime;
SimulatorRuntime *CreateSimulatorRuntime();
void DestroySimulatorRuntime(SimulatorRuntime *srt);
class Redirection;
class CachePage;
// When the SingleStepCallback is called, the simulator is about to execute
// sim->get_pc() and the current machine state represents the completed
@ -95,7 +94,11 @@ class Simulator
num_q_registers = 16
};
explicit Simulator(SimulatorRuntime *srt);
static Simulator *Create();
static void Destroy(Simulator *simulator);
// Constructor/destructor are for internal use only; use the static methods above.
Simulator();
~Simulator();
// The currently executing Simulator instance. Potentially there can be one
@ -106,6 +109,8 @@ class Simulator
return Simulator::Current()->stackLimit();
}
uintptr_t *addressOfStackLimit();
// Accessors for register state. Reading the pc value adheres to the ARM
// architecture specification and is off by a 8 from the currently executing
// instruction.
@ -333,6 +338,7 @@ class Simulator
// Simulator support.
char *stack_;
uintptr_t stackLimit_;
bool pc_modified_;
int64_t icount_;
@ -350,8 +356,6 @@ class Simulator
SingleStepCallback single_step_callback_;
void *single_step_callback_arg_;
SimulatorRuntime *srt_;
// A stop is watched if its code is less than kNumOfWatchedStops.
// Only watched stops support enabling/disabling and the counter feature.
static const uint32_t kNumOfWatchedStops = 256;
@ -374,6 +378,35 @@ class Simulator
return icount_;
}
private:
Redirection *redirection_;
// ICache checking.
struct ICacheHasher {
typedef void *Key;
typedef void *Lookup;
static HashNumber hash(const Lookup &l);
static bool match(const Key &k, const Lookup &l);
};
public:
typedef HashMap<void *, CachePage *, ICacheHasher, SystemAllocPolicy> ICacheMap;
protected:
ICacheMap icache_;
public:
ICacheMap &icache() {
return icache_;
}
Redirection *redirection() const {
return redirection_;
}
void setRedirection(js::jit::Redirection *redirection) {
redirection_ = redirection;
}
};
#define JS_CHECK_SIMULATOR_RECURSION_WITH_EXTRA(cx, extra, onerror) \

Просмотреть файл

@ -486,96 +486,20 @@ class CachePage {
char validity_map_[kValidityMapSize]; // One byte per line.
};
class Redirection;
class SimulatorRuntime
{
friend class AutoLockSimulatorRuntime;
Redirection *redirection_;
// ICache checking.
struct ICacheHasher {
typedef void *Key;
typedef void *Lookup;
static HashNumber hash(const Lookup &l);
static bool match(const Key &k, const Lookup &l);
};
public:
typedef HashMap<void *, CachePage *, ICacheHasher, SystemAllocPolicy> ICacheMap;
protected:
ICacheMap icache_;
// Synchronize access between main thread and compilation threads.
PRLock *lock_;
mozilla::DebugOnly<PRThread *> lockOwner_;
public:
SimulatorRuntime()
: redirection_(nullptr),
lock_(nullptr),
lockOwner_(nullptr) {}
~SimulatorRuntime();
bool init() {
lock_ = PR_NewLock();
if (!lock_)
return false;
if (!icache_.init())
return false;
return true;
}
ICacheMap &icache() {
MOZ_ASSERT(lockOwner_ == PR_GetCurrentThread());
return icache_;
}
Redirection *redirection() const {
MOZ_ASSERT(lockOwner_ == PR_GetCurrentThread());
return redirection_;
}
void setRedirection(js::jit::Redirection *redirection) {
MOZ_ASSERT(lockOwner_ == PR_GetCurrentThread());
redirection_ = redirection;
}
};
class AutoLockSimulatorRuntime
{
protected:
SimulatorRuntime *srt_;
public:
AutoLockSimulatorRuntime(SimulatorRuntime *srt)
: srt_(srt) {
PR_Lock(srt_->lock_);
MOZ_ASSERT(!srt_->lockOwner_);
#ifdef DEBUG
srt_->lockOwner_ = PR_GetCurrentThread();
#endif
}
~AutoLockSimulatorRuntime() {
MOZ_ASSERT(srt_->lockOwner_ == PR_GetCurrentThread());
srt_->lockOwner_ = nullptr;
PR_Unlock(srt_->lock_);
}
};
bool Simulator::ICacheCheckingEnabled = false;
int Simulator::StopSimAt = -1;
SimulatorRuntime *
CreateSimulatorRuntime()
Simulator *
Simulator::Create()
{
SimulatorRuntime *srt = js_new<SimulatorRuntime>();
if (!srt)
Simulator *sim = js_new<Simulator>();
if (!sim)
return nullptr;
if (!srt->init()) {
js_delete(srt);
return nullptr;
if (!sim->icache_.init()) {
js_delete(sim);
return false;
}
if (getenv("MIPS_SIM_ICACHE_CHECKS"))
@ -588,13 +512,13 @@ CreateSimulatorRuntime()
Simulator::StopSimAt = stopAt;
}
return srt;
return sim;
}
void
DestroySimulatorRuntime(SimulatorRuntime *srt)
Simulator::Destroy(Simulator *sim)
{
js_delete(srt);
js_delete(sim);
}
// The MipsDebugger class is used by the simulator while debugging simulated
@ -1193,9 +1117,9 @@ Simulator::setLastDebuggerInput(char *input)
}
static CachePage *
GetCachePage(SimulatorRuntime::ICacheMap &i_cache, void *page)
GetCachePage(Simulator::ICacheMap &i_cache, void *page)
{
SimulatorRuntime::ICacheMap::AddPtr p = i_cache.lookupForAdd(page);
Simulator::ICacheMap::AddPtr p = i_cache.lookupForAdd(page);
if (p)
return p->value();
@ -1207,7 +1131,7 @@ GetCachePage(SimulatorRuntime::ICacheMap &i_cache, void *page)
// Flush from start up to and not including start + size.
static void
FlushOnePage(SimulatorRuntime::ICacheMap &i_cache, intptr_t start, int size)
FlushOnePage(Simulator::ICacheMap &i_cache, intptr_t start, int size)
{
MOZ_ASSERT(size <= CachePage::kPageSize);
MOZ_ASSERT(AllOnOnePage(start, size - 1));
@ -1221,7 +1145,7 @@ FlushOnePage(SimulatorRuntime::ICacheMap &i_cache, intptr_t start, int size)
}
static void
FlushICache(SimulatorRuntime::ICacheMap &i_cache, void *start_addr, size_t size)
FlushICache(Simulator::ICacheMap &i_cache, void *start_addr, size_t size)
{
intptr_t start = reinterpret_cast<intptr_t>(start_addr);
int intra_line = (start & CachePage::kLineMask);
@ -1243,7 +1167,7 @@ FlushICache(SimulatorRuntime::ICacheMap &i_cache, void *start_addr, size_t size)
}
static void
CheckICache(SimulatorRuntime::ICacheMap &i_cache, SimInstruction *instr)
CheckICache(Simulator::ICacheMap &i_cache, SimInstruction *instr)
{
intptr_t address = reinterpret_cast<intptr_t>(instr);
void *page = reinterpret_cast<void*>(address & (~CachePage::kPageMask));
@ -1266,13 +1190,13 @@ CheckICache(SimulatorRuntime::ICacheMap &i_cache, SimInstruction *instr)
}
HashNumber
SimulatorRuntime::ICacheHasher::hash(const Lookup &l)
Simulator::ICacheHasher::hash(const Lookup &l)
{
return static_cast<uint32_t>(reinterpret_cast<uintptr_t>(l)) >> 2;
}
bool
SimulatorRuntime::ICacheHasher::match(const Key &k, const Lookup &l)
Simulator::ICacheHasher::match(const Key &k, const Lookup &l)
{
MOZ_ASSERT((reinterpret_cast<intptr_t>(k) & CachePage::kPageMask) == 0);
MOZ_ASSERT((reinterpret_cast<intptr_t>(l) & CachePage::kPageMask) == 0);
@ -1282,30 +1206,24 @@ SimulatorRuntime::ICacheHasher::match(const Key &k, const Lookup &l)
void
Simulator::FlushICache(void *start_addr, size_t size)
{
SimulatorRuntime *srt = TlsPerThreadData.get()->simulatorRuntime();
AutoLockSimulatorRuntime alsr(srt);
js::jit::FlushICache(srt->icache(), start_addr, size);
js::jit::FlushICache(Simulator::Current()->icache(), start_addr, size);
}
Simulator::~Simulator()
{
js_free(stack_);
}
Simulator::Simulator(SimulatorRuntime *srt)
: srt_(srt)
Simulator::Simulator()
{
// Set up simulator support first. Some of this information is needed to
// setup the architecture state.
// Allocate 2MB for the stack. Note that we will only use 1MB, see also
// Simulator::stackLimit().
// Allocate 2MB for the stack. Note that we will only use 1MB, see below.
static const size_t stackSize = 2 * 1024 * 1024;
stack_ = static_cast<char*>(js_malloc(stackSize));
if (!stack_) {
MOZ_ReportAssertionFailure("[unhandlable oom] Simulator stack", __FILE__, __LINE__);
MOZ_CRASH();
}
// Leave a safety margin of 1MB to prevent overrunning the stack when
// pushing values (total stack size is 2MB).
stackLimit_ = reinterpret_cast<uintptr_t>(stack_) + 1024 * 1024;
pc_modified_ = false;
icount_ = 0;
break_count_ = 0;
@ -1336,6 +1254,8 @@ Simulator::Simulator(SimulatorRuntime *srt)
exceptions[i] = 0;
lastDebuggerInput_ = nullptr;
redirection_ = nullptr;
}
// When the generated code calls an external reference we need to catch that in
@ -1347,18 +1267,18 @@ Simulator::Simulator(SimulatorRuntime *srt)
// offset from the swi instruction so the simulator knows what to call.
class Redirection
{
friend class SimulatorRuntime;
friend class Simulator;
Redirection(void* nativeFunction, ABIFunctionType type, SimulatorRuntime *srt)
Redirection(void* nativeFunction, ABIFunctionType type, Simulator *sim)
: nativeFunction_(nativeFunction),
swiInstruction_(kCallRedirInstr),
type_(type),
next_(nullptr)
{
next_ = srt->redirection();
next_ = sim->redirection();
if (Simulator::ICacheCheckingEnabled)
FlushICache(srt->icache(), addressOfSwiInstruction(), SimInstruction::kInstrSize);
srt->setRedirection(this);
FlushICache(sim->icache(), addressOfSwiInstruction(), SimInstruction::kInstrSize);
sim->setRedirection(this);
}
public:
@ -1367,13 +1287,8 @@ class Redirection
ABIFunctionType type() const { return type_; }
static Redirection *Get(void *nativeFunction, ABIFunctionType type) {
PerThreadData *pt = TlsPerThreadData.get();
SimulatorRuntime *srt = pt->simulatorRuntime();
AutoLockSimulatorRuntime alsr(srt);
MOZ_ASSERT_IF(pt->simulator(), pt->simulator()->srt_ == srt);
Redirection *current = srt->redirection();
Simulator *sim = Simulator::Current();
Redirection *current = sim->redirection();
for (; current != nullptr; current = current->next_) {
if (current->nativeFunction_ == nativeFunction) {
MOZ_ASSERT(current->type() == type);
@ -1387,7 +1302,7 @@ class Redirection
__FILE__, __LINE__);
MOZ_CRASH();
}
new(redir) Redirection(nativeFunction, type, srt);
new(redir) Redirection(nativeFunction, type, sim);
return redir;
}
@ -1404,6 +1319,17 @@ class Redirection
Redirection *next_;
};
Simulator::~Simulator()
{
js_free(stack_);
Redirection *r = redirection_;
while (r) {
Redirection *next = r->next_;
js_delete(r);
r = next;
}
}
/* static */ void *
Simulator::RedirectNativeFunction(void *nativeFunction, ABIFunctionType type)
{
@ -1411,30 +1337,11 @@ Simulator::RedirectNativeFunction(void *nativeFunction, ABIFunctionType type)
return redirection->addressOfSwiInstruction();
}
SimulatorRuntime::~SimulatorRuntime()
{
Redirection *r = redirection_;
while (r) {
Redirection *next = r->next_;
js_delete(r);
r = next;
}
if (lock_)
PR_DestroyLock(lock_);
}
// Get the active Simulator for the current thread.
Simulator *
Simulator::Current()
{
PerThreadData *pt = TlsPerThreadData.get();
Simulator *sim = pt->simulator();
if (!sim) {
sim = js_new<Simulator>(pt->simulatorRuntime());
pt->setSimulator(sim);
}
return sim;
return TlsPerThreadData.get()->simulator();
}
// Sets the register in the architecture state. It will also deal with updating
@ -1808,9 +1715,13 @@ Simulator::writeB(uint32_t addr, int8_t value)
uintptr_t
Simulator::stackLimit() const
{
// Leave a safety margin of 1MB to prevent overrunning the stack when
// pushing values (total stack size is 2MB).
return reinterpret_cast<uintptr_t>(stack_) + 1024 * 1024;
return stackLimit_;
}
uintptr_t *
Simulator::addressOfStackLimit()
{
return &stackLimit_;
}
bool
@ -3302,10 +3213,8 @@ Simulator::decodeTypeJump(SimInstruction *instr)
void
Simulator::instructionDecode(SimInstruction *instr)
{
if (Simulator::ICacheCheckingEnabled) {
AutoLockSimulatorRuntime alsr(srt_);
CheckICache(srt_->icache(), instr);
}
if (Simulator::ICacheCheckingEnabled)
CheckICache(icache(), instr);
pc_modified_ = false;
switch (instr->instructionType()) {
@ -3516,40 +3425,9 @@ js::PerThreadData::simulator() const
return runtime_->simulator();
}
void
JSRuntime::setSimulator(js::jit::Simulator *sim)
{
simulator_ = sim;
simulatorStackLimit_ = sim->stackLimit();
}
void
js::PerThreadData::setSimulator(js::jit::Simulator *sim)
{
runtime_->setSimulator(sim);
}
uintptr_t *
JSRuntime::addressOfSimulatorStackLimit()
{
return &simulatorStackLimit_;
return simulator_->addressOfStackLimit();
}
js::jit::SimulatorRuntime *
js::PerThreadData::simulatorRuntime() const
{
return runtime_->simulatorRuntime();
}
js::jit::SimulatorRuntime *
JSRuntime::simulatorRuntime() const
{
return simulatorRuntime_;
}
void
JSRuntime::setSimulatorRuntime(js::jit::SimulatorRuntime *srt)
{
MOZ_ASSERT(!simulatorRuntime_);
simulatorRuntime_ = srt;
}

Просмотреть файл

@ -36,9 +36,9 @@
namespace js {
namespace jit {
class SimulatorRuntime;
SimulatorRuntime *CreateSimulatorRuntime();
void DestroySimulatorRuntime(SimulatorRuntime *srt);
class Simulator;
class Redirection;
class CachePage;
const intptr_t kPointerAlignment = 4;
const intptr_t kPointerAlignmentMask = kPointerAlignment - 1;
@ -137,7 +137,11 @@ class Simulator {
kNumFPURegisters
};
explicit Simulator(SimulatorRuntime *srt);
static Simulator *Create();
static void Destroy(Simulator *simulator);
// Constructor/destructor are for internal use only; use the static methods above.
Simulator();
~Simulator();
// The currently executing Simulator instance. Potentially there can be one
@ -148,6 +152,8 @@ class Simulator {
return Simulator::Current()->stackLimit();
}
uintptr_t *addressOfStackLimit();
// Accessors for register state. Reading the pc value adheres to the MIPS
// architecture specification and is off by a 8 from the currently executing
// instruction.
@ -315,6 +321,7 @@ class Simulator {
// Simulator support.
char *stack_;
uintptr_t stackLimit_;
bool pc_modified_;
int icount_;
int break_count_;
@ -328,8 +335,6 @@ class Simulator {
SimInstruction *break_pc_;
Instr break_instr_;
SimulatorRuntime *srt_;
// A stop is watched if its code is less than kNumOfWatchedStops.
// Only watched stops support enabling/disabling and the counter feature.
static const uint32_t kNumOfWatchedStops = 256;
@ -347,6 +352,36 @@ class Simulator {
char *desc_;
};
StopCountAndDesc watchedStops_[kNumOfWatchedStops];
private:
Redirection *redirection_;
// ICache checking.
struct ICacheHasher {
typedef void *Key;
typedef void *Lookup;
static HashNumber hash(const Lookup &l);
static bool match(const Key &k, const Lookup &l);
};
public:
typedef HashMap<void *, CachePage *, ICacheHasher, SystemAllocPolicy> ICacheMap;
protected:
ICacheMap icache_;
public:
ICacheMap &icache() {
return icache_;
}
Redirection *redirection() const {
return redirection_;
}
void setRedirection(js::jit::Redirection *redirection) {
redirection_ = redirection;
}
};
#define JS_CHECK_SIMULATOR_RECURSION_WITH_EXTRA(cx, extra, onerror) \

Просмотреть файл

@ -1191,8 +1191,9 @@ ExclusiveContext::stackLimitAddressForJitCode(StackKind kind)
{
#if defined(JS_ARM_SIMULATOR) || defined(JS_MIPS_SIMULATOR)
return runtime_->addressOfSimulatorStackLimit();
#endif
#else
return stackLimitAddress(kind);
#endif
}
JSVersion

Просмотреть файл

@ -158,8 +158,6 @@ JSRuntime::JSRuntime(JSRuntime *parentRuntime)
gcInitialized(false),
#if defined(JS_ARM_SIMULATOR) || defined(JS_MIPS_SIMULATOR)
simulator_(nullptr),
simulatorStackLimit_(0),
simulatorRuntime_(nullptr),
#endif
scriptAndCountsVector(nullptr),
NaNValue(DoubleNaNValue()),
@ -318,8 +316,8 @@ JSRuntime::init(uint32_t maxbytes, uint32_t maxNurseryBytes)
dateTimeInfo.updateTimeZoneAdjustment();
#if defined(JS_ARM_SIMULATOR) || defined(JS_MIPS_SIMULATOR)
simulatorRuntime_ = js::jit::CreateSimulatorRuntime();
if (!simulatorRuntime_)
simulator_ = js::jit::Simulator::Create();
if (!simulator_)
return false;
#endif
@ -435,8 +433,7 @@ JSRuntime::~JSRuntime()
gc.nursery.disable();
#if defined(JS_ARM_SIMULATOR) || defined(JS_MIPS_SIMULATOR)
js::jit::DestroySimulatorRuntime(simulatorRuntime_);
js_delete(simulator_);
js::jit::Simulator::Destroy(simulator_);
#endif
DebugOnly<size_t> oldCount = liveRuntimesCount--;

Просмотреть файл

@ -85,7 +85,6 @@ class JitRuntime;
class JitActivation;
struct PcScriptCache;
class Simulator;
class SimulatorRuntime;
struct AutoFlushICache;
class CompileRuntime;
}
@ -562,8 +561,6 @@ class PerThreadData : public PerThreadDataFriendFields
#if defined(JS_ARM_SIMULATOR) || defined(JS_MIPS_SIMULATOR)
js::jit::Simulator *simulator() const;
void setSimulator(js::jit::Simulator *sim);
js::jit::SimulatorRuntime *simulatorRuntime() const;
#endif
};
@ -959,8 +956,6 @@ struct JSRuntime : public JS::shadow::Runtime,
#if defined(JS_ARM_SIMULATOR) || defined(JS_MIPS_SIMULATOR)
js::jit::Simulator *simulator_;
uintptr_t simulatorStackLimit_;
js::jit::SimulatorRuntime *simulatorRuntime_;
#endif
public:
@ -970,10 +965,7 @@ struct JSRuntime : public JS::shadow::Runtime,
#if defined(JS_ARM_SIMULATOR) || defined(JS_MIPS_SIMULATOR)
js::jit::Simulator *simulator() const;
void setSimulator(js::jit::Simulator *sim);
uintptr_t *addressOfSimulatorStackLimit();
js::jit::SimulatorRuntime *simulatorRuntime() const;
void setSimulatorRuntime(js::jit::SimulatorRuntime *srt);
#endif
/* Strong references on scripts held for PCCount profiling API. */