diff --git a/js/src/jit/mips/Simulator-mips.cpp b/js/src/jit/mips/Simulator-mips.cpp index f6c4a2b7327..cfe6efb2c88 100644 --- a/js/src/jit/mips/Simulator-mips.cpp +++ b/js/src/jit/mips/Simulator-mips.cpp @@ -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(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(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(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(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(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(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 diff --git a/js/src/jit/mips/Simulator-mips.h b/js/src/jit/mips/Simulator-mips.h index d9e1d0eb1d2..4c98bce14fd 100644 --- a/js/src/jit/mips/Simulator-mips.h +++ b/js/src/jit/mips/Simulator-mips.h @@ -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);