Bug 1128449 - MIPS simulator: split the constructor to allow OOM signaling. r=jandem

This commit is contained in:
Lars T Hansen 2015-02-04 10:34:34 +01:00
parent 5d731a4ee7
commit 26f9342a0e
2 changed files with 35 additions and 16 deletions

View File

@ -497,9 +497,9 @@ Simulator::Create()
if (!sim)
return nullptr;
if (!sim->icache_.init()) {
if (!sim->init()) {
js_delete(sim);
return false;
return nullptr;
}
if (getenv("MIPS_SIM_ICACHE_CHECKS"))
@ -1214,16 +1214,11 @@ 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 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;
// Note, allocation and anything that depends on allocated memory is
// deferred until init(), in order to handle OOM properly.
stack_ = nullptr;
stackLimit_ = 0;
pc_modified_ = false;
icount_ = 0;
break_count_ = 0;
@ -1241,10 +1236,6 @@ Simulator::Simulator()
}
FCSR_ = 0;
// The sp is initialized to point to the bottom (high address) of the
// allocated stack area. To be safe in potential stack underflows we leave
// some buffer below.
registers_[sp] = reinterpret_cast<int32_t>(stack_) + stackSize - 64;
// The ra and pc are initialized to a known bad value that will cause an
// access violation if the simulator ever tries to execute it.
registers_[pc] = bad_ra;
@ -1258,6 +1249,30 @@ Simulator::Simulator()
redirection_ = nullptr;
}
bool
Simulator::init()
{
if (!icache_.init())
return false;
// 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_)
return false;
// 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;
// The sp is initialized to point to the bottom (high address) of the
// allocated stack area. To be safe in potential stack underflows we leave
// some buffer below.
registers_[sp] = reinterpret_cast<int32_t>(stack_) + stackSize - 64;
return true;
}
// When the generated code calls an external reference we need to catch that in
// the simulator. The external reference will be a function compiled for the
// host architecture. We need to call that function instead of trying to

View File

@ -137,7 +137,9 @@ class Simulator {
kNumFPURegisters
};
// Returns nullptr on OOM.
static Simulator *Create();
static void Destroy(Simulator *simulator);
// Constructor/destructor are for internal use only; use the static methods above.
@ -224,6 +226,8 @@ class Simulator {
Unpredictable = 0xbadbeaf
};
bool init();
// Unsupported instructions use Format to print an error and stop execution.
void format(SimInstruction* instr, const char* format);