Bug 937540 part 5 - Use placement new syntax for MIR instructions. r=bhackett
authorJan de Mooij <jdemooij@mozilla.com>
Mon, 18 Nov 2013 00:00:07 +0100
changeset 155105 1fe0f523e64447dd0820f0724faed32bf676f21f
parent 155104 4f05b7cf7d11b0024b7aac83eb45d0884fde94e5
child 155106 56791576d7903213a0d63f36d724fb1ec7c622a6
push id36234
push userjandemooij@gmail.com
push dateSun, 17 Nov 2013 23:01:20 +0000
treeherdermozilla-inbound@1fe0f523e644 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbhackett
bugs937540
milestone28.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 937540 part 5 - Use placement new syntax for MIR instructions. r=bhackett
js/src/jit/AliasAnalysis.cpp
js/src/jit/AsmJS.cpp
js/src/jit/BacktrackingAllocator.cpp
js/src/jit/CodeGenerator.cpp
js/src/jit/EffectiveAddressAnalysis.cpp
js/src/jit/Ion.cpp
js/src/jit/IonAnalysis.cpp
js/src/jit/IonBuilder.cpp
js/src/jit/IonBuilder.h
js/src/jit/Lowering.cpp
js/src/jit/MCallOptimize.cpp
js/src/jit/MIR.cpp
js/src/jit/MIR.h
js/src/jit/MIRGenerator.h
js/src/jit/MIRGraph.cpp
js/src/jit/MIRGraph.h
js/src/jit/ParallelSafetyAnalysis.cpp
js/src/jit/RangeAnalysis.cpp
js/src/jit/RangeAnalysis.h
js/src/jit/RegisterAllocator.h
js/src/jit/TypePolicy.cpp
js/src/jit/TypePolicy.h
js/src/jit/UnreachableCodeElimination.cpp
js/src/jit/ValueNumbering.cpp
js/src/jit/shared/CodeGenerator-shared.cpp
js/src/jit/shared/Lowering-shared.h
js/src/jsworkers.cpp
--- a/js/src/jit/AliasAnalysis.cpp
+++ b/js/src/jit/AliasAnalysis.cpp
@@ -143,17 +143,17 @@ AliasAnalysis::analyze()
     uint32_t newId = 1;
 
     for (ReversePostorderIterator block(graph_.rpoBegin()); block != graph_.rpoEnd(); block++) {
         if (mir->shouldCancel("Alias Analysis (main loop)"))
             return false;
 
         if (block->isLoopHeader()) {
             IonSpew(IonSpew_Alias, "Processing loop header %d", block->id());
-            loop_ = new(mir->temp()) LoopAliasInfo(loop_, *block);
+            loop_ = new(graph_.alloc()) LoopAliasInfo(loop_, *block);
         }
 
         for (MDefinitionIterator def(*block); def; def++) {
             def->setId(newId++);
 
             AliasSet set = def->getAliasSet();
             if (set.isNone())
                 continue;
--- a/js/src/jit/AsmJS.cpp
+++ b/js/src/jit/AsmJS.cpp
@@ -1852,16 +1852,17 @@ class FunctionCompiler
         breakableStack_(m.cx()),
         unlabeledBreaks_(m.cx()),
         unlabeledContinues_(m.cx()),
         labeledBreaks_(m.cx()),
         labeledContinues_(m.cx())
     {}
 
     ModuleCompiler &    m() const      { return m_; }
+    TempAllocator &     alloc() const  { return *alloc_; }
     LifoAlloc &         lifo() const   { return lifo_; }
     ParseNode *         fn() const     { return fn_; }
     ExclusiveContext *  cx() const     { return m_.cx(); }
     const AsmJSModule & module() const { return m_.module(); }
 
     bool init()
     {
         return locals_.init() &&
@@ -1933,26 +1934,26 @@ class FunctionCompiler
 
         graph_  = lifo_.new_<MIRGraph>(alloc_);
         info_   = lifo_.new_<CompileInfo>(locals_.count(), SequentialExecution);
         mirGen_ = lifo_.new_<MIRGenerator>(cx()->compartment(), alloc_, graph_, info_);
 
         if (!newBlock(/* pred = */ nullptr, &curBlock_, fn_))
             return false;
 
-        curBlock_->add(MAsmJSCheckOverRecursed::New(&m_.stackOverflowLabel()));
+        curBlock_->add(MAsmJSCheckOverRecursed::New(alloc(), &m_.stackOverflowLabel()));
 
         for (ABIArgTypeIter i = argTypes; !i.done(); i++) {
-            MAsmJSParameter *ins = MAsmJSParameter::New(*i, i.mirType());
+            MAsmJSParameter *ins = MAsmJSParameter::New(alloc(), *i, i.mirType());
             curBlock_->add(ins);
             curBlock_->initSlot(info().localSlot(i.index()), ins);
         }
         unsigned firstLocalSlot = argTypes.length();
         for (unsigned i = 0; i < varInitializers_.length(); i++) {
-            MConstant *ins = MConstant::New(varInitializers_[i]);
+            MConstant *ins = MConstant::New(alloc(), varInitializers_[i]);
             curBlock_->add(ins);
             curBlock_->initSlot(info().localSlot(firstLocalSlot + i), ins);
         }
         return true;
     }
 
     /******************************* For consistency of returns in a function */
 
@@ -1997,151 +1998,151 @@ class FunctionCompiler
 
     /***************************** Code generation (after local scope setup) */
 
     MDefinition *constant(const Value &v)
     {
         if (!curBlock_)
             return nullptr;
         JS_ASSERT(v.isNumber());
-        MConstant *constant = MConstant::New(v);
+        MConstant *constant = MConstant::New(alloc(), v);
         curBlock_->add(constant);
         return constant;
     }
 
     template <class T>
     MDefinition *unary(MDefinition *op)
     {
         if (!curBlock_)
             return nullptr;
-        T *ins = T::NewAsmJS(op);
+        T *ins = T::NewAsmJS(alloc(), op);
         curBlock_->add(ins);
         return ins;
     }
 
     template <class T>
     MDefinition *unary(MDefinition *op, MIRType type)
     {
         if (!curBlock_)
             return nullptr;
-        T *ins = T::NewAsmJS(op, type);
+        T *ins = T::NewAsmJS(alloc(), op, type);
         curBlock_->add(ins);
         return ins;
     }
 
     template <class T>
     MDefinition *binary(MDefinition *lhs, MDefinition *rhs)
     {
         if (!curBlock_)
             return nullptr;
-        T *ins = T::New(lhs, rhs);
+        T *ins = T::New(alloc(), lhs, rhs);
         curBlock_->add(ins);
         return ins;
     }
 
     template <class T>
     MDefinition *binary(MDefinition *lhs, MDefinition *rhs, MIRType type)
     {
         if (!curBlock_)
             return nullptr;
-        T *ins = T::NewAsmJS(lhs, rhs, type);
+        T *ins = T::NewAsmJS(alloc(), lhs, rhs, type);
         curBlock_->add(ins);
         return ins;
     }
 
     MDefinition *mul(MDefinition *lhs, MDefinition *rhs, MIRType type, MMul::Mode mode)
     {
         if (!curBlock_)
             return nullptr;
-        MMul *ins = MMul::New(lhs, rhs, type, mode);
+        MMul *ins = MMul::New(alloc(), lhs, rhs, type, mode);
         curBlock_->add(ins);
         return ins;
     }
 
     template <class T>
     MDefinition *bitwise(MDefinition *lhs, MDefinition *rhs)
     {
         if (!curBlock_)
             return nullptr;
-        T *ins = T::NewAsmJS(lhs, rhs);
+        T *ins = T::NewAsmJS(alloc(), lhs, rhs);
         curBlock_->add(ins);
         return ins;
     }
 
     template <class T>
     MDefinition *bitwise(MDefinition *op)
     {
         if (!curBlock_)
             return nullptr;
-        T *ins = T::NewAsmJS(op);
+        T *ins = T::NewAsmJS(alloc(), op);
         curBlock_->add(ins);
         return ins;
     }
 
     MDefinition *compare(MDefinition *lhs, MDefinition *rhs, JSOp op, MCompare::CompareType type)
     {
         if (!curBlock_)
             return nullptr;
-        MCompare *ins = MCompare::NewAsmJS(lhs, rhs, op, type);
+        MCompare *ins = MCompare::NewAsmJS(alloc(), lhs, rhs, op, type);
         curBlock_->add(ins);
         return ins;
     }
 
     void assign(const Local &local, MDefinition *def)
     {
         if (!curBlock_)
             return;
         curBlock_->setSlot(info().localSlot(local.slot), def);
     }
 
     MDefinition *loadHeap(ArrayBufferView::ViewType vt, MDefinition *ptr, NeedsBoundsCheck chk)
     {
         if (!curBlock_)
             return nullptr;
-        MAsmJSLoadHeap *load = MAsmJSLoadHeap::New(vt, ptr);
+        MAsmJSLoadHeap *load = MAsmJSLoadHeap::New(alloc(), vt, ptr);
         curBlock_->add(load);
         if (chk == NO_BOUNDS_CHECK)
             load->setSkipBoundsCheck(true);
         return load;
     }
 
     void storeHeap(ArrayBufferView::ViewType vt, MDefinition *ptr, MDefinition *v, NeedsBoundsCheck chk)
     {
         if (!curBlock_)
             return;
-        MAsmJSStoreHeap *store = MAsmJSStoreHeap::New(vt, ptr, v);
+        MAsmJSStoreHeap *store = MAsmJSStoreHeap::New(alloc(), vt, ptr, v);
         curBlock_->add(store);
         if (chk == NO_BOUNDS_CHECK)
             store->setSkipBoundsCheck(true);
     }
 
     MDefinition *loadGlobalVar(const ModuleCompiler::Global &global)
     {
         if (!curBlock_)
             return nullptr;
         if (global.varIsLitConstant()) {
             JS_ASSERT(global.litConstValue().isNumber());
-            MConstant *constant = MConstant::New(global.litConstValue());
+            MConstant *constant = MConstant::New(alloc(), global.litConstValue());
             curBlock_->add(constant);
             return constant;
         }
         MIRType type = global.varType().toMIRType();
         unsigned globalDataOffset = module().globalVarIndexToGlobalDataOffset(global.varIndex());
-        MAsmJSLoadGlobalVar *load = MAsmJSLoadGlobalVar::New(type, globalDataOffset,
+        MAsmJSLoadGlobalVar *load = MAsmJSLoadGlobalVar::New(alloc(), type, globalDataOffset,
                                                              global.varIsConstant());
         curBlock_->add(load);
         return load;
     }
 
     void storeGlobalVar(const ModuleCompiler::Global &global, MDefinition *v)
     {
         if (!curBlock_)
             return;
         unsigned globalDataOffset = module().globalVarIndexToGlobalDataOffset(global.varIndex());
-        curBlock_->add(MAsmJSStoreGlobalVar::New(globalDataOffset, v));
+        curBlock_->add(MAsmJSStoreGlobalVar::New(alloc(), globalDataOffset, v));
     }
 
     /***************************************************************** Calls */
 
     // The IonMonkey backend maintains a single stack offset (from the stack
     // pointer to the base of the frame) by adding the total amount of spill
     // space required plus the maximum stack required for argument passing.
     // Since we do not use IonMonkey's MPrepareCall/MPassArg/MCall, we must
@@ -2202,17 +2203,18 @@ class FunctionCompiler
 
         uint32_t childStackBytes = mirGen().resetAsmJSMaxStackArgBytes();
         call->maxChildStackBytes_ = Max(call->maxChildStackBytes_, childStackBytes);
         if (childStackBytes > 0 && !call->stackArgs_.empty())
             call->childClobbers_ = true;
 
         ABIArg arg = call->abi_.next(type.toMIRType());
         if (arg.kind() == ABIArg::Stack) {
-            MAsmJSPassStackArg *mir = MAsmJSPassStackArg::New(arg.offsetFromArgBase(), argDef);
+            MAsmJSPassStackArg *mir = MAsmJSPassStackArg::New(alloc(), arg.offsetFromArgBase(),
+                                                              argDef);
             curBlock_->add(mir);
             if (!call->stackArgs_.append(mir))
                 return false;
         } else {
             if (!call->regArgs_.append(MAsmJSCall::Arg(arg.reg(), argDef)))
                 return false;
         }
         return true;
@@ -2240,17 +2242,18 @@ class FunctionCompiler
 
   private:
     bool callPrivate(MAsmJSCall::Callee callee, const Call &call, MIRType returnType, MDefinition **def)
     {
         if (!curBlock_) {
             *def = nullptr;
             return true;
         }
-        MAsmJSCall *ins = MAsmJSCall::New(callee, call.regArgs_, returnType, call.spIncrement_);
+        MAsmJSCall *ins = MAsmJSCall::New(alloc(), callee, call.regArgs_, returnType,
+                                          call.spIncrement_);
         if (!ins)
             return false;
         curBlock_->add(ins);
         *def = ins;
         return true;
     }
 
   public:
@@ -2263,96 +2266,96 @@ class FunctionCompiler
     bool funcPtrCall(const ModuleCompiler::FuncPtrTable &table, MDefinition *index,
                      const Call &call, MDefinition **def)
     {
         if (!curBlock_) {
             *def = nullptr;
             return true;
         }
 
-        MConstant *mask = MConstant::New(Int32Value(table.mask()));
+        MConstant *mask = MConstant::New(alloc(), Int32Value(table.mask()));
         curBlock_->add(mask);
-        MBitAnd *maskedIndex = MBitAnd::NewAsmJS(index, mask);
+        MBitAnd *maskedIndex = MBitAnd::NewAsmJS(alloc(), index, mask);
         curBlock_->add(maskedIndex);
-        MAsmJSLoadFuncPtr *ptrFun = MAsmJSLoadFuncPtr::New(table.globalDataOffset(), maskedIndex);
+        MAsmJSLoadFuncPtr *ptrFun = MAsmJSLoadFuncPtr::New(alloc(), table.globalDataOffset(), maskedIndex);
         curBlock_->add(ptrFun);
 
         MIRType returnType = table.sig().retType().toMIRType();
         return callPrivate(MAsmJSCall::Callee(ptrFun), call, returnType, def);
     }
 
     bool ffiCall(unsigned exitIndex, const Call &call, MIRType returnType, MDefinition **def)
     {
         if (!curBlock_) {
             *def = nullptr;
             return true;
         }
 
         JS_STATIC_ASSERT(offsetof(AsmJSModule::ExitDatum, exit) == 0);
         unsigned globalDataOffset = module().exitIndexToGlobalDataOffset(exitIndex);
 
-        MAsmJSLoadFFIFunc *ptrFun = MAsmJSLoadFFIFunc::New(globalDataOffset);
+        MAsmJSLoadFFIFunc *ptrFun = MAsmJSLoadFFIFunc::New(alloc(), globalDataOffset);
         curBlock_->add(ptrFun);
 
         return callPrivate(MAsmJSCall::Callee(ptrFun), call, returnType, def);
     }
 
     bool builtinCall(AsmJSImmKind builtin, const Call &call, MIRType returnType, MDefinition **def)
     {
         return callPrivate(MAsmJSCall::Callee(builtin), call, returnType, def);
     }
 
     /*********************************************** Control flow generation */
 
     void returnExpr(MDefinition *expr)
     {
         if (!curBlock_)
             return;
-        MAsmJSReturn *ins = MAsmJSReturn::New(expr);
+        MAsmJSReturn *ins = MAsmJSReturn::New(alloc(), expr);
         curBlock_->end(ins);
         curBlock_ = nullptr;
     }
 
     void returnVoid()
     {
         if (!curBlock_)
             return;
-        MAsmJSVoidReturn *ins = MAsmJSVoidReturn::New();
+        MAsmJSVoidReturn *ins = MAsmJSVoidReturn::New(alloc());
         curBlock_->end(ins);
         curBlock_ = nullptr;
     }
 
     bool branchAndStartThen(MDefinition *cond, MBasicBlock **thenBlock, MBasicBlock **elseBlock, ParseNode *thenPn, ParseNode* elsePn)
     {
         if (!curBlock_) {
             *thenBlock = nullptr;
             *elseBlock = nullptr;
             return true;
         }
         if (!newBlock(curBlock_, thenBlock, thenPn) || !newBlock(curBlock_, elseBlock, elsePn))
             return false;
-        curBlock_->end(MTest::New(cond, *thenBlock, *elseBlock));
+        curBlock_->end(MTest::New(alloc(), cond, *thenBlock, *elseBlock));
         curBlock_ = *thenBlock;
         return true;
     }
 
     bool appendThenBlock(BlockVector *thenBlocks) {
         if (!curBlock_)
             return true;
         return thenBlocks->append(curBlock_);
     }
 
     void joinIf(const BlockVector &thenBlocks, MBasicBlock *joinBlock)
     {
         if (!joinBlock)
             return;
         JS_ASSERT_IF(curBlock_, thenBlocks.back() == curBlock_);
         for (size_t i = 0; i < thenBlocks.length(); i++) {
-            thenBlocks[i]->end(MGoto::New(joinBlock));
-            joinBlock->addPredecessor(thenBlocks[i]);
+            thenBlocks[i]->end(MGoto::New(alloc(), joinBlock));
+            joinBlock->addPredecessor(alloc(), thenBlocks[i]);
         }
         curBlock_ = joinBlock;
         mirGraph().moveBlockToEnd(curBlock_);
     }
 
     void switchToElse(MBasicBlock *elseBlock)
     {
         if (!elseBlock)
@@ -2365,21 +2368,21 @@ class FunctionCompiler
     {
         if (!curBlock_ && thenBlocks.empty())
             return true;
         MBasicBlock *pred = curBlock_ ? curBlock_ : thenBlocks[0];
         MBasicBlock *join;
         if (!newBlock(pred, &join, pn))
             return false;
         if (curBlock_)
-            curBlock_->end(MGoto::New(join));
+            curBlock_->end(MGoto::New(alloc(), join));
         for (size_t i = 0; i < thenBlocks.length(); i++) {
-            thenBlocks[i]->end(MGoto::New(join));
+            thenBlocks[i]->end(MGoto::New(alloc(), join));
             if (pred == curBlock_ || i > 0)
-                join->addPredecessor(thenBlocks[i]);
+                join->addPredecessor(alloc(), thenBlocks[i]);
         }
         curBlock_ = join;
         return true;
     }
 
     void pushPhiInput(MDefinition *def)
     {
         if (!curBlock_)
@@ -2407,38 +2410,38 @@ class FunctionCompiler
         }
         *loopEntry = MBasicBlock::NewAsmJS(mirGraph(), info(), curBlock_,
                                            MBasicBlock::PENDING_LOOP_HEADER);
         if (!*loopEntry)
             return false;
         mirGraph().addBlock(*loopEntry);
         noteBasicBlockPosition(*loopEntry, bodyStmt);
         (*loopEntry)->setLoopDepth(loopStack_.length());
-        curBlock_->end(MGoto::New(*loopEntry));
+        curBlock_->end(MGoto::New(alloc(), *loopEntry));
         curBlock_ = *loopEntry;
         return true;
     }
 
     bool branchAndStartLoopBody(MDefinition *cond, MBasicBlock **afterLoop, ParseNode *bodyPn, ParseNode *afterPn)
     {
         if (!curBlock_) {
             *afterLoop = nullptr;
             return true;
         }
         JS_ASSERT(curBlock_->loopDepth() > 0);
         MBasicBlock *body;
         if (!newBlock(curBlock_, &body, bodyPn))
             return false;
         if (cond->isConstant() && cond->toConstant()->valueToBoolean()) {
             *afterLoop = nullptr;
-            curBlock_->end(MGoto::New(body));
+            curBlock_->end(MGoto::New(alloc(), body));
         } else {
             if (!newBlockWithDepth(curBlock_, curBlock_->loopDepth() - 1, afterLoop, afterPn))
                 return false;
-            curBlock_->end(MTest::New(cond, body, *afterLoop));
+            curBlock_->end(MTest::New(alloc(), cond, body, *afterLoop));
         }
         curBlock_ = body;
         return true;
     }
 
   private:
     ParseNode *popLoop()
     {
@@ -2458,17 +2461,17 @@ class FunctionCompiler
             JS_ASSERT(!curBlock_);
             JS_ASSERT(!unlabeledBreaks_.has(pn));
             return true;
         }
         JS_ASSERT(loopEntry->loopDepth() == loopStack_.length() + 1);
         JS_ASSERT_IF(afterLoop, afterLoop->loopDepth() == loopStack_.length());
         if (curBlock_) {
             JS_ASSERT(curBlock_->loopDepth() == loopStack_.length() + 1);
-            curBlock_->end(MGoto::New(loopEntry));
+            curBlock_->end(MGoto::New(alloc(), loopEntry));
             if (!loopEntry->setBackedgeAsmJS(curBlock_))
                 return false;
         }
         curBlock_ = afterLoop;
         if (curBlock_)
             mirGraph().moveBlockToEnd(curBlock_);
         return bindUnlabeledBreaks(pn);
     }
@@ -2481,32 +2484,32 @@ class FunctionCompiler
             JS_ASSERT(!unlabeledBreaks_.has(pn));
             return true;
         }
         JS_ASSERT(loopEntry->loopDepth() == loopStack_.length() + 1);
         if (curBlock_) {
             JS_ASSERT(curBlock_->loopDepth() == loopStack_.length() + 1);
             if (cond->isConstant()) {
                 if (cond->toConstant()->valueToBoolean()) {
-                    curBlock_->end(MGoto::New(loopEntry));
+                    curBlock_->end(MGoto::New(alloc(), loopEntry));
                     if (!loopEntry->setBackedgeAsmJS(curBlock_))
                         return false;
                     curBlock_ = nullptr;
                 } else {
                     MBasicBlock *afterLoop;
                     if (!newBlock(curBlock_, &afterLoop, afterLoopStmt))
                         return false;
-                    curBlock_->end(MGoto::New(afterLoop));
+                    curBlock_->end(MGoto::New(alloc(), afterLoop));
                     curBlock_ = afterLoop;
                 }
             } else {
                 MBasicBlock *afterLoop;
                 if (!newBlock(curBlock_, &afterLoop, afterLoopStmt))
                     return false;
-                curBlock_->end(MTest::New(cond, loopEntry, afterLoop));
+                curBlock_->end(MTest::New(alloc(), cond, loopEntry, afterLoop));
                 if (!loopEntry->setBackedgeAsmJS(curBlock_))
                     return false;
                 curBlock_ = afterLoop;
             }
         }
         return bindUnlabeledBreaks(pn);
     }
 
@@ -2543,33 +2546,33 @@ class FunctionCompiler
                      MBasicBlock **switchBlock)
     {
         if (!breakableStack_.append(pn))
             return false;
         if (!curBlock_) {
             *switchBlock = nullptr;
             return true;
         }
-        curBlock_->end(MTableSwitch::New(expr, low, high));
+        curBlock_->end(MTableSwitch::New(alloc(), expr, low, high));
         *switchBlock = curBlock_;
         curBlock_ = nullptr;
         return true;
     }
 
     bool startSwitchCase(MBasicBlock *switchBlock, MBasicBlock **next, ParseNode *pn)
     {
         if (!switchBlock) {
             *next = nullptr;
             return true;
         }
         if (!newBlock(switchBlock, next, pn))
             return false;
         if (curBlock_) {
-            curBlock_->end(MGoto::New(*next));
-            (*next)->addPredecessor(curBlock_);
+            curBlock_->end(MGoto::New(alloc(), *next));
+            (*next)->addPredecessor(alloc(), curBlock_);
         }
         curBlock_ = *next;
         return true;
     }
 
     bool startSwitchDefault(MBasicBlock *switchBlock, BlockVector *cases, MBasicBlock **defaultBlock, ParseNode *pn)
     {
         if (!startSwitchCase(switchBlock, defaultBlock, pn))
@@ -2592,17 +2595,17 @@ class FunctionCompiler
                 mir->addCase(defaultIndex);
             else
                 mir->addCase(mir->addSuccessor(cases[i]));
         }
         if (curBlock_) {
             MBasicBlock *next;
             if (!newBlock(curBlock_, &next, pn))
                 return false;
-            curBlock_->end(MGoto::New(next));
+            curBlock_->end(MGoto::New(alloc(), next));
             curBlock_ = next;
         }
         return bindUnlabeledBreaks(pn);
     }
 
     /*************************************************************************/
 
     MIRGenerator *extractMIR()
@@ -2643,26 +2646,26 @@ class FunctionCompiler
         return newBlockWithDepth(pred, loopStack_.length(), block, pn);
     }
 
     bool bindBreaksOrContinues(BlockVector *preds, bool *createdJoinBlock, ParseNode *pn)
     {
         for (unsigned i = 0; i < preds->length(); i++) {
             MBasicBlock *pred = (*preds)[i];
             if (*createdJoinBlock) {
-                pred->end(MGoto::New(curBlock_));
-                curBlock_->addPredecessor(pred);
+                pred->end(MGoto::New(alloc(), curBlock_));
+                curBlock_->addPredecessor(alloc(), pred);
             } else {
                 MBasicBlock *next;
                 if (!newBlock(pred, &next, pn))
                     return false;
-                pred->end(MGoto::New(next));
+                pred->end(MGoto::New(alloc(), next));
                 if (curBlock_) {
-                    curBlock_->end(MGoto::New(next));
-                    next->addPredecessor(curBlock_);
+                    curBlock_->end(MGoto::New(alloc(), next));
+                    next->addPredecessor(alloc(), curBlock_);
                 }
                 curBlock_ = next;
                 *createdJoinBlock = true;
             }
             JS_ASSERT(curBlock_->begin() == curBlock_->end());
         }
         preds->clear();
         return true;
@@ -5031,17 +5034,17 @@ CheckFunctionsSequential(ModuleCompiler 
 
         MIRGenerator *mir;
         ModuleCompiler::Func *func;
         if (!CheckFunction(m, lifo, &mir, &func))
             return false;
 
         int64_t before = PRMJ_Now();
 
-        IonContext icx(m.cx(), &mir->temp());
+        IonContext icx(m.cx(), &mir->alloc());
 
         IonSpewNewFunction(&mir->graph(), NullPtr());
 
         if (!OptimizeMIR(mir))
             return m.failOffset(func->srcOffset(), "internal compiler failure (probably out of memory)");
 
         LIRGraph *lir = GenerateLIR(mir);
         if (!lir)
@@ -5139,25 +5142,25 @@ GenerateCodeForFinishedJob(ModuleCompile
     if (!task)
         return false;
 
     ModuleCompiler::Func &func = *reinterpret_cast<ModuleCompiler::Func *>(task->func);
     func.accumulateCompileTime(task->compileTime);
 
     {
         // Perform code generation on the main thread.
-        IonContext ionContext(m.cx(), &task->mir->temp());
+        IonContext ionContext(m.cx(), &task->mir->alloc());
         if (!GenerateCode(m, func, *task->mir, *task->lir))
             return false;
     }
 
     group.compiledJobs++;
 
     // Clear the LifoAlloc for use by another worker.
-    TempAllocator &tempAlloc = task->mir->temp();
+    TempAllocator &tempAlloc = task->mir->alloc();
     tempAlloc.TempAllocator::~TempAllocator();
     task->lifo.releaseAll();
 
     *outTask = task;
     return true;
 }
 
 static inline bool
--- a/js/src/jit/BacktrackingAllocator.cpp
+++ b/js/src/jit/BacktrackingAllocator.cpp
@@ -21,17 +21,17 @@ BacktrackingAllocator::init()
         AnyRegister reg = AnyRegister(remainingRegisters.takeGeneral());
         registers[reg.code()].allocatable = true;
     }
     while (!remainingRegisters.empty(/* float = */ true)) {
         AnyRegister reg = AnyRegister(remainingRegisters.takeFloat());
         registers[reg.code()].allocatable = true;
     }
 
-    LifoAlloc *lifoAlloc = mir->temp().lifoAlloc();
+    LifoAlloc *lifoAlloc = mir->alloc().lifoAlloc();
     for (size_t i = 0; i < AnyRegister::Total; i++) {
         registers[i].reg = AnyRegister::FromCode(i);
         registers[i].allocations.setAllocator(lifoAlloc);
 
         LiveInterval *fixed = fixedIntervals[i];
         for (size_t j = 0; j < fixed->numRanges(); j++) {
             AllocatedRange range(fixed, fixed->getRange(j));
             if (!registers[i].allocations.insert(range))
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -5743,17 +5743,17 @@ CodeGenerator::generateAsmJS()
 
 bool
 CodeGenerator::generate()
 {
     IonSpew(IonSpew_Codegen, "# Emitting code for script %s:%d",
             gen->info().script()->filename(),
             gen->info().script()->lineno);
 
-    if (!safepoints_.init(gen->temp(), graph.totalSlotCount()))
+    if (!safepoints_.init(gen->alloc(), graph.totalSlotCount()))
         return false;
 
 #if JS_TRACE_LOGGING
     masm.tracelogStart(gen->info().script());
     masm.tracelogLog(TraceLogging::INFO_ENGINE_IONMONKEY);
 #endif
 
     // Before generating any code, we generate type checks for all parameters.
--- a/js/src/jit/EffectiveAddressAnalysis.cpp
+++ b/js/src/jit/EffectiveAddressAnalysis.cpp
@@ -7,17 +7,17 @@
 #include "jit/EffectiveAddressAnalysis.h"
 #include "jit/MIR.h"
 #include "jit/MIRGraph.h"
 
 using namespace js;
 using namespace jit;
 
 static void
-AnalyzeLsh(MBasicBlock *block, MLsh *lsh)
+AnalyzeLsh(TempAllocator &alloc, MBasicBlock *block, MLsh *lsh)
 {
     if (lsh->specialization() != MIRType_Int32)
         return;
 
     MDefinition *index = lsh->lhs();
     JS_ASSERT(index->type() == MIRType_Int32);
 
     MDefinition *shift = lsh->rhs();
@@ -79,17 +79,17 @@ AnalyzeLsh(MBasicBlock *block, MLsh *lsh
         uint32_t bitsClearedByMask = ~uint32_t(other->toConstant()->value().toInt32());
         if ((bitsClearedByShift & bitsClearedByMask) != bitsClearedByMask)
             return;
 
         bitAnd->replaceAllUsesWith(last);
         return;
     }
 
-    MEffectiveAddress *eaddr = MEffectiveAddress::New(base, index, scale, displacement);
+    MEffectiveAddress *eaddr = MEffectiveAddress::New(alloc, base, index, scale, displacement);
     last->replaceAllUsesWith(eaddr);
     block->insertAfter(last, eaddr);
 }
 
 // This analysis converts patterns of the form:
 //   truncate(x + (y << {0,1,2,3}))
 //   truncate(x + (y << {0,1,2,3}) + imm32)
 // into a single lea instruction, and patterns of the form:
@@ -104,13 +104,13 @@ AnalyzeLsh(MBasicBlock *block, MLsh *lsh
 //   truncate(x + y + imm32)
 //   truncate((y << {0,1,2,3}) + imm32)
 bool
 EffectiveAddressAnalysis::analyze()
 {
     for (ReversePostorderIterator block(graph_.rpoBegin()); block != graph_.rpoEnd(); block++) {
         for (MInstructionIterator i = block->begin(); i != block->end(); i++) {
             if (i->isLsh())
-                AnalyzeLsh(*block, i->toLsh());
+                AnalyzeLsh(graph_.alloc(), *block, i->toLsh());
         }
     }
     return true;
 }
--- a/js/src/jit/Ion.cpp
+++ b/js/src/jit/Ion.cpp
@@ -522,17 +522,17 @@ jit::FinishOffThreadBuilder(IonBuilder *
     if (CompilingOffThread(builder->script(), executionMode))
         SetIonScript(builder->script(), executionMode, nullptr);
 
     // The builder is allocated into its LifoAlloc, so destroying that will
     // destroy the builder and all other data accumulated during compilation,
     // except any final codegen (which includes an assembler and needs to be
     // explicitly destroyed).
     js_delete(builder->backgroundCodegen());
-    js_delete(builder->temp().lifoAlloc());
+    js_delete(builder->alloc().lifoAlloc());
 }
 
 static inline void
 FinishAllOffThreadCompilations(JitCompartment *ion)
 {
     OffThreadCompilationVector &compilations = ion->finishedOffThreadCompilations();
 
     for (size_t i = 0; i < compilations.length(); i++) {
@@ -1369,17 +1369,17 @@ OptimizeMIR(MIRGenerator *mir)
     return true;
 }
 
 LIRGraph *
 GenerateLIR(MIRGenerator *mir)
 {
     MIRGraph &graph = mir->graph();
 
-    LIRGraph *lir = mir->temp().lifoAlloc()->new_<LIRGraph>(&graph);
+    LIRGraph *lir = mir->alloc().lifoAlloc()->new_<LIRGraph>(&graph);
     if (!lir)
         return nullptr;
 
     LIRGenerator lirgen(mir, graph, *lir);
     if (!lirgen.generate())
         return nullptr;
     IonSpewPass("Generate LIR");
 
@@ -1504,27 +1504,27 @@ AttachFinishedCompilations(JSContext *cx
 
     // Incorporate any off thread compilations which have finished, failed or
     // have been cancelled.
     while (!compilations.empty()) {
         IonBuilder *builder = compilations.popCopy();
 
         if (CodeGenerator *codegen = builder->backgroundCodegen()) {
             RootedScript script(cx, builder->script());
-            IonContext ictx(cx, &builder->temp());
+            IonContext ictx(cx, &builder->alloc());
 
             // Root the assembler until the builder is finished below. As it
             // was constructed off thread, the assembler has not been rooted
             // previously, though any GC activity would discard the builder.
             codegen->masm.constructRoot(cx);
 
             bool success;
             {
                 // Release the worker thread lock and root the compiler for GC.
-                AutoTempAllocatorRooter root(cx, &builder->temp());
+                AutoTempAllocatorRooter root(cx, &builder->alloc());
                 AutoUnlockWorkerThreadState unlock(cx->runtime());
                 AutoFlushCache afc("AttachFinishedCompilations", cx->runtime()->jitRuntime());
                 success = codegen->link(cx, builder->constraints());
             }
 
             if (!success) {
                 // Silently ignore OOM during code generation, we're at an
                 // operation callback and can't propagate failures.
--- a/js/src/jit/IonAnalysis.cpp
+++ b/js/src/jit/IonAnalysis.cpp
@@ -37,17 +37,17 @@ jit::SplitCriticalEdges(MIRGraph &graph)
             MBasicBlock *target = block->getSuccessor(i);
             if (target->numPredecessors() < 2)
                 continue;
 
             // Create a new block inheriting from the predecessor.
             MBasicBlock *split = MBasicBlock::NewSplitEdge(graph, block->info(), *block);
             split->setLoopDepth(block->loopDepth());
             graph.insertBlockAfter(*block, split);
-            split->end(MGoto::New(target));
+            split->end(MGoto::New(graph.alloc(), target));
 
             block->replaceSuccessor(i, split);
             target->replacePredecessor(*block, split);
         }
     }
     return true;
 }
 
@@ -137,17 +137,17 @@ jit::EliminateDeadResumePointOperands(MI
                 // Store an undefined value in place of all dead resume point
                 // operands. Making any such substitution can in general alter
                 // the interpreter's behavior, even though the code is dead, as
                 // the interpreter will still execute opcodes whose effects
                 // cannot be observed. If the undefined value were to flow to,
                 // say, a dead property access the interpreter could throw an
                 // exception; we avoid this problem by removing dead operands
                 // before removing dead code.
-                MConstant *constant = MConstant::New(UndefinedValue());
+                MConstant *constant = MConstant::New(graph.alloc(), UndefinedValue());
                 block->insertBefore(*(block->begin()), constant);
                 uses = mrp->replaceOperand(uses, constant);
             }
         }
     }
 
     return true;
 }
@@ -384,16 +384,20 @@ namespace {
 // conversion operations.
 //
 class TypeAnalyzer
 {
     MIRGenerator *mir;
     MIRGraph &graph;
     Vector<MPhi *, 0, SystemAllocPolicy> phiWorklist_;
 
+    TempAllocator &alloc() const {
+        return graph.alloc();
+    }
+
     bool addPhiToWorklist(MPhi *phi) {
         if (phi->isInWorklist())
             return true;
         if (!phiWorklist_.append(phi))
             return false;
         phi->setInWorklist();
         return true;
     }
@@ -580,45 +584,45 @@ TypeAnalyzer::adjustPhiInputs(MPhi *phi)
 
             if (in->isBox() && in->toBox()->input()->type() == phiType) {
                 phi->replaceOperand(i, in->toBox()->input());
             } else {
                 MInstruction *replacement;
 
                 if (phiType == MIRType_Double && IsFloatType(in->type())) {
                     // Convert int32 operands to double.
-                    replacement = MToDouble::New(in);
+                    replacement = MToDouble::New(alloc(), in);
                 } else if (phiType == MIRType_Float32) {
                     if (in->type() == MIRType_Int32 || in->type() == MIRType_Double) {
-                        replacement = MToFloat32::New(in);
+                        replacement = MToFloat32::New(alloc(), in);
                     } else {
                         // See comment below
                         if (in->type() != MIRType_Value) {
-                            MBox *box = MBox::New(in);
+                            MBox *box = MBox::New(alloc(), in);
                             in->block()->insertBefore(in->block()->lastIns(), box);
                             in = box;
                         }
 
-                        MUnbox *unbox = MUnbox::New(in, MIRType_Double, MUnbox::Fallible);
+                        MUnbox *unbox = MUnbox::New(alloc(), in, MIRType_Double, MUnbox::Fallible);
                         in->block()->insertBefore(in->block()->lastIns(), unbox);
-                        replacement = MToFloat32::New(in);
+                        replacement = MToFloat32::New(alloc(), in);
                     }
                 } else {
                     // If we know this branch will fail to convert to phiType,
                     // insert a box that'll immediately fail in the fallible unbox
                     // below.
                     if (in->type() != MIRType_Value) {
-                        MBox *box = MBox::New(in);
+                        MBox *box = MBox::New(alloc(), in);
                         in->block()->insertBefore(in->block()->lastIns(), box);
                         in = box;
                     }
 
                     // Be optimistic and insert unboxes when the operand is a
                     // value.
-                    replacement = MUnbox::New(in, phiType, MUnbox::Fallible);
+                    replacement = MUnbox::New(alloc(), in, phiType, MUnbox::Fallible);
                 }
 
                 in->block()->insertBefore(in->block()->lastIns(), replacement);
                 phi->replaceOperand(i, replacement);
             }
         }
 
         return;
@@ -630,27 +634,27 @@ TypeAnalyzer::adjustPhiInputs(MPhi *phi)
         if (in->type() == MIRType_Value)
             continue;
 
         if (in->isUnbox() && phi->typeIncludes(in->toUnbox()->input())) {
             // The input is being explicitly unboxed, so sneak past and grab
             // the original box.
             phi->replaceOperand(i, in->toUnbox()->input());
         } else {
-            MDefinition *box = BoxInputsPolicy::alwaysBoxAt(in->block()->lastIns(), in);
+            MDefinition *box = BoxInputsPolicy::alwaysBoxAt(alloc(), in->block()->lastIns(), in);
             phi->replaceOperand(i, box);
         }
     }
 }
 
 bool
 TypeAnalyzer::adjustInputs(MDefinition *def)
 {
     TypePolicy *policy = def->typePolicy();
-    if (policy && !policy->adjustInputs(def->toInstruction()))
+    if (policy && !policy->adjustInputs(alloc(), def->toInstruction()))
         return false;
     return true;
 }
 
 void
 TypeAnalyzer::replaceRedundantPhi(MPhi *phi)
 {
     MBasicBlock *block = phi->block();
@@ -663,17 +667,17 @@ TypeAnalyzer::replaceRedundantPhi(MPhi *
         v = NullValue();
         break;
       case MIRType_Magic:
         v = MagicValue(JS_OPTIMIZED_ARGUMENTS);
         break;
       default:
         MOZ_ASSUME_UNREACHABLE("unexpected type");
     }
-    MConstant *c = MConstant::New(v);
+    MConstant *c = MConstant::New(alloc(), v);
     // The instruction pass will insert the box
     block->insertBefore(*(block->begin()), c);
     phi->replaceAllUsesWith(c);
 }
 
 bool
 TypeAnalyzer::insertConversions()
 {
@@ -859,17 +863,17 @@ TypeAnalyzer::specializeValidFloatOps()
             if (!ins->isFloat32Commutative())
                 continue;
 
             if (ins->type() == MIRType_Float32)
                 continue;
 
             // This call will try to specialize the instruction iff all uses are consumers and
             // all inputs are producers.
-            ins->trySpecializeFloat32();
+            ins->trySpecializeFloat32(alloc());
         }
     }
     return true;
 }
 
 bool
 TypeAnalyzer::graphContainsFloat32()
 {
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -561,45 +561,45 @@ IonBuilder::build()
     IonSpew(IonSpew_Scripts, "Analyzing script %s:%d (%p) (usecount=%d)",
             script()->filename(), script()->lineno, (void *)script(), (int)script()->getUseCount());
 
     if (!initParameters())
         return false;
 
     // Initialize local variables.
     for (uint32_t i = 0; i < info().nlocals(); i++) {
-        MConstant *undef = MConstant::New(UndefinedValue());
+        MConstant *undef = MConstant::New(alloc(), UndefinedValue());
         current->add(undef);
         current->initSlot(info().localSlot(i), undef);
     }
 
     // Initialize something for the scope chain. We can bail out before the
     // start instruction, but the snapshot is encoded *at* the start
     // instruction, which means generating any code that could load into
     // registers is illegal.
-    MInstruction *scope = MConstant::New(UndefinedValue());
+    MInstruction *scope = MConstant::New(alloc(), UndefinedValue());
     current->add(scope);
     current->initSlot(info().scopeChainSlot(), scope);
 
     // Initialize the return value.
-    MInstruction *returnValue = MConstant::New(UndefinedValue());
+    MInstruction *returnValue = MConstant::New(alloc(), UndefinedValue());
     current->add(returnValue);
     current->initSlot(info().returnValueSlot(), returnValue);
 
     // Initialize the arguments object slot to undefined if necessary.
     if (info().hasArguments()) {
-        MInstruction *argsObj = MConstant::New(UndefinedValue());
+        MInstruction *argsObj = MConstant::New(alloc(), UndefinedValue());
         current->add(argsObj);
         current->initSlot(info().argsObjSlot(), argsObj);
     }
 
     // Emit the start instruction, so we can begin real instructions.
-    current->makeStart(MStart::New(MStart::StartType_Default));
+    current->makeStart(MStart::New(alloc(), MStart::StartType_Default));
     if (instrumentedProfiling())
-        current->add(MFunctionBoundary::New(script(), MFunctionBoundary::Enter));
+        current->add(MFunctionBoundary::New(alloc(), script(), MFunctionBoundary::Enter));
 
     // Guard against over-recursion. Do this before we start unboxing, since
     // this will create an OSI point that will read the incoming argument
     // values, which is nice to do before their last real use, to minimize
     // register/stack pressure.
     MCheckOverRecursed *check = new MCheckOverRecursed;
     current->add(check);
     check->setResumePoint(current->entryResumePoint());
@@ -637,17 +637,17 @@ IonBuilder::build()
     for (uint32_t i = 0; i < info().endArgSlot(); i++) {
         MInstruction *ins = current->getEntrySlot(i)->toInstruction();
         if (ins->type() == MIRType_Value)
             ins->setResumePoint(current->entryResumePoint());
     }
 
     // lazyArguments should never be accessed in |argsObjAliasesFormals| scripts.
     if (info().hasArguments() && !info().argsObjAliasesFormals()) {
-        lazyArguments_ = MConstant::New(MagicValue(JS_OPTIMIZED_ARGUMENTS));
+        lazyArguments_ = MConstant::New(alloc(), MagicValue(JS_OPTIMIZED_ARGUMENTS));
         current->add(lazyArguments_);
     }
 
     if (!traverseBytecode())
         return false;
 
     if (!processIterators())
         return false;
@@ -723,37 +723,37 @@ IonBuilder::buildInline(IonBuilder *call
     MBasicBlock *predecessor = callerBuilder->current;
     JS_ASSERT(predecessor == callerResumePoint->block());
 
     // All further instructions generated in from this scope should be
     // considered as part of the function that we're inlining. We also need to
     // keep track of the inlining depth because all scripts inlined on the same
     // level contiguously have only one Inline_Exit node.
     if (instrumentedProfiling())
-        predecessor->add(MFunctionBoundary::New(script(),
+        predecessor->add(MFunctionBoundary::New(alloc(), script(),
                                                 MFunctionBoundary::Inline_Enter,
                                                 inliningDepth_));
 
-    predecessor->end(MGoto::New(current));
+    predecessor->end(MGoto::New(alloc(), current));
     if (!current->addPredecessorWithoutPhis(predecessor))
         return false;
 
     // Initialize scope chain slot to Undefined.  It's set later by |initScopeChain|.
-    MInstruction *scope = MConstant::New(UndefinedValue());
+    MInstruction *scope = MConstant::New(alloc(), UndefinedValue());
     current->add(scope);
     current->initSlot(info().scopeChainSlot(), scope);
 
     // Initialize |return value| slot.
-    MInstruction *returnValue = MConstant::New(UndefinedValue());
+    MInstruction *returnValue = MConstant::New(alloc(), UndefinedValue());
     current->add(returnValue);
     current->initSlot(info().returnValueSlot(), returnValue);
 
     // Initialize |arguments| slot.
     if (info().hasArguments()) {
-        MInstruction *argsObj = MConstant::New(UndefinedValue());
+        MInstruction *argsObj = MConstant::New(alloc(), UndefinedValue());
         current->add(argsObj);
         current->initSlot(info().argsObjSlot(), argsObj);
     }
 
     // Initialize |this| slot.
     current->initSlot(info().thisSlot(), callInfo.thisArg());
 
     IonSpew(IonSpew_Inlining, "Initializing %u arg slots", info().nargs());
@@ -766,42 +766,42 @@ IonBuilder::buildInline(IonBuilder *call
     uint32_t existing_args = Min<uint32_t>(callInfo.argc(), info().nargs());
     for (size_t i = 0; i < existing_args; ++i) {
         MDefinition *arg = callInfo.getArg(i);
         current->initSlot(info().argSlot(i), arg);
     }
 
     // Pass Undefined for missing arguments
     for (size_t i = callInfo.argc(); i < info().nargs(); ++i) {
-        MConstant *arg = MConstant::New(UndefinedValue());
+        MConstant *arg = MConstant::New(alloc(), UndefinedValue());
         current->add(arg);
         current->initSlot(info().argSlot(i), arg);
     }
 
     // Initialize the scope chain now that args are initialized.
     if (!initScopeChain(callInfo.fun()))
         return false;
 
     IonSpew(IonSpew_Inlining, "Initializing %u local slots", info().nlocals());
 
     // Initialize local variables.
     for (uint32_t i = 0; i < info().nlocals(); i++) {
-        MConstant *undef = MConstant::New(UndefinedValue());
+        MConstant *undef = MConstant::New(alloc(), UndefinedValue());
         current->add(undef);
         current->initSlot(info().localSlot(i), undef);
     }
 
     IonSpew(IonSpew_Inlining, "Inline entry block MResumePoint %p, %u operands",
             (void *) current->entryResumePoint(), current->entryResumePoint()->numOperands());
 
     // +2 for the scope chain and |this|, maybe another +1 for arguments object slot.
     JS_ASSERT(current->entryResumePoint()->numOperands() == info().totalSlots());
 
     if (script_->argumentsHasVarBinding()) {
-        lazyArguments_ = MConstant::New(MagicValue(JS_OPTIMIZED_ARGUMENTS));
+        lazyArguments_ = MConstant::New(alloc(), MagicValue(JS_OPTIMIZED_ARGUMENTS));
         current->add(lazyArguments_);
     }
 
     if (!traverseBytecode())
         return false;
 
     return true;
 }
@@ -809,17 +809,17 @@ IonBuilder::buildInline(IonBuilder *call
 void
 IonBuilder::rewriteParameter(uint32_t slotIdx, MDefinition *param, int32_t argIndex)
 {
     JS_ASSERT(param->isParameter() || param->isGetArgumentsObjectArg());
 
     types::TemporaryTypeSet *types = param->resultTypeSet();
     JSValueType definiteType = types->getKnownTypeTag();
 
-    MDefinition *actual = EnsureDefiniteType(param, definiteType);
+    MDefinition *actual = ensureDefiniteType(param, definiteType);
     if (actual == param)
         return;
 
     // Careful! We leave the original MParameter in the entry resume point. The
     // arguments still need to be checked unless proven otherwise at the call
     // site, and these checks can bailout. We can end up:
     //   v0 = Parameter(0)
     //   v1 = Unbox(v0, INT32)
@@ -853,34 +853,34 @@ IonBuilder::initParameters()
     if (!info().fun())
         return true;
 
     // If we are doing OSR on a frame which initially executed in the
     // interpreter and didn't accumulate type information, try to use that OSR
     // frame to determine possible initial types for 'this' and parameters.
 
     if (thisTypes->empty() && baselineFrame_) {
-        if (!thisTypes->addType(types::GetValueType(baselineFrame_->thisValue()), temp_->lifoAlloc()))
+        if (!thisTypes->addType(types::GetValueType(baselineFrame_->thisValue()), alloc_->lifoAlloc()))
             return false;
     }
 
-    MParameter *param = MParameter::New(MParameter::THIS_SLOT, thisTypes);
+    MParameter *param = MParameter::New(alloc(), MParameter::THIS_SLOT, thisTypes);
     current->add(param);
     current->initSlot(info().thisSlot(), param);
 
     for (uint32_t i = 0; i < info().nargs(); i++) {
         types::TemporaryTypeSet *types = &argTypes[i];
         if (types->empty() && baselineFrame_ &&
             !script_->baselineScript()->modifiesArguments())
         {
-            if (!types->addType(types::GetValueType(baselineFrame_->argv()[i]), temp_->lifoAlloc()))
+            if (!types->addType(types::GetValueType(baselineFrame_->argv()[i]), alloc_->lifoAlloc()))
                 return false;
         }
 
-        param = MParameter::New(i, types);
+        param = MParameter::New(alloc(), i, types);
         current->add(param);
         current->initSlot(info().argSlotUnchecked(i), param);
     }
 
     return true;
 }
 
 bool
@@ -899,51 +899,51 @@ IonBuilder::initScopeChain(MDefinition *
     // will try to access the scope. For other scripts, the scope instructions
     // will be held live by resume points and code will still be generated for
     // them, so just use a constant undefined value.
     if (!script()->compileAndGo)
         return abort("non-CNG global scripts are not supported");
 
     if (JSFunction *fun = info().fun()) {
         if (!callee) {
-            MCallee *calleeIns = MCallee::New();
+            MCallee *calleeIns = MCallee::New(alloc());
             current->add(calleeIns);
             callee = calleeIns;
         }
-        scope = MFunctionEnvironment::New(callee);
+        scope = MFunctionEnvironment::New(alloc(), callee);
         current->add(scope);
 
         // This reproduce what is done in CallObject::createForFunction
         if (fun->isHeavyweight()) {
             if (fun->isNamedLambda()) {
                 scope = createDeclEnvObject(callee, scope);
                 if (!scope)
                     return false;
             }
 
             scope = createCallObject(callee, scope);
             if (!scope)
                 return false;
         }
     } else {
-        scope = MConstant::New(ObjectValue(script()->global()));
+        scope = MConstant::New(alloc(), ObjectValue(script()->global()));
         current->add(scope);
     }
 
     current->setScopeChain(scope);
     return true;
 }
 
 bool
 IonBuilder::initArgumentsObject()
 {
     IonSpew(IonSpew_MIR, "%s:%d - Emitting code to initialize arguments object! block=%p",
                               script()->filename(), script()->lineno, current);
     JS_ASSERT(info().needsArgsObj());
-    MCreateArgumentsObject *argsObj = MCreateArgumentsObject::New(current->scopeChain());
+    MCreateArgumentsObject *argsObj = MCreateArgumentsObject::New(alloc(), current->scopeChain());
     current->add(argsObj);
     current->setArgumentsObject(argsObj);
     return true;
 }
 
 bool
 IonBuilder::addOsrValueTypeBarrier(uint32_t slot, MInstruction **def_,
                                    MIRType type, types::TemporaryTypeSet *typeSet)
@@ -951,63 +951,63 @@ IonBuilder::addOsrValueTypeBarrier(uint3
     MInstruction *&def = *def_;
     MBasicBlock *osrBlock = def->block();
 
     // Clear bogus type information added in newOsrPreheader().
     def->setResultType(MIRType_Value);
     def->setResultTypeSet(nullptr);
 
     if (typeSet && !typeSet->unknown()) {
-        MInstruction *barrier = MTypeBarrier::New(def, typeSet);
+        MInstruction *barrier = MTypeBarrier::New(alloc(), def, typeSet);
         osrBlock->insertBefore(osrBlock->lastIns(), barrier);
         osrBlock->rewriteSlot(slot, barrier);
         def = barrier;
     } else if (type == MIRType_Null ||
                type == MIRType_Undefined ||
                type == MIRType_Magic)
     {
         // No unbox instruction will be added below, so check the type by
         // adding a type barrier for a singleton type set.
         types::Type ntype = types::Type::PrimitiveType(ValueTypeFromMIRType(type));
-        typeSet = temp_->lifoAlloc()->new_<types::TemporaryTypeSet>(ntype);
+        typeSet = alloc_->lifoAlloc()->new_<types::TemporaryTypeSet>(ntype);
         if (!typeSet)
             return false;
-        MInstruction *barrier = MTypeBarrier::New(def, typeSet);
+        MInstruction *barrier = MTypeBarrier::New(alloc(), def, typeSet);
         osrBlock->insertBefore(osrBlock->lastIns(), barrier);
         osrBlock->rewriteSlot(slot, barrier);
         def = barrier;
     }
 
     if (type != def->type()) {
         switch (type) {
           case MIRType_Boolean:
           case MIRType_Int32:
           case MIRType_Double:
           case MIRType_String:
           case MIRType_Object:
           {
-            MUnbox *unbox = MUnbox::New(def, type, MUnbox::Fallible);
+            MUnbox *unbox = MUnbox::New(alloc(), def, type, MUnbox::Fallible);
             osrBlock->insertBefore(osrBlock->lastIns(), unbox);
             osrBlock->rewriteSlot(slot, unbox);
             def = unbox;
             break;
           }
 
           case MIRType_Null:
           {
-            MConstant *c = MConstant::New(NullValue());
+            MConstant *c = MConstant::New(alloc(), NullValue());
             osrBlock->insertBefore(osrBlock->lastIns(), c);
             osrBlock->rewriteSlot(slot, c);
             def = c;
             break;
           }
 
           case MIRType_Undefined:
           {
-            MConstant *c = MConstant::New(UndefinedValue());
+            MConstant *c = MConstant::New(alloc(), UndefinedValue());
             osrBlock->insertBefore(osrBlock->lastIns(), c);
             osrBlock->rewriteSlot(slot, c);
             def = c;
             break;
           }
 
           case MIRType_Magic:
             JS_ASSERT(lazyArguments_);
@@ -1120,17 +1120,17 @@ IonBuilder::maybeAddOsrTypeBarriers()
 // through uses in the loop body.
 bool
 IonBuilder::traverseBytecode()
 {
     for (;;) {
         JS_ASSERT(pc < info().limitPC());
 
         for (;;) {
-            if (!temp().ensureBallast())
+            if (!alloc().ensureBallast())
                 return false;
 
             // Check if we've hit an expected join point or edge in the bytecode.
             // Leaving one control structure could place us at the edge of another,
             // thus |while| instead of |if| so we don't skip any opcodes.
             if (!cfgStack_.empty() && cfgStack_.back().stopAt == pc) {
                 ControlStatus status = processCfgStack();
                 if (status == ControlStatus_Error)
@@ -1413,17 +1413,18 @@ IonBuilder::inspectOpcode(JSOp op)
         return jsop_rest();
 
       case JSOP_NOTEARG:
         return jsop_notearg();
 
       case JSOP_GETARG:
       case JSOP_CALLARG:
         if (info().argsObjAliasesFormals()) {
-            MGetArgumentsObjectArg *getArg = MGetArgumentsObjectArg::New(current->argumentsObject(),
+            MGetArgumentsObjectArg *getArg = MGetArgumentsObjectArg::New(alloc(),
+                                                                         current->argumentsObject(),
                                                                          GET_SLOTNO(pc));
             current->add(getArg);
             current->push(getArg);
         } else {
             current->pushArg(GET_SLOTNO(pc));
         }
         return true;
 
@@ -1595,17 +1596,17 @@ IonBuilder::inspectOpcode(JSOp op)
 
       case JSOP_THIS:
         return jsop_this();
 
       case JSOP_CALLEE:
       {
         MDefinition *callee;
         if (inliningDepth_ == 0) {
-            MInstruction *calleeIns = MCallee::New();
+            MInstruction *calleeIns = MCallee::New(alloc());
             current->add(calleeIns);
             callee = calleeIns;
         } else {
             callee = inlineCallInfo_->fun();
         }
         current->push(callee);
         return true;
       }
@@ -1795,19 +1796,19 @@ IonBuilder::processCfgEntry(CFGState &st
 
 IonBuilder::ControlStatus
 IonBuilder::processIfEnd(CFGState &state)
 {
     if (current) {
         // Here, the false block is the join point. Create an edge from the
         // current block to the false block. Note that a RETURN opcode
         // could have already ended the block.
-        current->end(MGoto::New(state.branch.ifFalse));
-
-        if (!state.branch.ifFalse->addPredecessor(current))
+        current->end(MGoto::New(alloc(), state.branch.ifFalse));
+
+        if (!state.branch.ifFalse->addPredecessor(alloc(), current))
             return ControlStatus_Error;
     }
 
     setCurrentAndSpecializePhis(state.branch.ifFalse);
     graph().moveBlockToEnd(current);
     pc = current->pc();
     return ControlStatus_Joined;
 }
@@ -1843,21 +1844,21 @@ IonBuilder::processIfElseFalseEnd(CFGSta
         return ControlStatus_Ended;
 
     // Create a new block to represent the join.
     MBasicBlock *join = newBlock(pred, state.branch.falseEnd);
     if (!join)
         return ControlStatus_Error;
 
     // Create edges from the true and false blocks as needed.
-    pred->end(MGoto::New(join));
+    pred->end(MGoto::New(alloc(), join));
 
     if (other) {
-        other->end(MGoto::New(join));
-        if (!join->addPredecessor(other))
+        other->end(MGoto::New(alloc(), join));
+        if (!join->addPredecessor(alloc(), other))
             return ControlStatus_Error;
     }
 
     // Ignore unreachable remainder of false block if existent.
     setCurrentAndSpecializePhis(join);
     pc = current->pc();
     return ControlStatus_Joined;
 }
@@ -1888,18 +1889,18 @@ IonBuilder::processBrokenLoop(CFGState &
 
     // Join the breaks together and continue parsing.
     if (state.loop.breaks) {
         MBasicBlock *block = createBreakCatchBlock(state.loop.breaks, state.loop.exitpc);
         if (!block)
             return ControlStatus_Error;
 
         if (current) {
-            current->end(MGoto::New(block));
-            if (!block->addPredecessor(current))
+            current->end(MGoto::New(alloc(), block));
+            if (!block->addPredecessor(alloc(), current))
                 return ControlStatus_Error;
         }
 
         setCurrentAndSpecializePhis(block);
     }
 
     // If the loop is not gated on a condition, and has only returns, we'll
     // reach this case. For example:
@@ -1952,18 +1953,18 @@ IonBuilder::finishLoop(CFGState &state, 
         // Create a catch block to join all break exits.
         MBasicBlock *block = createBreakCatchBlock(state.loop.breaks, state.loop.exitpc);
         if (!block)
             return ControlStatus_Error;
 
         if (successor) {
             // Finally, create an unconditional edge from the successor to the
             // catch block.
-            successor->end(MGoto::New(block));
-            if (!block->addPredecessor(successor))
+            successor->end(MGoto::New(alloc(), block));
+            if (!block->addPredecessor(alloc(), successor))
                 return ControlStatus_Error;
         }
         successor = block;
     }
 
     setCurrentAndSpecializePhis(successor);
 
     // An infinite loop (for (;;) { }) will not have a successor.
@@ -2034,17 +2035,17 @@ IonBuilder::processDoWhileBodyEnd(CFGSta
     // No current means control flow cannot reach the condition, so this will
     // never loop.
     if (!current)
         return processBrokenLoop(state);
 
     MBasicBlock *header = newBlock(current, state.loop.updatepc);
     if (!header)
         return ControlStatus_Error;
-    current->end(MGoto::New(header));
+    current->end(MGoto::New(alloc(), header));
 
     state.state = CFGState::DO_WHILE_LOOP_COND;
     state.stopAt = state.loop.updateEnd;
     pc = state.loop.updatepc;
     setCurrentAndSpecializePhis(header);
     return ControlStatus_Jumped;
 }
 
@@ -2059,17 +2060,17 @@ IonBuilder::processDoWhileCondEnd(CFGSta
 
     // Pop the last value, and create the successor block.
     MDefinition *vins = current->pop();
     MBasicBlock *successor = newBlock(current, GetNextPc(pc), loopDepth_ - 1);
     if (!successor)
         return ControlStatus_Error;
 
     // Create the test instruction and end the current block.
-    MTest *test = MTest::New(vins, state.loop.entry, successor);
+    MTest *test = MTest::New(alloc(), vins, state.loop.entry, successor);
     current->end(test);
     return finishLoop(state, successor);
 }
 
 IonBuilder::ControlStatus
 IonBuilder::processWhileCondEnd(CFGState &state)
 {
     JS_ASSERT(JSOp(*pc) == JSOP_IFNE || JSOp(*pc) == JSOP_IFEQ);
@@ -2080,19 +2081,19 @@ IonBuilder::processWhileCondEnd(CFGState
     // Create the body and successor blocks.
     MBasicBlock *body = newBlock(current, state.loop.bodyStart);
     state.loop.successor = newBlock(current, state.loop.exitpc, loopDepth_ - 1);
     if (!body || !state.loop.successor)
         return ControlStatus_Error;
 
     MTest *test;
     if (JSOp(*pc) == JSOP_IFNE)
-        test = MTest::New(ins, body, state.loop.successor);
+        test = MTest::New(alloc(), ins, body, state.loop.successor);
     else
-        test = MTest::New(ins, state.loop.successor, body);
+        test = MTest::New(alloc(), ins, state.loop.successor, body);
     current->end(test);
 
     state.state = CFGState::WHILE_LOOP_BODY;
     state.stopAt = state.loop.bodyEnd;
     pc = state.loop.bodyStart;
     setCurrentAndSpecializePhis(body);
     return ControlStatus_Jumped;
 }
@@ -2101,17 +2102,17 @@ IonBuilder::ControlStatus
 IonBuilder::processWhileBodyEnd(CFGState &state)
 {
     if (!processDeferredContinues(state))
         return ControlStatus_Error;
 
     if (!current)
         return processBrokenLoop(state);
 
-    current->end(MGoto::New(state.loop.entry));
+    current->end(MGoto::New(alloc(), state.loop.entry));
     return finishLoop(state, state.loop.successor);
 }
 
 IonBuilder::ControlStatus
 IonBuilder::processForCondEnd(CFGState &state)
 {
     JS_ASSERT(JSOp(*pc) == JSOP_IFNE);
 
@@ -2119,17 +2120,17 @@ IonBuilder::processForCondEnd(CFGState &
     MDefinition *ins = current->pop();
 
     // Create the body and successor blocks.
     MBasicBlock *body = newBlock(current, state.loop.bodyStart);
     state.loop.successor = newBlock(current, state.loop.exitpc, loopDepth_ - 1);
     if (!body || !state.loop.successor)
         return ControlStatus_Error;
 
-    MTest *test = MTest::New(ins, body, state.loop.successor);
+    MTest *test = MTest::New(alloc(), ins, body, state.loop.successor);
     current->end(test);
 
     state.state = CFGState::FOR_LOOP_BODY;
     state.stopAt = state.loop.bodyEnd;
     pc = state.loop.bodyStart;
     setCurrentAndSpecializePhis(body);
     return ControlStatus_Jumped;
 }
@@ -2156,17 +2157,17 @@ IonBuilder::processForBodyEnd(CFGState &
 IonBuilder::ControlStatus
 IonBuilder::processForUpdateEnd(CFGState &state)
 {
     // If there is no current, we couldn't reach the loop edge and there was no
     // update clause.
     if (!current)
         return processBrokenLoop(state);
 
-    current->end(MGoto::New(state.loop.entry));
+    current->end(MGoto::New(alloc(), state.loop.entry));
     return finishLoop(state, state.loop.successor);
 }
 
 IonBuilder::DeferredEdge *
 IonBuilder::filterDeadDeferredEdges(DeferredEdge *edge)
 {
     DeferredEdge *head = edge, *prev = nullptr;
 
@@ -2198,30 +2199,30 @@ IonBuilder::processDeferredContinues(CFG
     if (state.loop.continues) {
         DeferredEdge *edge = filterDeadDeferredEdges(state.loop.continues);
 
         MBasicBlock *update = newBlock(edge->block, loops_.back().continuepc);
         if (!update)
             return false;
 
         if (current) {
-            current->end(MGoto::New(update));
-            if (!update->addPredecessor(current))
+            current->end(MGoto::New(alloc(), update));
+            if (!update->addPredecessor(alloc(), current))
                 return ControlStatus_Error;
         }
 
         // No need to use addPredecessor for first edge,
         // because it is already predecessor.
-        edge->block->end(MGoto::New(update));
+        edge->block->end(MGoto::New(alloc(), update));
         edge = edge->next;
 
         // Remaining edges
         while (edge) {
-            edge->block->end(MGoto::New(update));
-            if (!update->addPredecessor(edge->block))
+            edge->block->end(MGoto::New(alloc(), update));
+            if (!update->addPredecessor(alloc(), edge->block))
                 return ControlStatus_Error;
             edge = edge->next;
         }
         state.loop.continues = nullptr;
 
         setCurrentAndSpecializePhis(update);
     }
 
@@ -2235,23 +2236,23 @@ IonBuilder::createBreakCatchBlock(Deferr
 
     // Create block, using the first break statement as predecessor
     MBasicBlock *successor = newBlock(edge->block, pc);
     if (!successor)
         return nullptr;
 
     // No need to use addPredecessor for first edge,
     // because it is already predecessor.
-    edge->block->end(MGoto::New(successor));
+    edge->block->end(MGoto::New(alloc(), successor));
     edge = edge->next;
 
     // Finish up remaining breaks.
     while (edge) {
-        edge->block->end(MGoto::New(successor));
-        if (!successor->addPredecessor(edge->block))
+        edge->block->end(MGoto::New(alloc(), successor));
+        if (!successor->addPredecessor(alloc(), edge->block))
             return nullptr;
         edge = edge->next;
     }
 
     return successor;
 }
 
 IonBuilder::ControlStatus
@@ -2267,18 +2268,18 @@ IonBuilder::processNextTableSwitchCase(C
 
     // Get the next successor
     MBasicBlock *successor = state.tableswitch.ins->getBlock(state.tableswitch.currentBlock);
 
     // Add current block as predecessor if available.
     // This means the previous case didn't have a break statement.
     // So flow will continue in this block.
     if (current) {
-        current->end(MGoto::New(successor));
-        successor->addPredecessor(current);
+        current->end(MGoto::New(alloc(), successor));
+        successor->addPredecessor(alloc(), current);
     }
 
     // Insert successor after the current block, to maintain RPO.
     graph().moveBlockToEnd(successor);
 
     // If this is the last successor the block should stop at the end of the tableswitch
     // Else it should stop at the start of the next successor
     if (state.tableswitch.currentBlock+1 < state.tableswitch.ins->numBlocks())
@@ -2291,19 +2292,19 @@ IonBuilder::processNextTableSwitchCase(C
     return ControlStatus_Jumped;
 }
 
 IonBuilder::ControlStatus
 IonBuilder::processAndOrEnd(CFGState &state)
 {
     // We just processed the RHS of an && or || expression.
     // Now jump to the join point (the false block).
-    current->end(MGoto::New(state.branch.ifFalse));
-
-    if (!state.branch.ifFalse->addPredecessor(current))
+    current->end(MGoto::New(alloc(), state.branch.ifFalse));
+
+    if (!state.branch.ifFalse->addPredecessor(alloc(), current))
         return ControlStatus_Error;
 
     setCurrentAndSpecializePhis(state.branch.ifFalse);
     graph().moveBlockToEnd(current);
     pc = current->pc();
     return ControlStatus_Joined;
 }
 
@@ -2320,18 +2321,18 @@ IonBuilder::processLabelEnd(CFGState &st
     if (!state.label.breaks)
         return ControlStatus_Joined;
 
     MBasicBlock *successor = createBreakCatchBlock(state.label.breaks, state.stopAt);
     if (!successor)
         return ControlStatus_Error;
 
     if (current) {
-        current->end(MGoto::New(successor));
-        successor->addPredecessor(current);
+        current->end(MGoto::New(alloc(), successor));
+        successor->addPredecessor(alloc(), current);
     }
 
     pc = state.stopAt;
     setCurrentAndSpecializePhis(successor);
     return ControlStatus_Joined;
 }
 
 IonBuilder::ControlStatus
@@ -2340,19 +2341,19 @@ IonBuilder::processTryEnd(CFGState &stat
     JS_ASSERT(state.state == CFGState::TRY);
 
     if (!state.try_.successor) {
         JS_ASSERT(!current);
         return ControlStatus_Ended;
     }
 
     if (current) {
-        current->end(MGoto::New(state.try_.successor));
-
-        if (!state.try_.successor->addPredecessor(current))
+        current->end(MGoto::New(alloc(), state.try_.successor));
+
+        if (!state.try_.successor->addPredecessor(alloc(), current))
             return ControlStatus_Error;
     }
 
     // Start parsing the code after this try-catch statement.
     setCurrentAndSpecializePhis(state.try_.successor);
     graph().moveBlockToEnd(current);
     pc = current->pc();
     return ControlStatus_Joined;
@@ -2494,19 +2495,19 @@ IonBuilder::processSwitchEnd(DeferredEdg
         successor = newBlock(current, exitpc);
 
     if (!successor)
         return ControlStatus_Ended;
 
     // If there is current, the current block flows into this one.
     // So current is also a predecessor to this block
     if (current) {
-        current->end(MGoto::New(successor));
+        current->end(MGoto::New(alloc(), successor));
         if (breaks)
-            successor->addPredecessor(current);
+            successor->addPredecessor(alloc(), current);
     }
 
     pc = exitpc;
     setCurrentAndSpecializePhis(successor);
     return ControlStatus_Joined;
 }
 
 IonBuilder::ControlStatus
@@ -2610,24 +2611,24 @@ IonBuilder::doWhileLoop(JSOp op, jssrcno
 
     jsbytecode *loopEntry = GetNextPc(loopHead);
     bool osr = info().hasOsrAt(loopEntry);
 
     if (osr) {
         MBasicBlock *preheader = newOsrPreheader(current, loopEntry);
         if (!preheader)
             return ControlStatus_Error;
-        current->end(MGoto::New(preheader));
+        current->end(MGoto::New(alloc(), preheader));
         setCurrentAndSpecializePhis(preheader);
     }
 
     MBasicBlock *header = newPendingLoopHeader(current, pc, osr);
     if (!header)
         return ControlStatus_Error;
-    current->end(MGoto::New(header));
+    current->end(MGoto::New(alloc(), header));
 
     jsbytecode *loophead = GetNextPc(pc);
     jsbytecode *bodyStart = GetNextPc(loophead);
     jsbytecode *bodyEnd = conditionpc;
     jsbytecode *exitpc = GetNextPc(ifne);
     analyzeNewLoopTypes(header, bodyStart, exitpc);
     if (!pushLoop(CFGState::DO_WHILE_LOOP_BODY, conditionpc, header, osr,
                   loopHead, bodyStart, bodyStart, bodyEnd, exitpc, conditionpc))
@@ -2670,24 +2671,24 @@ IonBuilder::whileOrForInLoop(jssrcnote *
 
     jsbytecode *loopEntry = pc + GetJumpOffset(pc);
     bool osr = info().hasOsrAt(loopEntry);
 
     if (osr) {
         MBasicBlock *preheader = newOsrPreheader(current, loopEntry);
         if (!preheader)
             return ControlStatus_Error;
-        current->end(MGoto::New(preheader));
+        current->end(MGoto::New(alloc(), preheader));
         setCurrentAndSpecializePhis(preheader);
     }
 
     MBasicBlock *header = newPendingLoopHeader(current, pc, osr);
     if (!header)
         return ControlStatus_Error;
-    current->end(MGoto::New(header));
+    current->end(MGoto::New(alloc(), header));
 
     // Skip past the JSOP_LOOPHEAD for the body start.
     jsbytecode *loopHead = GetNextPc(pc);
     jsbytecode *bodyStart = GetNextPc(loopHead);
     jsbytecode *bodyEnd = pc + GetJumpOffset(pc);
     jsbytecode *exitpc = GetNextPc(ifne);
     analyzeNewLoopTypes(header, bodyStart, exitpc);
     if (!pushLoop(CFGState::WHILE_LOOP_COND, ifne, header, osr,
@@ -2754,24 +2755,24 @@ IonBuilder::forLoop(JSOp op, jssrcnote *
     bodyStart = GetNextPc(bodyStart);
 
     bool osr = info().hasOsrAt(loopEntry);
 
     if (osr) {
         MBasicBlock *preheader = newOsrPreheader(current, loopEntry);
         if (!preheader)
             return ControlStatus_Error;
-        current->end(MGoto::New(preheader));
+        current->end(MGoto::New(alloc(), preheader));
         setCurrentAndSpecializePhis(preheader);
     }
 
     MBasicBlock *header = newPendingLoopHeader(current, pc, osr);
     if (!header)
         return ControlStatus_Error;
-    current->end(MGoto::New(header));
+    current->end(MGoto::New(alloc(), header));
 
     // If there is no condition, we immediately parse the body. Otherwise, we
     // parse the condition.
     jsbytecode *stopAt;
     CFGState::State initial;
     if (condpc != ifne) {
         pc = condpc;
         stopAt = ifne;
@@ -2843,17 +2844,17 @@ IonBuilder::tableSwitch(JSOp op, jssrcno
     jsbytecode *pc2 = pc;
     pc2 += JUMP_OFFSET_LEN;
     int low = GET_JUMP_OFFSET(pc2);
     pc2 += JUMP_OFFSET_LEN;
     int high = GET_JUMP_OFFSET(pc2);
     pc2 += JUMP_OFFSET_LEN;
 
     // Create MIR instruction
-    MTableSwitch *tableswitch = MTableSwitch::New(ins, low, high);
+    MTableSwitch *tableswitch = MTableSwitch::New(alloc(), ins, low, high);
 
     // Create default case
     MBasicBlock *defaultcase = newBlock(current, defaultpc);
     if (!defaultcase)
         return ControlStatus_Error;
     tableswitch->addDefault(defaultcase);
     tableswitch->addBlock(defaultcase);
 
@@ -2868,18 +2869,18 @@ IonBuilder::tableSwitch(JSOp op, jssrcno
         if (!caseblock)
             return ControlStatus_Error;
 
         // If the casepc equals the current pc, it is not a written case,
         // but a filled gap. That way we can use a tableswitch instead of
         // condswitch, even if not all numbers are consecutive.
         // In that case this block goes to the default case
         if (casepc == pc) {
-            caseblock->end(MGoto::New(defaultcase));
-            defaultcase->addPredecessor(caseblock);
+            caseblock->end(MGoto::New(alloc(), defaultcase));
+            defaultcase->addPredecessor(alloc(), caseblock);
         }
 
         tableswitch->addCase(tableswitch->addSuccessor(caseblock));
 
         // If this is an actual case (not filled gap),
         // add this block to the list that still needs to get processed
         if (casepc != pc)
             tableswitch->addBlock(caseblock);
@@ -3019,17 +3020,17 @@ IonBuilder::jsop_condswitch()
 }
 
 IonBuilder::CFGState
 IonBuilder::CFGState::CondSwitch(IonBuilder *builder, jsbytecode *exitpc, jsbytecode *defaultTarget)
 {
     CFGState state;
     state.state = COND_SWITCH_CASE;
     state.stopAt = nullptr;
-    state.condswitch.bodies = (FixedList<MBasicBlock *> *)builder->temp_->allocate(
+    state.condswitch.bodies = (FixedList<MBasicBlock *> *)builder->alloc_->allocate(
         sizeof(FixedList<MBasicBlock *>));
     state.condswitch.currentIdx = 0;
     state.condswitch.defaultTarget = defaultTarget;
     state.condswitch.defaultIdx = uint32_t(-1);
     state.condswitch.exitpc = exitpc;
     state.condswitch.breaks = nullptr;
     return state;
 }
@@ -3145,41 +3146,41 @@ IonBuilder::processCondSwitchCase(CFGSta
     if (!caseBlock)
         return ControlStatus_Error;
 
     // Terminate the last case condition block by emitting the code
     // corresponding to JSOP_CASE bytecode.
     if (bodyBlock != caseBlock) {
         MDefinition *caseOperand = current->pop();
         MDefinition *switchOperand = current->peek(-1);
-        MCompare *cmpResult = MCompare::New(switchOperand, caseOperand, JSOP_STRICTEQ);
+        MCompare *cmpResult = MCompare::New(alloc(), switchOperand, caseOperand, JSOP_STRICTEQ);
         cmpResult->infer(inspector, pc);
         JS_ASSERT(!cmpResult->isEffectful());
         current->add(cmpResult);
-        current->end(MTest::New(cmpResult, bodyBlock, caseBlock));
+        current->end(MTest::New(alloc(), cmpResult, bodyBlock, caseBlock));
 
         // Add last case as predecessor of the body if the body is aliasing
         // the previous case body.
-        if (!bodyIsNew && !bodyBlock->addPredecessorPopN(current, 1))
+        if (!bodyIsNew && !bodyBlock->addPredecessorPopN(alloc(), current, 1))
             return ControlStatus_Error;
 
         // Add last case as predecessor of the non-matching case if the
         // non-matching case is an aliased default case. We need to pop the
         // switch operand as we skip the default case block and use the default
         // body block directly.
         JS_ASSERT_IF(!caseIsNew, caseIsDefault);
-        if (!caseIsNew && !caseBlock->addPredecessorPopN(current, 1))
+        if (!caseIsNew && !caseBlock->addPredecessorPopN(alloc(), current, 1))
             return ControlStatus_Error;
     } else {
         // The default case alias the last case body.
         JS_ASSERT(caseIsDefault);
         current->pop(); // Case operand
         current->pop(); // Switch operand
-        current->end(MGoto::New(bodyBlock));
-        if (!bodyIsNew && !bodyBlock->addPredecessor(current))
+        current->end(MGoto::New(alloc(), bodyBlock));
+        if (!bodyIsNew && !bodyBlock->addPredecessor(alloc(), current))
             return ControlStatus_Error;
     }
 
     if (caseIsDefault) {
         // The last case condition is finished.  Loop in processCondSwitchBody,
         // with potential stops in processSwitchBreak.  Check that the bodies
         // fixed list is over-estimate by at most 1, and shrink the size such as
         // length can be used as an upper bound while iterating bodies.
@@ -3224,18 +3225,18 @@ IonBuilder::processCondSwitchBody(CFGSta
     MBasicBlock *nextBody = bodies[currentIdx++];
     JS_ASSERT_IF(current, pc == nextBody->pc());
 
     // Fix the reverse post-order iteration.
     graph().moveBlockToEnd(nextBody);
 
     // The last body continue into the new one.
     if (current) {
-        current->end(MGoto::New(nextBody));
-        nextBody->addPredecessor(current);
+        current->end(MGoto::New(alloc(), nextBody));
+        nextBody->addPredecessor(alloc(), current);
     }
 
     // Continue in the next body.
     setCurrentAndSpecializePhis(nextBody);
     pc = current->pc();
 
     if (currentIdx < bodies.length())
         state.stopAt = bodies[currentIdx]->pc();
@@ -3257,18 +3258,18 @@ IonBuilder::jsop_andor(JSOp op)
     MDefinition *lhs = current->peek(-1);
 
     MBasicBlock *evalRhs = newBlock(current, rhsStart);
     MBasicBlock *join = newBlock(current, joinStart);
     if (!evalRhs || !join)
         return false;
 
     MTest *test = (op == JSOP_AND)
-                  ? MTest::New(lhs, evalRhs, join)
-                  : MTest::New(lhs, join, evalRhs);
+                  ? MTest::New(alloc(), lhs, evalRhs, join)
+                  : MTest::New(alloc(), lhs, join, evalRhs);
     test->infer();
     current->end(test);
 
     if (!cfgStack_.append(CFGState::AndOr(joinStart, join)))
         return false;
 
     setCurrentAndSpecializePhis(evalRhs);
     return true;
@@ -3284,17 +3285,17 @@ IonBuilder::jsop_dup2()
     return true;
 }
 
 bool
 IonBuilder::jsop_loophead(jsbytecode *pc)
 {
     assertValidLoopHeadOp(pc);
 
-    current->add(MInterruptCheck::New());
+    current->add(MInterruptCheck::New(alloc()));
 
     return true;
 }
 
 bool
 IonBuilder::jsop_ifeq(JSOp op)
 {
     // IFEQ always has a forward offset.
@@ -3310,17 +3311,17 @@ IonBuilder::jsop_ifeq(JSOp op)
     MDefinition *ins = current->pop();
 
     // Create true and false branches.
     MBasicBlock *ifTrue = newBlock(current, trueStart);
     MBasicBlock *ifFalse = newBlock(current, falseStart);
     if (!ifTrue || !ifFalse)
         return false;
 
-    MTest *test = MTest::New(ins, ifTrue, ifFalse);
+    MTest *test = MTest::New(alloc(), ins, ifTrue, ifFalse);
     current->end(test);
 
     // The bytecode for if/ternary gets emitted either like this:
     //
     //    IFEQ X  ; src note (IF_ELSE, COND) points to the GOTO
     //    ...
     //    GOTO Z
     // X: ...     ; else/else if
@@ -3429,22 +3430,22 @@ IonBuilder::jsop_try()
 
     MBasicBlock *successor;
     if (analysis().maybeInfo(afterTry)) {
         successor = newBlock(current, afterTry);
         if (!successor)
             return false;
 
         // Add MTest(true, tryBlock, successorBlock).
-        MConstant *true_ = MConstant::New(BooleanValue(true));
+        MConstant *true_ = MConstant::New(alloc(), BooleanValue(true));
         current->add(true_);
-        current->end(MTest::New(true_, tryBlock, successor));
+        current->end(MTest::New(alloc(), true_, tryBlock, successor));
     } else {
         successor = nullptr;
-        current->end(MGoto::New(tryBlock));
+        current->end(MGoto::New(alloc(), tryBlock));
     }
 
     if (!cfgStack_.append(CFGState::Try(endpc, successor)))
         return false;
 
     // The baseline compiler should not attempt to enter the catch block
     // via OSR.
     JS_ASSERT(info().osrPc() < endpc || info().osrPc() >= afterTry);
@@ -3462,33 +3463,33 @@ IonBuilder::processReturn(JSOp op)
       case JSOP_RETURN:
         // Return the last instruction.
         def = current->pop();
         break;
 
       case JSOP_RETRVAL:
         // Return undefined eagerly if script doesn't use return value.
         if (script()->noScriptRval) {
-            MInstruction *ins = MConstant::New(UndefinedValue());
+            MInstruction *ins = MConstant::New(alloc(), UndefinedValue());
             current->add(ins);
             def = ins;
             break;
         }
 
         def = current->getSlot(info().returnValueSlot());
         break;
 
       default:
         def = nullptr;
         MOZ_ASSUME_UNREACHABLE("unknown return op");
     }
 
     if (instrumentedProfiling())
-        current->add(MFunctionBoundary::New(script(), MFunctionBoundary::Exit));
-    MReturn *ret = MReturn::New(def);
+        current->add(MFunctionBoundary::New(alloc(), script(), MFunctionBoundary::Exit));
+    MReturn *ret = MReturn::New(alloc(), def);
     current->end(ret);
 
     if (!graph().addExit(current))
         return ControlStatus_Error;
 
     // Make sure no one tries to use this block now.
     setCurrent(nullptr);
     return processControlEnd();
@@ -3520,48 +3521,48 @@ IonBuilder::processThrow()
         // ])();
         //
         // If we use the resume point after the call, this will print 1 instead
         // of 2. To fix this, we create a resume point right before the MThrow.
         //
         // Note that this is not a problem for instructions other than MThrow
         // because they are either marked as effectful (have their own resume
         // point) or cannot throw a catchable exception.
-        MNop *ins = MNop::New();
+        MNop *ins = MNop::New(alloc());
         current->add(ins);
 
         if (!resumeAfter(ins))
             return ControlStatus_Error;
     }
 
-    MThrow *ins = MThrow::New(def);
+    MThrow *ins = MThrow::New(alloc(), def);
     current->end(ins);
 
     if (!graph().addExit(current))
         return ControlStatus_Error;
 
     // Make sure no one tries to use this block now.
     setCurrent(nullptr);
     return processControlEnd();
 }
 
 bool
 IonBuilder::pushConstant(const Value &v)
 {
-    MConstant *ins = MConstant::New(v);
+    MConstant *ins = MConstant::New(alloc(), v);
     current->add(ins);
     current->push(ins);
     return true;
 }
 
 bool
 IonBuilder::jsop_bitnot()
 {
     MDefinition *input = current->pop();
-    MBitNot *ins = MBitNot::New(input);
+    MBitNot *ins = MBitNot::New(alloc(), input);
 
     current->add(ins);
     ins->infer();
 
     current->push(ins);
     if (ins->isEffectful() && !resumeAfter(ins))
         return false;
     return true;
@@ -3571,37 +3572,37 @@ IonBuilder::jsop_bitop(JSOp op)
 {
     // Pop inputs.
     MDefinition *right = current->pop();
     MDefinition *left = current->pop();
 
     MBinaryBitwiseInstruction *ins;
     switch (op) {
       case JSOP_BITAND:
-        ins = MBitAnd::New(left, right);
+        ins = MBitAnd::New(alloc(), left, right);
         break;
 
       case JSOP_BITOR:
-        ins = MBitOr::New(left, right);
+        ins = MBitOr::New(alloc(), left, right);
         break;
 
       case JSOP_BITXOR:
-        ins = MBitXor::New(left, right);
+        ins = MBitXor::New(alloc(), left, right);
         break;
 
       case JSOP_LSH:
-        ins = MLsh::New(left, right);
+        ins = MLsh::New(alloc(), left, right);
         break;
 
       case JSOP_RSH:
-        ins = MRsh::New(left, right);
+        ins = MRsh::New(alloc(), left, right);
         break;
 
       case JSOP_URSH:
-        ins = MUrsh::New(left, right);
+        ins = MUrsh::New(alloc(), left, right);
         break;
 
       default:
         MOZ_ASSUME_UNREACHABLE("unexpected bitop");
     }
 
     current->add(ins);
     ins->infer(inspector, pc);
@@ -3623,50 +3624,50 @@ IonBuilder::jsop_binary(JSOp op, MDefini
           (right->type() == MIRType_String ||
            right->type() == MIRType_Int32 ||
            right->type() == MIRType_Double)) ||
          (left->type() == MIRType_Int32 &&
           right->type() == MIRType_String) ||
          (left->type() == MIRType_Double &&
           right->type() == MIRType_String)))
     {
-        MConcat *ins = MConcat::New(left, right);
+        MConcat *ins = MConcat::New(alloc(), left, right);
         current->add(ins);
         current->push(ins);
         return maybeInsertResume();
     }
 
     MBinaryArithInstruction *ins;
     switch (op) {
       case JSOP_ADD:
-        ins = MAdd::New(left, right);
+        ins = MAdd::New(alloc(), left, right);
         break;
 
       case JSOP_SUB:
-        ins = MSub::New(left, right);
+        ins = MSub::New(alloc(), left, right);
         break;
 
       case JSOP_MUL:
-        ins = MMul::New(left, right);
+        ins = MMul::New(alloc(), left, right);
         break;
 
       case JSOP_DIV:
-        ins = MDiv::New(left, right);
+        ins = MDiv::New(alloc(), left, right);
         break;
 
       case JSOP_MOD:
-        ins = MMod::New(left, right);
+        ins = MMod::New(alloc(), left, right);
         break;
 
       default:
         MOZ_ASSUME_UNREACHABLE("unexpected binary opcode");
     }
 
     current->add(ins);
-    ins->infer(inspector, pc);
+    ins->infer(alloc(), inspector, pc);
     current->push(ins);
 
     if (ins->isEffectful())
         return resumeAfter(ins);
     return maybeInsertResume();
 }
 
 bool
@@ -3683,44 +3684,44 @@ IonBuilder::jsop_pos()
 {
     if (IsNumberType(current->peek(-1)->type())) {
         // Already int32 or double.
         return true;
     }
 
     // Compile +x as x * 1.
     MDefinition *value = current->pop();
-    MConstant *one = MConstant::New(Int32Value(1));
+    MConstant *one = MConstant::New(alloc(), Int32Value(1));
     current->add(one);
 
     return jsop_binary(JSOP_MUL, value, one);
 }
 
 bool
 IonBuilder::jsop_neg()
 {
     // Since JSOP_NEG does not use a slot, we cannot push the MConstant.
     // The MConstant is therefore passed to JSOP_MUL without slot traffic.
-    MConstant *negator = MConstant::New(Int32Value(-1));
+    MConstant *negator = MConstant::New(alloc(), Int32Value(-1));
     current->add(negator);
 
     MDefinition *right = current->pop();
 
     if (!jsop_binary(JSOP_MUL, negator, right))
         return false;
     return true;
 }
 
 bool
 IonBuilder::jsop_notearg()
 {
     // JSOP_NOTEARG notes that the value in current->pop() has just
     // been pushed onto the stack for use in calling a function.
     MDefinition *def = current->pop();
-    MPassArg *arg = MPassArg::New(def);
+    MPassArg *arg = MPassArg::New(alloc(), def);
 
     current->add(arg);
     current->push(arg);
     return true;
 }
 
 class AutoAccumulateExits
 {
@@ -3763,17 +3764,17 @@ IonBuilder::inlineScriptedCall(CallInfo 
             return false;
         callInfo.setThis(thisDefn);
     }
 
     // Capture formals in the outer resume point.
     callInfo.pushFormals(current);
 
     MResumePoint *outerResumePoint =
-        MResumePoint::New(current, pc, callerResumePoint_, MResumePoint::Outer);
+        MResumePoint::New(alloc(), current, pc, callerResumePoint_, MResumePoint::Outer);
     if (!outerResumePoint)
         return false;
 
     // Pop formals again, except leave |fun| on stack for duration of call.
     callInfo.popFormals(current);
     current->push(callInfo.fun());
 
     JSScript *calleeScript = target->nonLazyScript();
@@ -3782,37 +3783,37 @@ IonBuilder::inlineScriptedCall(CallInfo 
     // Improve type information of |this| when not set.
     if (callInfo.constructing() &&
         !callInfo.thisArg()->resultTypeSet() &&
         calleeScript->types)
     {
         types::StackTypeSet *types = types::TypeScript::ThisTypes(calleeScript);
         if (!types->unknown()) {
             MTypeBarrier *barrier =
-                MTypeBarrier::New(callInfo.thisArg(), types->clone(temp_->lifoAlloc()));
+                MTypeBarrier::New(alloc(), callInfo.thisArg(), types->clone(alloc_->lifoAlloc()));
             current->add(barrier);
             callInfo.setThis(barrier);
         }
     }
 
     // Start inlining.
-    LifoAlloc *alloc = temp_->lifoAlloc();
-    CompileInfo *info = alloc->new_<CompileInfo>(calleeScript, target,
-                                                 (jsbytecode *)nullptr, callInfo.constructing(),
-                                                 this->info().executionMode());
+    LifoAlloc *lifoAlloc = alloc_->lifoAlloc();
+    CompileInfo *info = lifoAlloc->new_<CompileInfo>(calleeScript, target,
+                                                     (jsbytecode *)nullptr, callInfo.constructing(),
+                                                     this->info().executionMode());
     if (!info)
         return false;
 
     MIRGraphExits saveExits;
     AutoAccumulateExits aae(graph(), saveExits);
 
     // Build the graph.
     JS_ASSERT_IF(analysisContext, !analysisContext->isExceptionPending());
     IonBuilder inlineBuilder(analysisContext, compartment,
-                             &temp(), &graph(), constraints(), &inspector, info, nullptr,
+                             &alloc(), &graph(), constraints(), &inspector, info, nullptr,
                              inliningDepth_ + 1, loopDepth_);
     if (!inlineBuilder.buildInline(this, outerResumePoint, callInfo)) {
         if (analysisContext && analysisContext->isExceptionPending()) {
             IonSpew(IonSpew_Abort, "Inline builder raised exception.");
             abortReason_ = AbortReason_Error;
             return false;
         }
 
@@ -3832,17 +3833,17 @@ IonBuilder::inlineScriptedCall(CallInfo 
     jsbytecode *postCall = GetNextPc(pc);
     MBasicBlock *returnBlock = newBlock(nullptr, postCall);
     if (!returnBlock)
         return false;
     returnBlock->setCallerResumePoint(callerResumePoint_);
 
     // When profiling add Inline_Exit instruction to indicate end of inlined function.
     if (instrumentedProfiling())
-        returnBlock->add(MFunctionBoundary::New(nullptr, MFunctionBoundary::Inline_Exit));
+        returnBlock->add(MFunctionBoundary::New(alloc(), nullptr, MFunctionBoundary::Inline_Exit));
 
     // Inherit the slots from current and pop |fun|.
     returnBlock->inheritSlots(current);
     returnBlock->pop();
 
     // Accumulate return values.
     MIRGraphExits &exits = *inlineBuilder.graph().exitAccumulator();
     if (exits.length() == 0) {
@@ -3852,17 +3853,17 @@ IonBuilder::inlineScriptedCall(CallInfo 
         return false;
     }
     MDefinition *retvalDefn = patchInlinedReturns(callInfo, exits, returnBlock);
     if (!retvalDefn)
         return false;
     returnBlock->push(retvalDefn);
 
     // Initialize entry slots now that the stack has been fixed up.
-    if (!returnBlock->initEntrySlots())
+    if (!returnBlock->initEntrySlots(alloc()))
         return false;
 
     setCurrentAndSpecializePhis(returnBlock);
     return true;
 }
 
 MDefinition *
 IonBuilder::patchInlinedReturn(CallInfo &callInfo, MBasicBlock *exit, MBasicBlock *bottom)
@@ -3870,29 +3871,29 @@ IonBuilder::patchInlinedReturn(CallInfo 
     // Replaces the MReturn in the exit block with an MGoto.
     MDefinition *rdef = exit->lastIns()->toReturn()->input();
     exit->discardLastIns();
 
     // Constructors must be patched by the caller to always return an object.
     if (callInfo.constructing()) {
         if (rdef->type() == MIRType_Value) {
             // Unknown return: dynamically detect objects.
-            MReturnFromCtor *filter = MReturnFromCtor::New(rdef, callInfo.thisArg());
+            MReturnFromCtor *filter = MReturnFromCtor::New(alloc(), rdef, callInfo.thisArg());
             exit->add(filter);
             rdef = filter;
         } else if (rdef->type() != MIRType_Object) {
             // Known non-object return: force |this|.
             rdef = callInfo.thisArg();
         }
     } else if (callInfo.isSetter()) {
         // Setters return their argument, not whatever value is returned.
         rdef = callInfo.getArg(0);
     }
 
-    MGoto *replacement = MGoto::New(bottom);
+    MGoto *replacement = MGoto::New(alloc(), bottom);
     exit->end(replacement);
     if (!bottom->addPredecessorWithoutPhis(exit))
         return nullptr;
 
     return rdef;
 }
 
 MDefinition *
@@ -3901,17 +3902,17 @@ IonBuilder::patchInlinedReturns(CallInfo
     // Replaces MReturns with MGotos, returning the MDefinition
     // representing the return value, or nullptr.
     JS_ASSERT(exits.length() > 0);
 
     if (exits.length() == 1)
         return patchInlinedReturn(callInfo, exits[0], bottom);
 
     // Accumulate multiple returns with a phi.
-    MPhi *phi = MPhi::New(bottom->stackDepth());
+    MPhi *phi = MPhi::New(alloc(), bottom->stackDepth());
     if (!phi->reserveLength(exits.length()))
         return nullptr;
 
     for (size_t i = 0; i < exits.length(); i++) {
         MDefinition *rdef = patchInlinedReturn(callInfo, exits[i], bottom);
         if (!rdef)
             return nullptr;
         phi->addInput(rdef);
@@ -4141,17 +4142,17 @@ IonBuilder::inlineCallsite(ObjectVector 
         // folded to ensure this happens.
         callInfo.fun()->setFoldedUnchecked();
 
         // If the callee is not going to be a lambda (which may vary across
         // different invocations), then the callee definition can be replaced by a
         // constant.
         if (!lambda) {
             // Replace the function with an MConstant.
-            MConstant *constFun = MConstant::New(ObjectValue(*target));
+            MConstant *constFun = MConstant::New(alloc(), ObjectValue(*target));
             current->add(constFun);
             callInfo.setFun(constFun);
         }
 
         return inlineSingleCall(callInfo, target);
     }
 
     // Choose a subset of the targets for polymorphic inlining.
@@ -4176,17 +4177,17 @@ IonBuilder::inlineGenericFallback(JSFunc
     if (!fallbackBlock)
         return false;
 
     // Create a new CallInfo to track modified state within this block.
     CallInfo fallbackInfo(callInfo.constructing());
     if (!fallbackInfo.init(callInfo))
         return false;
     fallbackInfo.popFormals(fallbackBlock);
-    fallbackInfo.wrapArgs(fallbackBlock);
+    fallbackInfo.wrapArgs(alloc(), fallbackBlock);
 
     // Generate an MCall, which uses stateful |current|.
     setCurrentAndSpecializePhis(fallbackBlock);
     if (!makeCall(target, fallbackInfo, clonedAtCallsite))
         return false;
 
     // Pass return block to caller as |current|.
     return true;
@@ -4216,25 +4217,25 @@ IonBuilder::inlineTypeObjectFallback(Cal
 
     // Create a new CallInfo to track modified state within the fallback path.
     CallInfo fallbackInfo(callInfo.constructing());
     if (!fallbackInfo.init(callInfo))
         return false;
 
     // Capture stack prior to the call operation. This captures the function.
     MResumePoint *preCallResumePoint =
-        MResumePoint::New(dispatchBlock, pc, callerResumePoint_, MResumePoint::ResumeAt);
+        MResumePoint::New(alloc(), dispatchBlock, pc, callerResumePoint_, MResumePoint::ResumeAt);
     if (!preCallResumePoint)
         return false;
 
     DebugOnly<size_t> preCallFuncIndex = preCallResumePoint->numOperands() - callInfo.numFormals();
     JS_ASSERT(preCallResumePoint->getOperand(preCallFuncIndex) == fallbackInfo.fun());
 
     // In the dispatch block, replace the function's slot entry with Undefined.
-    MConstant *undefined = MConstant::New(UndefinedValue());
+    MConstant *undefined = MConstant::New(alloc(), UndefinedValue());
     dispatchBlock->add(undefined);
     dispatchBlock->rewriteAtDepth(-int(callInfo.numFormals()), undefined);
 
     // Construct a block that does nothing but remove formals from the stack.
     // This is effectively changing the entry resume point of the later fallback block.
     MBasicBlock *prepBlock = newBlock(dispatchBlock, pc);
     if (!prepBlock)
         return false;
@@ -4244,17 +4245,17 @@ IonBuilder::inlineTypeObjectFallback(Cal
     // This is subtle: the pc and resume point are those of the MGetPropertyCache!
     InlinePropertyTable *propTable = cache->propTable();
     JS_ASSERT(propTable->pc() != nullptr);
     JS_ASSERT(propTable->priorResumePoint() != nullptr);
     MBasicBlock *getPropBlock = newBlock(prepBlock, propTable->pc(), propTable->priorResumePoint());
     if (!getPropBlock)
         return false;
 
-    prepBlock->end(MGoto::New(getPropBlock));
+    prepBlock->end(MGoto::New(alloc(), getPropBlock));
 
     // Since the getPropBlock inherited the stack from right before the MGetPropertyCache,
     // the target of the MGetPropertyCache is still on the stack.
     DebugOnly<MDefinition *> checkObject = getPropBlock->pop();
     JS_ASSERT(checkObject == cache->object());
 
     // Move the MGetPropertyCache and friends into the getPropBlock.
     if (fallbackInfo.fun()->isGetPropertyCache()) {
@@ -4271,24 +4272,24 @@ IonBuilder::inlineTypeObjectFallback(Cal
         getPropBlock->addFromElsewhere(barrier);
         getPropBlock->push(barrier);
     }
 
     // Construct an end block with the correct resume point.
     MBasicBlock *preCallBlock = newBlock(getPropBlock, pc, preCallResumePoint);
     if (!preCallBlock)
         return false;
-    getPropBlock->end(MGoto::New(preCallBlock));
+    getPropBlock->end(MGoto::New(alloc(), preCallBlock));
 
     // Now inline the MCallGeneric, using preCallBlock as the dispatch point.
     if (!inlineGenericFallback(nullptr, fallbackInfo, preCallBlock, false))
         return false;
 
     // inlineGenericFallback() set the return block as |current|.
-    preCallBlock->end(MGoto::New(current));
+    preCallBlock->end(MGoto::New(alloc(), current));
     *fallbackTarget = prepBlock;
     return true;
 }
 
 bool
 IonBuilder::inlineCalls(CallInfo &callInfo, ObjectVector &targets,
                         ObjectVector &originals, BoolVector &choiceSet,
                         MGetPropertyCache *maybeCache)
@@ -4319,39 +4320,39 @@ IonBuilder::inlineCalls(CallInfo &callIn
         propTable->trimToTargets(originals);
         if (propTable->numEntries() == 0)
             maybeCache = nullptr;
     }
 
     // Generate a dispatch based on guard kind.
     MDispatchInstruction *dispatch;
     if (maybeCache) {
-        dispatch = MTypeObjectDispatch::New(maybeCache->object(), maybeCache->propTable());
+        dispatch = MTypeObjectDispatch::New(alloc(), maybeCache->object(), maybeCache->propTable());
         callInfo.fun()->setFoldedUnchecked();
     } else {
-        dispatch = MFunctionDispatch::New(callInfo.fun());
+        dispatch = MFunctionDispatch::New(alloc(), callInfo.fun());
     }
 
     // Generate a return block to host the rval-collecting MPhi.
     jsbytecode *postCall = GetNextPc(pc);
     MBasicBlock *returnBlock = newBlock(nullptr, postCall);
     if (!returnBlock)
         return false;
     returnBlock->setCallerResumePoint(callerResumePoint_);
 
     // Set up stack, used to manually create a post-call resume point.
     returnBlock->inheritSlots(dispatchBlock);
     callInfo.popFormals(returnBlock);
 
-    MPhi *retPhi = MPhi::New(returnBlock->stackDepth());
+    MPhi *retPhi = MPhi::New(alloc(), returnBlock->stackDepth());
     returnBlock->addPhi(retPhi);
     returnBlock->push(retPhi);
 
     // Create a resume point from current stack state.
-    returnBlock->initEntrySlots();
+    returnBlock->initEntrySlots(alloc());
 
     // Reserve the capacity for the phi.
     // Note: this is an upperbound. Unreachable targets and uninlineable natives are also counted.
     uint32_t count = 1; // Possible fallback block.
     for (uint32_t i = 0; i < targets.length(); i++) {
         if (choiceSet[i])
             count++;
     }
@@ -4382,32 +4383,32 @@ IonBuilder::inlineCalls(CallInfo &callIn
             continue;
         }
 
         MBasicBlock *inlineBlock = newBlock(dispatchBlock, pc);
         if (!inlineBlock)
             return false;
 
         // Create a function MConstant to use in the entry ResumePoint.
-        MConstant *funcDef = MConstant::New(ObjectValue(*target));
+        MConstant *funcDef = MConstant::New(alloc(), ObjectValue(*target));
         funcDef->setFoldedUnchecked();
         dispatchBlock->add(funcDef);
 
         // Use the MConstant in the inline resume point and on stack.
         int funIndex = inlineBlock->entryResumePoint()->numOperands() - callInfo.numFormals();
         inlineBlock->entryResumePoint()->replaceOperand(funIndex, funcDef);
         inlineBlock->rewriteSlot(funIndex, funcDef);
 
         // Create a new CallInfo to track modified state within the inline block.
         CallInfo inlineInfo(callInfo.constructing());
         if (!inlineInfo.init(callInfo))
             return false;
         inlineInfo.popFormals(inlineBlock);
         inlineInfo.setFun(funcDef);
-        inlineInfo.wrapArgs(inlineBlock);
+        inlineInfo.wrapArgs(alloc(), inlineBlock);
 
         if (maybeCache) {
             JS_ASSERT(callInfo.thisArg() == maybeCache->object());
             types::TemporaryTypeSet *targetThisTypes =
                 maybeCache->propTable()->buildTypeSetForFunction(original);
             if (!targetThisTypes)
                 return false;
             maybeCache->object()->setResultTypeSet(targetThisTypes);
@@ -4436,17 +4437,17 @@ IonBuilder::inlineCalls(CallInfo &callIn
         // Connect the inline path to the returnBlock.
         //
         // Note that guarding is on the original function pointer even
         // if there is a clone, since cloning occurs at the callsite.
         dispatch->addCase(original, inlineBlock);
 
         MDefinition *retVal = inlineReturnBlock->peek(-1);
         retPhi->addInput(retVal);
-        inlineReturnBlock->end(MGoto::New(returnBlock));
+        inlineReturnBlock->end(MGoto::New(alloc(), returnBlock));
         if (!returnBlock->addPredecessorWithoutPhis(inlineReturnBlock))
             return false;
     }
 
     // Patch the InlinePropertyTable to not dispatch to vetoed paths.
     //
     // Note that like above, we trim using originals instead of targets.
     if (maybeCache) {
@@ -4496,17 +4497,17 @@ IonBuilder::inlineCalls(CallInfo &callIn
             dispatch->addFallback(current);
         }
 
         MBasicBlock *fallbackReturnBlock = current;
 
         // Connect fallback case to return infrastructure.
         MDefinition *retVal = fallbackReturnBlock->peek(-1);
         retPhi->addInput(retVal);
-        fallbackReturnBlock->end(MGoto::New(returnBlock));
+        fallbackReturnBlock->end(MGoto::New(alloc(), returnBlock));
         if (!returnBlock->addPredecessorWithoutPhis(fallbackReturnBlock))
             return false;
     }
 
     // Finally add the dispatch instruction.
     // This must be done at the end so that add() may be called above.
     dispatchBlock->end(dispatch);
 
@@ -4527,73 +4528,73 @@ IonBuilder::createDeclEnvObject(MDefinit
 
     // One field is added to the function to handle its name.  This cannot be a
     // dynamic slot because there is still plenty of room on the DeclEnv object.
     JS_ASSERT(!templateObj->hasDynamicSlots());
 
     // Allocate the actual object. It is important that no intervening
     // instructions could potentially bailout, thus leaking the dynamic slots
     // pointer.
-    MInstruction *declEnvObj = MNewDeclEnvObject::New(templateObj);
+    MInstruction *declEnvObj = MNewDeclEnvObject::New(alloc(), templateObj);
     current->add(declEnvObj);
 
     // Initialize the object's reserved slots. No post barrier is needed here:
     // the object will be allocated in the nursery if possible, and if the
     // tenured heap is used instead, a minor collection will have been performed
     // that moved scope/callee to the tenured heap.
-    current->add(MStoreFixedSlot::New(declEnvObj, DeclEnvObject::enclosingScopeSlot(), scope));
-    current->add(MStoreFixedSlot::New(declEnvObj, DeclEnvObject::lambdaSlot(), callee));
+    current->add(MStoreFixedSlot::New(alloc(), declEnvObj, DeclEnvObject::enclosingScopeSlot(), scope));
+    current->add(MStoreFixedSlot::New(alloc(), declEnvObj, DeclEnvObject::lambdaSlot(), callee));
 
     return declEnvObj;
 }
 
 MInstruction *
 IonBuilder::createCallObject(MDefinition *callee, MDefinition *scope)
 {
     // Get a template CallObject that we'll use to generate inline object
     // creation.
     CallObject *templateObj = inspector->templateCallObject();
 
     // If the CallObject needs dynamic slots, allocate those now.
     MInstruction *slots;
     if (templateObj->hasDynamicSlots()) {
         size_t nslots = JSObject::dynamicSlotsCount(templateObj->numFixedSlots(),
                                                     templateObj->slotSpan());
-        slots = MNewSlots::New(nslots);
+        slots = MNewSlots::New(alloc(), nslots);
     } else {
-        slots = MConstant::New(NullValue());
+        slots = MConstant::New(alloc(), NullValue());
     }
     current->add(slots);
 
     // Allocate the actual object. It is important that no intervening
     // instructions could potentially bailout, thus leaking the dynamic slots
     // pointer. Run-once scripts need a singleton type, so always do a VM call
     // in such cases.
-    MInstruction *callObj = MNewCallObject::New(templateObj, script()->treatAsRunOnce, slots);
+    MInstruction *callObj = MNewCallObject::New(alloc(), templateObj, script()->treatAsRunOnce, slots);
     current->add(callObj);
 
     // Insert a post barrier to protect the following writes if we allocated
     // the new call object directly into tenured storage.
     if (templateObj->type()->isLongLivedForJITAlloc())
-        current->add(MPostWriteBarrier::New(callObj));
+        current->add(MPostWriteBarrier::New(alloc(), callObj));
 
     // Initialize the object's reserved slots. No post barrier is needed here,
     // for the same reason as in createDeclEnvObject.
-    current->add(MStoreFixedSlot::New(callObj, CallObject::enclosingScopeSlot(), scope));
-    current->add(MStoreFixedSlot::New(callObj, CallObject::calleeSlot(), callee));
+    current->add(MStoreFixedSlot::New(alloc(), callObj, CallObject::enclosingScopeSlot(), scope));
+    current->add(MStoreFixedSlot::New(alloc(), callObj, CallObject::calleeSlot(), callee));
 
     // Initialize argument slots.
     for (AliasedFormalIter i(script()); i; i++) {
         unsigned slot = i.scopeSlot();
         unsigned formal = i.frameIndex();
         MDefinition *param = current->getSlot(info().argSlotUnchecked(formal));
         if (slot >= templateObj->numFixedSlots())
-            current->add(MStoreSlot::New(slots, slot - templateObj->numFixedSlots(), param));
+            current->add(MStoreSlot::New(alloc(), slots, slot - templateObj->numFixedSlots(), param));
         else
-            current->add(MStoreFixedSlot::New(callObj, slot, param));
+            current->add(MStoreFixedSlot::New(alloc(), callObj, slot, param));
     }
 
     return callObj;
 }
 
 MDefinition *
 IonBuilder::createThisScripted(MDefinition *callee)
 {
@@ -4605,29 +4606,29 @@ IonBuilder::createThisScripted(MDefiniti
     // - First try an idempotent property cache.
     // - Upon failing idempotent property cache, we can't use a non-idempotent cache,
     //   therefore we fallback to CallGetProperty
     //
     // Note: both CallGetProperty and GetPropertyCache can trigger a GC,
     //       and thus invalidation.
     MInstruction *getProto;
     if (!invalidatedIdempotentCache()) {
-        MGetPropertyCache *getPropCache = MGetPropertyCache::New(callee, names().prototype);
+        MGetPropertyCache *getPropCache = MGetPropertyCache::New(alloc(), callee, names().prototype);
         getPropCache->setIdempotent();
         getProto = getPropCache;
     } else {
-        MCallGetProperty *callGetProp = MCallGetProperty::New(callee, names().prototype,
+        MCallGetProperty *callGetProp = MCallGetProperty::New(alloc(), callee, names().prototype,
                                                               /* callprop = */ false);
         callGetProp->setIdempotent();
         getProto = callGetProp;
     }
     current->add(getProto);
 
     // Create this from prototype
-    MCreateThisWithProto *createThis = MCreateThisWithProto::New(callee, getProto);
+    MCreateThisWithProto *createThis = MCreateThisWithProto::New(alloc(), callee, getProto);
     current->add(createThis);
 
     return createThis;
 }
 
 JSObject *
 IonBuilder::getSingletonPrototype(JSFunction *target)
 {
@@ -4673,38 +4674,38 @@ IonBuilder::createThisScriptedSingleton(
         JS_ASSERT(templateObject->type() == templateType);
 
         // Trigger recompilation if the templateObject changes.
         types::TypeObjectKey::get(templateType)->watchStateChangeForNewScriptTemplate(constraints());
     }
 
     // Generate an inline path to create a new |this| object with
     // the given singleton prototype.
-    MCreateThisWithTemplate *createThis = MCreateThisWithTemplate::New(templateObject);
+    MCreateThisWithTemplate *createThis = MCreateThisWithTemplate::New(alloc(), templateObject);
     current->add(createThis);
 
     return createThis;
 }
 
 MDefinition *
 IonBuilder::createThis(JSFunction *target, MDefinition *callee)
 {
     // Create this for unknown target
     if (!target) {
-        MCreateThis *createThis = MCreateThis::New(callee);
+        MCreateThis *createThis = MCreateThis::New(alloc(), callee);
         current->add(createThis);
         return createThis;
     }
 
     // Native constructors build the new Object themselves.
     if (target->isNative()) {
         if (!target->isNativeConstructor())
             return nullptr;
 
-        MConstant *magic = MConstant::New(MagicValue(JS_IS_CONSTRUCTING));
+        MConstant *magic = MConstant::New(alloc(), MagicValue(JS_IS_CONSTRUCTING));
         current->add(magic);
         return magic;
     }
 
     // Try baking in the prototype.
     MDefinition *createThis = createThisScriptedSingleton(target, callee);
     if (createThis)
         return createThis;
@@ -4749,19 +4750,19 @@ IonBuilder::jsop_funcall(uint32_t argc)
     passFunc->block()->discard(passFunc);
 
     // Shimmy the slots down to remove the native 'call' function.
     current->shimmySlots(funcDepth - 1);
 
     // If no |this| argument was provided, explicitly pass Undefined.
     // Pushing is safe here, since one stack slot has been removed.
     if (argc == 0) {
-        MConstant *undef = MConstant::New(UndefinedValue());
+        MConstant *undef = MConstant::New(alloc(), UndefinedValue());
         current->add(undef);
-        MPassArg *pass = MPassArg::New(undef);
+        MPassArg *pass = MPassArg::New(alloc(), undef);
         current->add(pass);
         current->push(pass);
     } else {
         // |this| becomes implicit in the call.
         argc -= 1;
     }
 
     CallInfo callInfo(false);
@@ -4856,20 +4857,20 @@ IonBuilder::jsop_funapplyarguments(uint3
         MPassArg *passFunc = current->pop()->toPassArg();
         MDefinition *argFunc = passFunc->getArgument();
         passFunc->replaceAllUsesWith(argFunc);
         passFunc->block()->discard(passFunc);
 
         // Pop apply function.
         current->pop();
 
-        MArgumentsLength *numArgs = MArgumentsLength::New();
+        MArgumentsLength *numArgs = MArgumentsLength::New(alloc());
         current->add(numArgs);
 
-        MApplyArgs *apply = MApplyArgs::New(target, argFunc, numArgs, argThis);
+        MApplyArgs *apply = MApplyArgs::New(alloc(), target, argFunc, numArgs, argThis);
         current->add(apply);
         current->push(apply);
         if (!resumeAfter(apply))
             return false;
 
         types::TemporaryTypeSet *types = bytecodeTypes(pc);
         return pushTypeBarrier(apply, types, true);
     }
@@ -4913,35 +4914,35 @@ IonBuilder::jsop_funapplyarguments(uint3
 
     // Pop apply function.
     current->pop();
 
     // Try inlining call
     if (makeInliningDecision(target, callInfo) && target->isInterpreted())
         return inlineScriptedCall(callInfo, target);
 
-    callInfo.wrapArgs(current);
+    callInfo.wrapArgs(alloc(), current);
     return makeCall(target, callInfo, false);
 }
 
 bool
 IonBuilder::jsop_call(uint32_t argc, bool constructing)
 {
     // If this call has never executed, try to seed the observed type set
     // based on how the call result is used.
     types::TemporaryTypeSet *observed = bytecodeTypes(pc);
     if (observed->empty()) {
         if (BytecodeFlowsToBitop(pc)) {
-            if (!observed->addType(types::Type::Int32Type(), temp_->lifoAlloc()))
+            if (!observed->addType(types::Type::Int32Type(), alloc_->lifoAlloc()))
                 return false;
         } else if (*GetNextPc(pc) == JSOP_POS) {
             // Note: this is lame, overspecialized on the code patterns used
             // by asm.js and should be replaced by a more general mechanism.
             // See bug 870847.
-            if (!observed->addType(types::Type::DoubleType(), temp_->lifoAlloc()))
+            if (!observed->addType(types::Type::DoubleType(), alloc_->lifoAlloc()))
                 return false;
         }
     }
 
     int calleeDepth = -((int)argc + 2);
 
     // Acquire known call target if existent.
     ObjectVector originals;
@@ -4991,26 +4992,26 @@ IonBuilder::jsop_call(uint32_t argc, boo
 MDefinition *
 IonBuilder::makeCallsiteClone(JSFunction *target, MDefinition *fun)
 {
     // Bake in the clone eagerly if we have a known target. We have arrived here
     // because TI told us that the known target is a should-clone-at-callsite
     // function, which means that target already is the clone. Make sure to ensure
     // that the old definition remains in resume points.
     if (target) {
-        MConstant *constant = MConstant::New(ObjectValue(*target));
+        MConstant *constant = MConstant::New(alloc(), ObjectValue(*target));
         current->add(constant);
         fun->setFoldedUnchecked();
         return constant;
     }
 
     // Add a callsite clone IC if we have multiple targets. Note that we
     // should have checked already that at least some targets are marked as
     // should-clone-at-callsite.
-    MCallsiteCloneCache *clone = MCallsiteCloneCache::New(fun, pc);
+    MCallsiteCloneCache *clone = MCallsiteCloneCache::New(alloc(), fun, pc);
     current->add(clone);
     return clone;
 }
 
 bool
 IonBuilder::testShouldDOMCall(types::TypeSet *inTypes,
                               JSFunction *func, JSJitInfo::OpType opType)
 {
@@ -5123,27 +5124,27 @@ IonBuilder::makeCallHelper(JSFunction *t
     uint32_t targetArgs = callInfo.argc();
 
     // Collect number of missing arguments provided that the target is
     // scripted. Native functions are passed an explicit 'argc' parameter.
     if (target && !target->isNative())
         targetArgs = Max<uint32_t>(target->nargs, callInfo.argc());
 
     MCall *call =
-        MCall::New(target, targetArgs + 1, callInfo.argc(), callInfo.constructing());
+        MCall::New(alloc(), target, targetArgs + 1, callInfo.argc(), callInfo.constructing());
     if (!call)
         return nullptr;
 
     // Explicitly pad any missing arguments with |undefined|.
     // This permits skipping the argumentsRectifier.
     for (int i = targetArgs; i > (int)callInfo.argc(); i--) {
         JS_ASSERT_IF(target, !target->isNative());
-        MConstant *undef = MConstant::New(UndefinedValue());
+        MConstant *undef = MConstant::New(alloc(), UndefinedValue());
         current->add(undef);
-        MPassArg *pass = MPassArg::New(undef);
+        MPassArg *pass = MPassArg::New(alloc(), undef);
         current->add(pass);
         call->addArg(i, pass);
     }
 
     // Add explicit arguments.
     // Skip addArg(0) because it is reserved for this
     for (int32_t i = callInfo.argc() - 1; i >= 0; i--) {
         JS_ASSERT(callInfo.getArg(i)->isPassArg());
@@ -5165,17 +5166,17 @@ IonBuilder::makeCallHelper(JSFunction *t
             abort("Failure inlining constructor for call.");
             return nullptr;
         }
 
         // Unwrap the MPassArg before discarding: it may have been captured by an MResumePoint.
         thisArg->replaceAllUsesWith(thisArg->getArgument());
         thisArg->block()->discard(thisArg);
 
-        MPassArg *newThis = MPassArg::New(create);
+        MPassArg *newThis = MPassArg::New(alloc(), create);
         current->add(newThis);
 
         thisArg = newThis;
         callInfo.setThis(newThis);
     }
 
     // Pass |this| and function.
     call->addArg(0, thisArg);
@@ -5246,17 +5247,17 @@ IonBuilder::makeCall(JSFunction *target,
 
     bool barrier = true;
     MDefinition *replace = call;
     if (call->isDOMFunction()) {
         JSFunction* target = call->getSingleTarget();
         JS_ASSERT(target && target->isNative() && target->jitInfo());
         const JSJitInfo *jitinfo = target->jitInfo();
         barrier = DOMCallNeedsBarrier(jitinfo, types);
-        replace = EnsureDefiniteType(call, jitinfo->returnType);
+        replace = ensureDefiniteType(call, jitinfo->returnType);
         if (replace != call) {
             current->pop();
             current->push(replace);
         }
     }
 
     return pushTypeBarrier(replace, types, barrier);
 }
@@ -5310,54 +5311,54 @@ IonBuilder::jsop_eval(uint32_t argc)
         if (string->isConcat() &&
             string->getOperand(1)->isConstant() &&
             string->getOperand(1)->toConstant()->value().isString())
         {
             JSString *str = string->getOperand(1)->toConstant()->value().toString();
 
             if (str->isLinear() && StringEqualsAscii(&str->asLinear(), "()")) {
                 MDefinition *name = string->getOperand(0);
-                MInstruction *dynamicName = MGetDynamicName::New(scopeChain, name);
+                MInstruction *dynamicName = MGetDynamicName::New(alloc(), scopeChain, name);
                 current->add(dynamicName);
 
-                MInstruction *thisv = MPassArg::New(thisValue);
+                MInstruction *thisv = MPassArg::New(alloc(), thisValue);
                 current->add(thisv);
 
                 current->push(dynamicName);
                 current->push(thisv);
 
                 CallInfo evalCallInfo(/* constructing = */ false);
                 if (!evalCallInfo.init(current, /* argc = */ 0))
                     return false;
 
                 return makeCall(nullptr, evalCallInfo, false);
             }
         }
 
-        MInstruction *filterArguments = MFilterArgumentsOrEval::New(string);
+        MInstruction *filterArguments = MFilterArgumentsOrEval::New(alloc(), string);
         current->add(filterArguments);
 
-        MInstruction *ins = MCallDirectEval::New(scopeChain, string, thisValue, pc);
+        MInstruction *ins = MCallDirectEval::New(alloc(), scopeChain, string, thisValue, pc);
         current->add(ins);
         current->push(ins);
 
         types::TemporaryTypeSet *types = bytecodeTypes(pc);
         return resumeAfter(ins) && pushTypeBarrier(ins, types, true);
     }
 
     return jsop_call(argc, /* constructing = */ false);
 }
 
 bool
 IonBuilder::jsop_compare(JSOp op)
 {
     MDefinition *right = current->pop();
     MDefinition *left = current->pop();
 
-    MCompare *ins = MCompare::New(left, right, op);
+    MCompare *ins = MCompare::New(alloc(), left, right, op);
     current->add(ins);
     current->push(ins);
 
     ins->infer(inspector, pc);
 
     if (ins->isEffectful() && !resumeAfter(ins))
         return false;
     return true;
@@ -5379,17 +5380,17 @@ IonBuilder::jsop_newarray(uint32_t count
         return abort("New array has unknown properties");
     }
 
     types::TemporaryTypeSet::DoubleConversion conversion =
         bytecodeTypes(pc)->convertDoubleElements(constraints());
     if (conversion == types::TemporaryTypeSet::AlwaysConvertToDoubles)
         templateObject->setShouldConvertDoubleElements();
 
-    MNewArray *ins = new MNewArray(count, templateObject, MNewArray::NewArray_Allocating);
+    MNewArray *ins = MNewArray::New(alloc(), count, templateObject, MNewArray::NewArray_Allocating);
 
     current->add(ins);
     current->push(ins);
 
     return true;
 }
 
 bool
@@ -5398,33 +5399,33 @@ IonBuilder::jsop_newobject()
     // Don't bake in the TypeObject for non-CNG scripts.
     JS_ASSERT(script()->compileAndGo);
 
     JSObject *templateObject = inspector->getTemplateObject(pc);
     if (!templateObject)
         return abort("No template object for NEWOBJECT");
 
     JS_ASSERT(templateObject->is<JSObject>());
-    MNewObject *ins = MNewObject::New(templateObject,
+    MNewObject *ins = MNewObject::New(alloc(), templateObject,
                                       /* templateObjectIsClassPrototype = */ false);
 
     current->add(ins);
     current->push(ins);
 
     return resumeAfter(ins);
 }
 
 bool
 IonBuilder::jsop_initelem()
 {
     MDefinition *value = current->pop();
     MDefinition *id = current->pop();
     MDefinition *obj = current->peek(-1);
 
-    MInitElem *initElem = MInitElem::New(obj, id, value);
+    MInitElem *initElem = MInitElem::New(alloc(), obj, id, value);
     current->add(initElem);
 
     return resumeAfter(initElem);
 }
 
 bool
 IonBuilder::jsop_initelem_array()
 {
@@ -5443,43 +5444,43 @@ IonBuilder::jsop_initelem_array()
         types::HeapTypeSetKey elemTypes = initializer->property(JSID_VOID);
         if (!TypeSetIncludes(elemTypes.maybeTypes(), value->type(), value->resultTypeSet())) {
             elemTypes.freeze(constraints());
             needStub = true;
         }
     }
 
     if (NeedsPostBarrier(info(), value))
-        current->add(MPostWriteBarrier::New(obj, value));
+        current->add(MPostWriteBarrier::New(alloc(), obj, value));
 
     if (needStub) {
-        MCallInitElementArray *store = MCallInitElementArray::New(obj, GET_UINT24(pc), value);
+        MCallInitElementArray *store = MCallInitElementArray::New(alloc(), obj, GET_UINT24(pc), value);
         current->add(store);
         return resumeAfter(store);
     }
 
-    MConstant *id = MConstant::New(Int32Value(GET_UINT24(pc)));
+    MConstant *id = MConstant::New(alloc(), Int32Value(GET_UINT24(pc)));
     current->add(id);
 
     // Get the elements vector.
-    MElements *elements = MElements::New(obj);
+    MElements *elements = MElements::New(alloc(), obj);
     current->add(elements);
 
     if (obj->toNewArray()->templateObject()->shouldConvertDoubleElements()) {
-        MInstruction *valueDouble = MToDouble::New(value);
+        MInstruction *valueDouble = MToDouble::New(alloc(), value);
         current->add(valueDouble);
         value = valueDouble;
     }
 
     // Store the value.
-    MStoreElement *store = MStoreElement::New(elements, id, value, /* needsHoleCheck = */ false);
+    MStoreElement *store = MStoreElement::New(alloc(), elements, id, value, /* needsHoleCheck = */ false);
     current->add(store);
 
     // Update the length.
-    MSetInitializedLength *initLength = MSetInitializedLength::New(elements, id);
+    MSetInitializedLength *initLength = MSetInitializedLength::New(alloc(), elements, id);
     current->add(initLength);
 
     if (!resumeAfter(initLength))
         return false;
 
    return true;
 }
 
@@ -5490,32 +5491,32 @@ IonBuilder::jsop_initprop(PropertyName *
     MDefinition *obj = current->peek(-1);
 
     JSObject *templateObject = obj->toNewObject()->templateObject();
 
     Shape *shape = templateObject->nativeLookupPure(name);
 
     if (!shape) {
         // JSOP_NEWINIT becomes an MNewObject without preconfigured properties.
-        MInitProp *init = MInitProp::New(obj, name, value);
+        MInitProp *init = MInitProp::New(alloc(), obj, name, value);
         current->add(init);
         return resumeAfter(init);
     }
 
-    if (PropertyWriteNeedsTypeBarrier(constraints(), current,
+    if (PropertyWriteNeedsTypeBarrier(alloc(), constraints(), current,
                                       &obj, name, &value, /* canModify = */ true))
     {
         // JSOP_NEWINIT becomes an MNewObject without preconfigured properties.
-        MInitProp *init = MInitProp::New(obj, name, value);
+        MInitProp *init = MInitProp::New(alloc(), obj, name, value);
         current->add(init);
         return resumeAfter(init);
     }
 
     if (NeedsPostBarrier(info(), value))
-        current->add(MPostWriteBarrier::New(obj, value));
+        current->add(MPostWriteBarrier::New(alloc(), obj, value));
 
     bool needsBarrier = true;
     if (obj->resultTypeSet() &&
         !obj->resultTypeSet()->propertyNeedsBarrier(constraints(), NameToId(name)))
     {
         needsBarrier = false;
     }
 
@@ -5526,55 +5527,55 @@ IonBuilder::jsop_initprop(PropertyName *
       case DefinitePropertiesAnalysis:
         break;
       case ParallelExecution:
         needsBarrier = false;
         break;
     }
 
     if (templateObject->isFixedSlot(shape->slot())) {
-        MStoreFixedSlot *store = MStoreFixedSlot::New(obj, shape->slot(), value);
+        MStoreFixedSlot *store = MStoreFixedSlot::New(alloc(), obj, shape->slot(), value);
         if (needsBarrier)
             store->setNeedsBarrier();
 
         current->add(store);
         return resumeAfter(store);
     }
 
-    MSlots *slots = MSlots::New(obj);
+    MSlots *slots = MSlots::New(alloc(), obj);
     current->add(slots);
 
     uint32_t slot = templateObject->dynamicSlotIndex(shape->slot());
-    MStoreSlot *store = MStoreSlot::New(slots, slot, value);
+    MStoreSlot *store = MStoreSlot::New(alloc(), slots, slot, value);
     if (needsBarrier)
         store->setNeedsBarrier();
 
     current->add(store);
     return resumeAfter(store);
 }
 
 bool
 IonBuilder::jsop_initprop_getter_setter(PropertyName *name)
 {
     MDefinition *value = current->pop();
     MDefinition *obj = current->peek(-1);
 
-    MInitPropGetterSetter *init = MInitPropGetterSetter::New(obj, name, value);
+    MInitPropGetterSetter *init = MInitPropGetterSetter::New(alloc(), obj, name, value);
     current->add(init);
     return resumeAfter(init);
 }
 
 bool
 IonBuilder::jsop_initelem_getter_setter()
 {
     MDefinition *value = current->pop();
     MDefinition *id = current->pop();
     MDefinition *obj = current->peek(-1);
 
-    MInitElemGetterSetter *init = MInitElemGetterSetter::New(obj, id, value);
+    MInitElemGetterSetter *init = MInitElemGetterSetter::New(alloc(), obj, id, value);
     current->add(init);
     return resumeAfter(init);
 }
 
 MBasicBlock *
 IonBuilder::addBlock(MBasicBlock *block, uint32_t loopDepth)
 {
     if (!block)
@@ -5635,62 +5636,62 @@ IonBuilder::newOsrPreheader(MBasicBlock 
     // Create two blocks: one for the OSR entry with no predecessors, one for
     // the preheader, which has the OSR entry block as a predecessor. The
     // OSR block is always the second block (with id 1).
     MBasicBlock *osrBlock  = newBlockAfter(*graph().begin(), loopEntry);
     MBasicBlock *preheader = newBlock(predecessor, loopEntry);
     if (!osrBlock || !preheader)
         return nullptr;
 
-    MOsrEntry *entry = MOsrEntry::New();
+    MOsrEntry *entry = MOsrEntry::New(alloc());
     osrBlock->add(entry);
 
     // Initialize |scopeChain|.
     {
         uint32_t slot = info().scopeChainSlot();
 
         MInstruction *scopev;
         if (analysis().usesScopeChain()) {
-            scopev = MOsrScopeChain::New(entry);
+            scopev = MOsrScopeChain::New(alloc(), entry);
         } else {
             // Use an undefined value if the script does not need its scope
             // chain, to match the type that is already being tracked for the
             // slot.
-            scopev = MConstant::New(UndefinedValue());
+            scopev = MConstant::New(alloc(), UndefinedValue());
         }
 
         osrBlock->add(scopev);
         osrBlock->initSlot(slot, scopev);
     }
     // Initialize |return value|
     {
         MInstruction *returnValue;
         if (!script()->noScriptRval)
-            returnValue = MOsrReturnValue::New(entry);
+            returnValue = MOsrReturnValue::New(alloc(), entry);
         else
-            returnValue = MConstant::New(UndefinedValue());
+            returnValue = MConstant::New(alloc(), UndefinedValue());
         osrBlock->add(returnValue);
         osrBlock->initSlot(info().returnValueSlot(), returnValue);
     }
 
     // Initialize arguments object.
     bool needsArgsObj = info().needsArgsObj();
     MInstruction *argsObj = nullptr;
     if (info().hasArguments()) {
         if (needsArgsObj)
-            argsObj = MOsrArgumentsObject::New(entry);
+            argsObj = MOsrArgumentsObject::New(alloc(), entry);
         else
-            argsObj = MConstant::New(UndefinedValue());
+            argsObj = MConstant::New(alloc(), UndefinedValue());
         osrBlock->add(argsObj);
         osrBlock->initSlot(info().argsObjSlot(), argsObj);
     }
 
     if (info().fun()) {
         // Initialize |this| parameter.
-        MParameter *thisv = MParameter::New(MParameter::THIS_SLOT, nullptr);
+        MParameter *thisv = MParameter::New(alloc(), MParameter::THIS_SLOT, nullptr);
         osrBlock->add(thisv);
         osrBlock->initSlot(info().thisSlot(), thisv);
 
         // Initialize arguments.
         for (uint32_t i = 0; i < info().nargs(); i++) {
             uint32_t slot = needsArgsObj ? info().argSlotUnchecked(i) : info().argSlot(i);
 
             // Only grab arguments from the arguments object if the arguments object
@@ -5702,53 +5703,53 @@ IonBuilder::newOsrPreheader(MBasicBlock 
                 // If this is an aliased formal, then the arguments object
                 // contains a hole at this index.  Any references to this
                 // variable in the jitcode will come from JSOP_*ALIASEDVAR
                 // opcodes, so the slot itself can be set to undefined.  If
                 // it's not aliased, it must be retrieved from the arguments
                 // object.
                 MInstruction *osrv;
                 if (script()->formalIsAliased(i))
-                    osrv = MConstant::New(UndefinedValue());
+                    osrv = MConstant::New(alloc(), UndefinedValue());
                 else
-                    osrv = MGetArgumentsObjectArg::New(argsObj, i);
+                    osrv = MGetArgumentsObjectArg::New(alloc(), argsObj, i);
 
                 osrBlock->add(osrv);
                 osrBlock->initSlot(slot, osrv);
             } else {
-                MParameter *arg = MParameter::New(i, nullptr);
+                MParameter *arg = MParameter::New(alloc(), i, nullptr);
                 osrBlock->add(arg);
                 osrBlock->initSlot(slot, arg);
             }
         }
     }
 
     // Initialize locals.
     for (uint32_t i = 0; i < info().nlocals(); i++) {
         uint32_t slot = info().localSlot(i);
         ptrdiff_t offset = BaselineFrame::reverseOffsetOfLocal(i);
 
-        MOsrValue *osrv = MOsrValue::New(entry, offset);
+        MOsrValue *osrv = MOsrValue::New(alloc(), entry, offset);
         osrBlock->add(osrv);
         osrBlock->initSlot(slot, osrv);
     }
 
     // Initialize stack.
     uint32_t numStackSlots = preheader->stackDepth() - info().firstStackSlot();
     for (uint32_t i = 0; i < numStackSlots; i++) {
         uint32_t slot = info().stackSlot(i);
         ptrdiff_t offset = BaselineFrame::reverseOffsetOfLocal(info().nlocals() + i);
 
-        MOsrValue *osrv = MOsrValue::New(entry, offset);
+        MOsrValue *osrv = MOsrValue::New(alloc(), entry, offset);
         osrBlock->add(osrv);
         osrBlock->initSlot(slot, osrv);
     }
 
     // Create an MStart to hold the first valid MResumePoint.
-    MStart *start = MStart::New(MStart::StartType_Osr);
+    MStart *start = MStart::New(alloc(), MStart::StartType_Osr);
     osrBlock->add(start);
     graph().setOsrStart(start);
 
     // MOsrValue instructions are infallible, so the first MResumePoint must
     // occur after they execute, at the point of the MStart.
     if (!resumeAt(start, loopEntry))
         return nullptr;
 
@@ -5777,18 +5778,18 @@ IonBuilder::newOsrPreheader(MBasicBlock 
         if (info().isSlotAliased(i))
             continue;
 
         def->setResultType(existing->type());
         def->setResultTypeSet(existing->resultTypeSet());
     }
 
     // Finish the osrBlock.
-    osrBlock->end(MGoto::New(preheader));
-    preheader->addPredecessor(osrBlock);
+    osrBlock->end(MGoto::New(alloc(), preheader));
+    preheader->addPredecessor(alloc(), osrBlock);
     graph().setOsrBlock(osrBlock);
 
     // Wrap |this| with a guaranteed use, to prevent instruction elimination.
     // Prevent |this| from being DCE'd: necessary for constructors.
     if (info().fun())
         preheader->getSlot(info().thisSlot())->setGuard();
 
     return preheader;
@@ -5840,17 +5841,17 @@ IonBuilder::newPendingLoopHeader(MBasicB
             }
 
             // Extract typeset from value.
             MIRType type = existingValue.isDouble()
                          ? MIRType_Double
                          : MIRTypeFromValueType(existingValue.extractNonDoubleType());
             types::Type ntype = types::GetValueType(existingValue);
             types::TemporaryTypeSet *typeSet =
-                temp_->lifoAlloc()->new_<types::TemporaryTypeSet>(ntype);
+                alloc_->lifoAlloc()->new_<types::TemporaryTypeSet>(ntype);
             if (!typeSet)
                 return nullptr;
             phi->addBackedgeType(type, typeSet);
         }
     }
 
     return block;
 }
@@ -5878,17 +5879,18 @@ IonBuilder::newPendingLoopHeader(MBasicB
 // During LIR construction, if an instruction can bail back to the interpreter,
 // we create an LSnapshot, which uses the last known resume point to request
 // register/stack assignments for every live value.
 bool
 IonBuilder::resume(MInstruction *ins, jsbytecode *pc, MResumePoint::Mode mode)
 {
     JS_ASSERT(ins->isEffectful() || !ins->isMovable());
 
-    MResumePoint *resumePoint = MResumePoint::New(ins->block(), pc, callerResumePoint_, mode);
+    MResumePoint *resumePoint = MResumePoint::New(alloc(), ins->block(), pc, callerResumePoint_,
+                                                  mode);
     if (!resumePoint)
         return false;
     ins->setResumePoint(resumePoint);
     resumePoint->setInstruction(ins);
     return true;
 }
 
 bool
@@ -5914,17 +5916,17 @@ IonBuilder::maybeInsertResume()
     //
     // This optimization is not performed outside of loop bodies, where good
     // register allocation is not as critical, in order to avoid creating
     // excessive resume points.
 
     if (loopDepth_ == 0)
         return true;
 
-    MNop *ins = MNop::New();
+    MNop *ins = MNop::New(alloc());
     current->add(ins);
 
     return resumeAfter(ins);
 }
 
 static bool
 ClassHasEffectlessLookup(const Class *clasp)
 {
@@ -6102,67 +6104,67 @@ IonBuilder::pushTypeBarrier(MDefinition 
     // If the instruction has no side effects, we'll resume the entire operation.
     // The actual type barrier will occur in the interpreter. If the
     // instruction is effectful, even if it has a singleton type, there
     // must be a resume point capturing the original def, and resuming
     // to that point will explicitly monitor the new type.
 
     if (!needsBarrier) {
         JSValueType type = observed->getKnownTypeTag();
-        MDefinition *replace = EnsureDefiniteType(def, type);
+        MDefinition *replace = ensureDefiniteType(def, type);
         if (replace != def) {
             current->pop();
             current->push(replace);
         }
         replace->setResultTypeSet(observed);
         return true;
     }
 
     if (observed->unknown())
         return true;
 
     current->pop();
 
-    MInstruction *barrier = MTypeBarrier::New(def, observed);
+    MInstruction *barrier = MTypeBarrier::New(alloc(), def, observed);
     current->add(barrier);
 
     if (barrier->type() == MIRType_Undefined)
         return pushConstant(UndefinedValue());
     if (barrier->type() == MIRType_Null)
         return pushConstant(NullValue());
 
     current->push(barrier);
     return true;
 }
 
 MDefinition *
-IonBuilder::EnsureDefiniteType(MDefinition *def, JSValueType definiteType)
+IonBuilder::ensureDefiniteType(MDefinition *def, JSValueType definiteType)
 {
     MInstruction *replace;
     switch (definiteType) {
       case JSVAL_TYPE_UNDEFINED:
         def->setFoldedUnchecked();
-        replace = MConstant::New(UndefinedValue());
+        replace = MConstant::New(alloc(), UndefinedValue());
         break;
 
       case JSVAL_TYPE_NULL:
         def->setFoldedUnchecked();
-        replace = MConstant::New(NullValue());
+        replace = MConstant::New(alloc(), NullValue());
         break;
 
       case JSVAL_TYPE_UNKNOWN:
         return def;
 
       default: {
         MIRType replaceType = MIRTypeFromValueType(definiteType);
         if (def->type() != MIRType_Value) {
             JS_ASSERT(def->type() == replaceType);
             return def;
         }
-        replace = MUnbox::New(def, replaceType, MUnbox::Infallible);
+        replace = MUnbox::New(alloc(), def, replaceType, MUnbox::Infallible);
         break;
       }
     }
 
     current->add(replace);
     return replace;
 }
 
@@ -6231,17 +6233,17 @@ IonBuilder::getStaticName(JSObject *stat
                 return pushConstant(ObjectValue(*singleton));
         }
         if (knownType == JSVAL_TYPE_UNDEFINED)
             return pushConstant(UndefinedValue());
         if (knownType == JSVAL_TYPE_NULL)
             return pushConstant(NullValue());
     }
 
-    MInstruction *obj = MConstant::New(ObjectValue(*staticObject));
+    MInstruction *obj = MConstant::New(alloc(), ObjectValue(*staticObject));
     current->add(obj);
 
     MIRType rvalType = MIRTypeFromValueType(types->getKnownTypeTag());
     if (barrier)
         rvalType = MIRType_Value;
 
     return loadSlot(obj, property.maybeTypes()->definiteSlot(), NumFixedSlots(staticObject),
                     rvalType, barrier, types);
@@ -6314,17 +6316,17 @@ IonBuilder::setStaticName(JSObject *stat
 
     current->pop();
 
     // Pop the bound object on the stack.
     MDefinition *obj = current->pop();
     JS_ASSERT(&obj->toConstant()->value().toObject() == staticObject);
 
     if (NeedsPostBarrier(info(), value))
-        current->add(MPostWriteBarrier::New(obj, value));
+        current->add(MPostWriteBarrier::New(alloc(), obj, value));
 
     // If the property has a known type, we may be able to optimize typed stores by not
     // storing the type tag.
     MIRType slotType = MIRType_None;
     JSValueType knownType = property.knownTypeTag(constraints());
     if (knownType != JSVAL_TYPE_UNKNOWN)
         slotType = MIRTypeFromValueType(knownType);
 
@@ -6333,29 +6335,29 @@ IonBuilder::setStaticName(JSObject *stat
                      value, needsBarrier, slotType);
 }
 
 bool
 IonBuilder::jsop_getname(PropertyName *name)
 {
     MDefinition *object;
     if (js_CodeSpec[*pc].format & JOF_GNAME) {
-        MInstruction *global = MConstant::New(ObjectValue(script()->global()));
+        MInstruction *global = MConstant::New(alloc(), ObjectValue(script()->global()));
         current->add(global);
         object = global;
     } else {
         current->push(current->scopeChain());
         object = current->pop();
     }
 
     MGetNameCache *ins;
     if (JSOp(*GetNextPc(pc)) == JSOP_TYPEOF)
-        ins = MGetNameCache::New(object, name, MGetNameCache::NAMETYPEOF);
+        ins = MGetNameCache::New(alloc(), object, name, MGetNameCache::NAMETYPEOF);
     else
-        ins = MGetNameCache::New(object, name, MGetNameCache::NAME);
+        ins = MGetNameCache::New(alloc(), object, name, MGetNameCache::NAME);
 
     current->add(ins);
     current->push(ins);
 
     if (!resumeAfter(ins))
         return false;
 
     types::TemporaryTypeSet *types = bytecodeTypes(pc);
@@ -6366,46 +6368,46 @@ bool
 IonBuilder::jsop_intrinsic(PropertyName *name)
 {
     types::TemporaryTypeSet *types = bytecodeTypes(pc);
     JSValueType type = types->getKnownTypeTag();
 
     // If we haven't executed this opcode yet, we need to get the intrinsic
     // value and monitor the result.
     if (type == JSVAL_TYPE_UNKNOWN) {
-        MCallGetIntrinsicValue *ins = MCallGetIntrinsicValue::New(name);
+        MCallGetIntrinsicValue *ins = MCallGetIntrinsicValue::New(alloc(), name);
 
         current->add(ins);
         current->push(ins);
 
         if (!resumeAfter(ins))
             return false;
 
         return pushTypeBarrier(ins, types, true);
     }
 
     // Bake in the intrinsic. Make sure that TI agrees with us on the type.
     Value vp;
     JS_ALWAYS_TRUE(script()->global().maybeGetIntrinsicValue(name, &vp));
     JS_ASSERT(types->hasType(types::GetValueType(vp)));
 
-    MConstant *ins = MConstant::New(vp);
+    MConstant *ins = MConstant::New(alloc(), vp);
     current->add(ins);
     current->push(ins);
 
     return true;
 }
 
 bool
 IonBuilder::jsop_bindname(PropertyName *name)
 {
     JS_ASSERT(analysis().usesScopeChain());
 
     MDefinition *scopeChain = current->scopeChain();
-    MBindNameCache *ins = MBindNameCache::New(scopeChain, name, script(), pc);
+    MBindNameCache *ins = MBindNameCache::New(alloc(), scopeChain, name, script(), pc);
 
     current->add(ins);
     current->push(ins);
 
     return resumeAfter(ins);
 }
 
 static JSValueType
@@ -6460,17 +6462,17 @@ IonBuilder::jsop_getelem()
 
     if (script()->argumentsHasVarBinding() && obj->mightBeType(MIRType_Magic))
         return abort("Type is not definitely lazy arguments.");
 
     if (!getElemTryCache(&emitted, obj, index) || emitted)
         return emitted;
 
     // Emit call.
-    MInstruction *ins = MCallGetElement::New(obj, index);
+    MInstruction *ins = MCallGetElement::New(alloc(), obj, index);
 
     current->add(ins);
     current->push(ins);
 
     if (!resumeAfter(ins))
         return false;
 
     types::TemporaryTypeSet *types = bytecodeTypes(pc);
@@ -6536,42 +6538,42 @@ IonBuilder::getElemTryScalarElemOfTypedO
     if (!elemTypeReprs.singleton())
         return true;
     ScalarTypeRepresentation *elemTypeRepr = elemTypeReprs.getTypeRepresentation()->asScalar();
 
     // Get the length.
     size_t lenOfAll = objTypeReprs.arrayLength();
     if (lenOfAll >= size_t(INT_MAX)) // int32 max is bound
         return true;
-    MInstruction *length = MConstant::New(Int32Value(int32_t(lenOfAll)));
+    MInstruction *length = MConstant::New(alloc(), Int32Value(int32_t(lenOfAll)));
 
     *emitted = true;
     current->add(length);
 
     // Ensure index is an integer.
-    MInstruction *idInt32 = MToInt32::New(index);
+    MInstruction *idInt32 = MToInt32::New(alloc(), index);
     current->add(idInt32);
     index = idInt32;
 
     // Typed-object accesses usually in bounds (bail out otherwise).
     index = addBoundsCheck(index, length);
 
     // Since we passed the bounds check, it is impossible for the
     // result of multiplication to overflow; so enable imul path.
     const int32_t alignment = elemTypeRepr->alignment();
-    MMul *indexAsByteOffset = MMul::New(index, constantInt(alignment),
+    MMul *indexAsByteOffset = MMul::New(alloc(), index, constantInt(alignment),
                                         MIRType_Int32, MMul::Integer);
     current->add(indexAsByteOffset);
 
     // Find location within the owner object.
     MDefinition *elements, *scaledOffset;
     loadTypedObjectElements(obj, indexAsByteOffset, alignment, &elements, &scaledOffset);
 
     // Load the element.
-    MLoadTypedArrayElement *load = MLoadTypedArrayElement::New(elements, scaledOffset, elemTypeRepr->type());
+    MLoadTypedArrayElement *load = MLoadTypedArrayElement::New(alloc(), elements, scaledOffset, elemTypeRepr->type());
     current->add(load);
     current->push(load);
 
     // If we are reading in-bounds elements, we can use knowledge about
     // the array type to determine the result type, even if the opcode has
     // never executed. The known pushed type is only used to distinguish
     // uint32 reads that may produce either doubles or integers.
     types::TemporaryTypeSet *resultTypes = bytecodeTypes(pc);
@@ -6597,36 +6599,36 @@ IonBuilder::getElemTryComplexElemOfTyped
 
     MDefinition *type = loadTypedObjectType(obj);
     MDefinition *elemType = typeObjectForElementFromArrayStructType(type);
 
     // Get the length.
     size_t lenOfAll = objTypeReprs.arrayLength();
     if (lenOfAll >= size_t(INT_MAX)) // int32 max is bound
         return true;
-    MInstruction *length = MConstant::New(Int32Value(int32_t(lenOfAll)));
+    MInstruction *length = MConstant::New(alloc(), Int32Value(int32_t(lenOfAll)));
 
     *emitted = true;
     current->add(length);
 
     // Ensure index is an integer.
-    MInstruction *idInt32 = MToInt32::New(index);
+    MInstruction *idInt32 = MToInt32::New(alloc(), index);
     current->add(idInt32);
     index = idInt32;
 
     // Typed-object accesses usually in bounds (bail out otherwise).
     index = addBoundsCheck(index, length);
 
     // Convert array index to element data offset.
-    MConstant *alignment = MConstant::New(Int32Value(elemSize));
+    MConstant *alignment = MConstant::New(alloc(), Int32Value(elemSize));
     current->add(alignment);
 
     // Since we passed the bounds check, it is impossible for the
     // result of multiplication to overflow; so enable imul path.
-    MMul *indexAsByteOffset = MMul::New(index, alignment, MIRType_Int32,
+    MMul *indexAsByteOffset = MMul::New(alloc(), index, alignment, MIRType_Int32,
                                         MMul::Integer);
     current->add(indexAsByteOffset);
 
     // Find location within the owner object.
     MDefinition *owner, *ownerOffset;
     loadTypedObjectData(obj, indexAsByteOffset, &owner, &ownerOffset);
 
     // Create the derived type object.
@@ -6702,17 +6704,17 @@ IonBuilder::getElemTryTypedStatic(bool *
     if (!ptr)
         return true;
 
     // Emit LoadTypedArrayElementStatic.
 
     obj->setFoldedUnchecked();
     index->setFoldedUnchecked();
 
-    MLoadTypedArrayElementStatic *load = MLoadTypedArrayElementStatic::New(tarr, ptr);
+    MLoadTypedArrayElementStatic *load = MLoadTypedArrayElementStatic::New(alloc(), tarr, ptr);
     current->add(load);
     current->push(load);
 
     // The load is infallible if an undefined result will be coerced to the
     // appropriate numeric type if the read is out of bounds. The truncation
     // analysis picks up some of these cases, but is incomplete with respect
     // to others. For now, sniff the bytecode for simple patterns following
     // the load which guarantee a truncation or numeric conversion.
@@ -6756,29 +6758,29 @@ IonBuilder::getElemTryString(bool *emitt
         return true;
 
     // If the index is expected to be out-of-bounds, don't optimize to avoid
     // frequent bailouts.
     if (bytecodeTypes(pc)->hasType(types::Type::UndefinedType()))
         return true;
 
     // Emit fast path for string[index].
-    MInstruction *idInt32 = MToInt32::New(index);
+    MInstruction *idInt32 = MToInt32::New(alloc(), index);
     current->add(idInt32);
     index = idInt32;
 
-    MStringLength *length = MStringLength::New(obj);
+    MStringLength *length = MStringLength::New(alloc(), obj);
     current->add(length);
 
     index = addBoundsCheck(index, length);
 
-    MCharCodeAt *charCode = MCharCodeAt::New(obj, index);
+    MCharCodeAt *charCode = MCharCodeAt::New(alloc(), obj, index);
     current->add(charCode);
 
-    MFromCharCode *result = MFromCharCode::New(charCode);
+    MFromCharCode *result = MFromCharCode::New(alloc(), charCode);
     current->add(result);
     current->push(result);
 
     *emitted = true;
     return true;
 }
 
 bool
@@ -6795,29 +6797,29 @@ IonBuilder::getElemTryArguments(bool *em
     // Emit GetFrameArgument.
 
     JS_ASSERT(!info().argsObjAliasesFormals());
 
     // Type Inference has guaranteed this is an optimized arguments object.
     obj->setFoldedUnchecked();
 
     // To ensure that we are not looking above the number of actual arguments.
-    MArgumentsLength *length = MArgumentsLength::New();
+    MArgumentsLength *length = MArgumentsLength::New(alloc());
     current->add(length);
 
     // Ensure index is an integer.
-    MInstruction *idInt32 = MToInt32::New(index);
+    MInstruction *idInt32 = MToInt32::New(alloc(), index);
     current->add(idInt32);
     index = idInt32;
 
     // Bailouts if we read more than the number of actual arguments.
     index = addBoundsCheck(index, length);
 
     // Load the argument from the actual arguments.
-    MGetFrameArgument *load = MGetFrameArgument::New(index, analysis_.hasSetArg());
+    MGetFrameArgument *load = MGetFrameArgument::New(alloc(), index, analysis_.hasSetArg());
     current->add(load);
     current->push(load);
 
     types::TemporaryTypeSet *types = bytecodeTypes(pc);
     if (!pushTypeBarrier(load, types, true))
         return false;
 
     *emitted = true;
@@ -6892,17 +6894,17 @@ IonBuilder::getElemTryCache(bool *emitte
     // can attach stubs for particular properties.
     if (index->mightBeType(MIRType_String))
         barrier = true;
 
     // See note about always needing a barrier in jsop_getprop.
     if (needsToMonitorMissingProperties(types))
         barrier = true;
 
-    MInstruction *ins = MGetElementCache::New(obj, index, barrier);
+    MInstruction *ins = MGetElementCache::New(alloc(), obj, index, barrier);
 
     current->add(ins);
     current->push(ins);
 
     if (!resumeAfter(ins))
         return false;
 
     // Spice up type information.
@@ -6944,28 +6946,28 @@ IonBuilder::jsop_getelem_dense(MDefiniti
         types->hasType(types::Type::UndefinedType()) &&
         !ElementAccessHasExtraIndexedProperty(constraints(), obj);
 
     JSValueType knownType = JSVAL_TYPE_UNKNOWN;
     if (!barrier)
         knownType = GetElemKnownType(needsHoleCheck, types);
 
     // Ensure index is an integer.
-    MInstruction *idInt32 = MToInt32::New(index);
+    MInstruction *idInt32 = MToInt32::New(alloc(), index);
     current->add(idInt32);
     index = idInt32;
 
     // Get the elements vector.
-    MInstruction *elements = MElements::New(obj);
+    MInstruction *elements = MElements::New(alloc(), obj);
     current->add(elements);
 
     // Note: to help GVN, use the original MElements instruction and not
     // MConvertElementsToDoubles as operand. This is fine because converting
     // elements to double does not change the initialized length.
-    MInitializedLength *initLength = MInitializedLength::New(elements);
+    MInitializedLength *initLength = MInitializedLength::New(alloc(), elements);
     current->add(initLength);
 
     // If we can load the element as a definite double, make sure to check that
     // the array has been converted to homogenous doubles first.
     //
     // NB: We disable this optimization in parallel execution mode
     // because it is inherently not threadsafe (how do you convert the
     // array atomically when there might be concurrent readers)?
@@ -6987,23 +6989,23 @@ IonBuilder::jsop_getelem_dense(MDefiniti
 
     if (!readOutOfBounds) {
         // This load should not return undefined, so likely we're reading
         // in-bounds elements, and the array is packed or its holes are not
         // read. This is the best case: we can separate the bounds check for
         // hoisting.
         index = addBoundsCheck(index, initLength);
 
-        load = MLoadElement::New(elements, index, needsHoleCheck, loadDouble);
+        load = MLoadElement::New(alloc(), elements, index, needsHoleCheck, loadDouble);
         current->add(load);
     } else {
         // This load may return undefined, so assume that we *can* read holes,
         // or that we can read out-of-bounds accesses. In this case, the bounds
         // check is part of the opcode.
-        load = MLoadElementHole::New(elements, index, initLength, needsHoleCheck);
+        load = MLoadElementHole::New(alloc(), elements, index, initLength, needsHoleCheck);
         current->add(load);
 
         // If maybeUndefined was true, the typeset must have undefined, and
         // then either additional types or a barrier. This means we should
         // never have a typed version of LoadElementHole.
         JS_ASSERT(knownType == JSVAL_TYPE_UNKNOWN);
     }
 
@@ -7016,68 +7018,68 @@ IonBuilder::jsop_getelem_dense(MDefiniti
 
 MInstruction *
 IonBuilder::getTypedArrayLength(MDefinition *obj)
 {
     if (obj->isConstant() && obj->toConstant()->value().isObject()) {
         TypedArrayObject *tarr = &obj->toConstant()->value().toObject().as<TypedArrayObject>();
         int32_t length = (int32_t) tarr->length();
         obj->setFoldedUnchecked();
-        return MConstant::New(Int32Value(length));
-    }
-    return MTypedArrayLength::New(obj);
+        return MConstant::New(alloc(), Int32Value(length));
+    }
+    return MTypedArrayLength::New(alloc(), obj);
 }
 
 MInstruction *
 IonBuilder::getTypedArrayElements(MDefinition *obj)
 {
     if (obj->isConstant() && obj->toConstant()->value().isObject()) {
         TypedArrayObject *tarr = &obj->toConstant()->value().toObject().as<TypedArrayObject>();
         void *data = tarr->viewData();
 
         // The 'data' pointer can change in rare circumstances
         // (ArrayBufferObject::changeContents).
         types::TypeObjectKey *tarrType = types::TypeObjectKey::get(tarr);
         tarrType->watchStateChangeForTypedArrayBuffer(constraints());
 
         obj->setFoldedUnchecked();
-        return MConstantElements::New(data);
-    }
-    return MTypedArrayElements::New(obj);
+        return MConstantElements::New(alloc(), data);
+    }
+    return MTypedArrayElements::New(alloc(), obj);
 }
 
 MDefinition *
 IonBuilder::convertShiftToMaskForStaticTypedArray(MDefinition *id,
                                                   ArrayBufferView::ViewType viewType)
 {
     // No shifting is necessary if the typed array has single byte elements.
     if (TypedArrayShift(viewType) == 0)
         return id;
 
     // If the index is an already shifted constant, undo the shift to get the
     // absolute offset being accessed.
     if (id->isConstant() && id->toConstant()->value().isInt32()) {
         int32_t index = id->toConstant()->value().toInt32();
-        MConstant *offset = MConstant::New(Int32Value(index << TypedArrayShift(viewType)));
+        MConstant *offset = MConstant::New(alloc(), Int32Value(index << TypedArrayShift(viewType)));
         current->add(offset);
         return offset;
     }
 
     if (!id->isRsh() || id->isEffectful())
         return nullptr;
     if (!id->getOperand(1)->isConstant())
         return nullptr;
     const Value &value = id->getOperand(1)->toConstant()->value();
     if (!value.isInt32() || uint32_t(value.toInt32()) != TypedArrayShift(viewType))
         return nullptr;
 
     // Instead of shifting, mask off the low bits of the index so that
     // a non-scaled access on the typed array can be performed.
-    MConstant *mask = MConstant::New(Int32Value(~((1 << value.toInt32()) - 1)));
-    MBitAnd *ptr = MBitAnd::New(id->getOperand(0), mask);
+    MConstant *mask = MConstant::New(alloc(), Int32Value(~((1 << value.toInt32()) - 1)));
+    MBitAnd *ptr = MBitAnd::New(alloc(), id->getOperand(0), mask);
 
     ptr->infer(nullptr, nullptr);
     JS_ASSERT(!ptr->isEffectful());
 
     current->add(mask);
     current->add(ptr);
 
     return ptr;
@@ -7114,17 +7116,17 @@ IonBuilder::jsop_getelem_typed(MDefiniti
     bool maybeUndefined = types->hasType(types::Type::UndefinedType());
 
     // Reading from an Uint32Array will result in a double for values
     // that don't fit in an int32. We have to bailout if this happens
     // and the instruction is not known to return a double.
     bool allowDouble = types->hasType(types::Type::DoubleType());
 
     // Ensure id is an integer.
-    MInstruction *idInt32 = MToInt32::New(index);
+    MInstruction *idInt32 = MToInt32::New(alloc(), index);
     current->add(idInt32);
     index = idInt32;
 
     if (!maybeUndefined) {
         // Assume the index is in range, so that we can hoist the length,
         // elements vector and bounds check.
 
         // If we are reading in-bounds elements, we can use knowledge about
@@ -7140,17 +7142,17 @@ IonBuilder::jsop_getelem_typed(MDefiniti
         // Bounds check.
         index = addBoundsCheck(index, length);
 
         // Get the elements vector.
         MInstruction *elements = getTypedArrayElements(obj);
         current->add(elements);
 
         // Load the element.
-        MLoadTypedArrayElement *load = MLoadTypedArrayElement::New(elements, index, arrayType);
+        MLoadTypedArrayElement *load = MLoadTypedArrayElement::New(alloc(), elements, index, arrayType);
         current->add(load);
         current->push(load);
 
         // Note: we can ignore the type barrier here, we know the type must
         // be valid and unbarriered.
         load->setResultType(knownType);
         return true;
     } else {
@@ -7178,17 +7180,17 @@ IonBuilder::jsop_getelem_typed(MDefiniti
           default:
             MOZ_ASSUME_UNREACHABLE("Unknown typed array type");
         }
 
         // Assume we will read out-of-bound values. In this case the
         // bounds check will be part of the instruction, and the instruction
         // will always return a Value.
         MLoadTypedArrayElementHole *load =
-            MLoadTypedArrayElementHole::New(obj, index, arrayType, allowDouble);
+            MLoadTypedArrayElementHole::New(alloc(), obj, index, arrayType, allowDouble);
         current->add(load);
         current->push(load);
 
         return pushTypeBarrier(load, types, needsBarrier);
     }
 }
 
 bool
@@ -7214,17 +7216,17 @@ IonBuilder::jsop_setelem()
 
     if (script()->argumentsHasVarBinding() && object->mightBeType(MIRType_Magic))
         return abort("Type is not definitely lazy arguments.");
 
     if (!setElemTryCache(&emitted, object, index, value) || emitted)
         return emitted;
 
     // Emit call.
-    MInstruction *ins = MCallSetElement::New(object, index, value);
+    MInstruction *ins = MCallSetElement::New(alloc(), object, index, value);
     current->add(ins);
     current->push(value);
 
     return resumeAfter(ins);
 }
 
 bool
 IonBuilder::setElemTryTypedStatic(bool *emitted, MDefinition *object,
@@ -7257,21 +7259,21 @@ IonBuilder::setElemTryTypedStatic(bool *
 
     // Emit StoreTypedArrayElementStatic.
     object->setFoldedUnchecked();
     index->setFoldedUnchecked();
 
     // Clamp value to [0, 255] for Uint8ClampedArray.
     MDefinition *toWrite = value;
     if (viewType == ArrayBufferView::TYPE_UINT8_CLAMPED) {
-        toWrite = MClampToUint8::New(value);
+        toWrite = MClampToUint8::New(alloc(), value);
         current->add(toWrite->toInstruction());
     }
 
-    MInstruction *store = MStoreTypedArrayElementStatic::New(tarr, ptr, toWrite);
+    MInstruction *store = MStoreTypedArrayElementStatic::New(alloc(), tarr, ptr, toWrite);
     current->add(store);
     current->push(value);
 
     if (!resumeAfter(store))
         return false;
 
     *emitted = true;
     return true;
@@ -7298,17 +7300,17 @@ IonBuilder::setElemTryTyped(bool *emitte
 bool
 IonBuilder::setElemTryDense(bool *emitted, MDefinition *object,
                             MDefinition *index, MDefinition *value)
 {
     JS_ASSERT(*emitted == false);
 
     if (!ElementAccessIsDenseNative(object, index))
         return true;
-    if (PropertyWriteNeedsTypeBarrier(constraints(), current,
+    if (PropertyWriteNeedsTypeBarrier(alloc(), constraints(), current,
                                       &object, nullptr, &value, /* canModify = */ true))
     {
         return true;
     }
     if (!object->resultTypeSet())
         return true;
 
     types::TemporaryTypeSet::DoubleConversion conversion =
@@ -7361,33 +7363,33 @@ IonBuilder::setElemTryCache(bool *emitte
 
     // TODO: Bug 876650: remove this check:
     // Temporary disable the cache if non dense native,
     // until the cache supports more ics
     SetElemICInspector icInspect(inspector->setElemICInspector(pc));
     if (!icInspect.sawDenseWrite() && !icInspect.sawTypedArrayWrite())
         return true;
 
-    if (PropertyWriteNeedsTypeBarrier(constraints(), current,
+    if (PropertyWriteNeedsTypeBarrier(alloc(), constraints(), current,
                                       &object, nullptr, &value, /* canModify = */ true))
     {
         return true;
     }
 
     // We can avoid worrying about holes in the IC if we know a priori we are safe
     // from them. If TI can guard that there are no indexed properties on the prototype
     // chain, we know that we anen't missing any setters by overwriting the hole with
     // another value.
     bool guardHoles = ElementAccessHasExtraIndexedProperty(constraints(), object);
 
     if (NeedsPostBarrier(info(), value))
-        current->add(MPostWriteBarrier::New(object, value));
+        current->add(MPostWriteBarrier::New(alloc(), object, value));
 
     // Emit SetElementCache.
-    MInstruction *ins = MSetElementCache::New(object, index, value, script()->strict, guardHoles);
+    MInstruction *ins = MSetElementCache::New(alloc(), object, index, value, script()->strict, guardHoles);
     current->add(ins);
     current->push(value);
 
     if (!resumeAfter(ins))
         return false;
 
     *emitted = true;
     return true;
@@ -7401,41 +7403,41 @@ IonBuilder::jsop_setelem_dense(types::Te
     MIRType elementType = DenseNativeElementType(constraints(), obj);
     bool packed = ElementAccessIsPacked(constraints(), obj);
 
     // Writes which are on holes in the object do not have to bail out if they
     // cannot hit another indexed property on the object or its prototypes.
     bool writeOutOfBounds = !ElementAccessHasExtraIndexedProperty(constraints(), obj);
 
     if (NeedsPostBarrier(info(), value))
-        current->add(MPostWriteBarrier::New(obj, value));
+        current->add(MPostWriteBarrier::New(alloc(), obj, value));
 
     // Ensure id is an integer.
-    MInstruction *idInt32 = MToInt32::New(id);
+    MInstruction *idInt32 = MToInt32::New(alloc(), id);
     current->add(idInt32);
     id = idInt32;
 
     // Get the elements vector.
-    MElements *elements = MElements::New(obj);
+    MElements *elements = MElements::New(alloc(), obj);
     current->add(elements);
 
     // Ensure the value is a double, if double conversion might be needed.
     MDefinition *newValue = value;
     switch (conversion) {
       case types::TemporaryTypeSet::AlwaysConvertToDoubles:
       case types::TemporaryTypeSet::MaybeConvertToDoubles: {
-        MInstruction *valueDouble = MToDouble::New(value);
+        MInstruction *valueDouble = MToDouble::New(alloc(), value);
         current->add(valueDouble);
         newValue = valueDouble;
         break;
       }
 
       case types::TemporaryTypeSet::AmbiguousDoubleConversion: {
         JS_ASSERT(value->type() == MIRType_Int32);
-        MInstruction *maybeDouble = MMaybeToDoubleElement::New(elements, value);
+        MInstruction *maybeDouble = MMaybeToDoubleElement::New(alloc(), elements, value);
         current->add(maybeDouble);
         newValue = maybeDouble;
         break;
       }
 
       case types::TemporaryTypeSet::DontConvertToDoubles:
         break;
 
@@ -7451,37 +7453,37 @@ IonBuilder::jsop_setelem_dense(types::Te
 
     // Use MStoreElementHole if this SETELEM has written to out-of-bounds
     // indexes in the past. Otherwise, use MStoreElement so that we can hoist
     // the initialized length and bounds check.
     MStoreElementCommon *store;
     if (writeHole && writeOutOfBounds) {
         JS_ASSERT(safety == SetElem_Normal);
 
-        MStoreElementHole *ins = MStoreElementHole::New(obj, elements, id, newValue);
+        MStoreElementHole *ins = MStoreElementHole::New(alloc(), obj, elements, id, newValue);
         store = ins;
 
         current->add(ins);
         current->push(value);
 
         if (!resumeAfter(ins))
             return false;
     } else {
-        MInitializedLength *initLength = MInitializedLength::New(elements);
+        MInitializedLength *initLength = MInitializedLength::New(alloc(), elements);
         current->add(initLength);
 
         bool needsHoleCheck;
         if (safety == SetElem_Normal) {
             id = addBoundsCheck(id, initLength);
             needsHoleCheck = !packed && !writeOutOfBounds;
         } else {
             needsHoleCheck = false;
         }
 
-        MStoreElement *ins = MStoreElement::New(elements, id, newValue, needsHoleCheck);
+        MStoreElement *ins = MStoreElement::New(alloc(), elements, id, newValue, needsHoleCheck);
         store = ins;
 
         if (safety == SetElem_Unsafe)
             ins->setRacy();
 
         current->add(ins);
 
         if (safety == SetElem_Normal)
@@ -7514,17 +7516,17 @@ IonBuilder::jsop_setelem_typed(ScalarTyp
     } else {
         expectOOB = false;
     }
 
     if (expectOOB)
         spew("Emitting OOB TypedArray SetElem");
 
     // Ensure id is an integer.
-    MInstruction *idInt32 = MToInt32::New(id);
+    MInstruction *idInt32 = MToInt32::New(alloc(), id);
     current->add(idInt32);
     id = idInt32;
 
     // Get the length.
     MInstruction *length = getTypedArrayLength(obj);
     current->add(length);
 
     if (!expectOOB && safety == SetElem_Normal) {
@@ -7534,27 +7536,27 @@ IonBuilder::jsop_setelem_typed(ScalarTyp
 
     // Get the elements vector.
     MInstruction *elements = getTypedArrayElements(obj);
     current->add(elements);
 
     // Clamp value to [0, 255] for Uint8ClampedArray.
     MDefinition *toWrite = value;
     if (arrayType == ScalarTypeRepresentation::TYPE_UINT8_CLAMPED) {
-        toWrite = MClampToUint8::New(value);
+        toWrite = MClampToUint8::New(alloc(), value);
         current->add(toWrite->toInstruction());
     }
 
     // Store the value.
     MInstruction *ins;
     if (expectOOB) {
-        ins = MStoreTypedArrayElementHole::New(elements, length, id, toWrite, arrayType);
+        ins = MStoreTypedArrayElementHole::New(alloc(), elements, length, id, toWrite, arrayType);
     } else {
         MStoreTypedArrayElement *store =
-            MStoreTypedArrayElement::New(elements, id, toWrite, arrayType);
+            MStoreTypedArrayElement::New(alloc(), elements, id, toWrite, arrayType);
         if (safety == SetElem_Unsafe)
             store->setRacy();
         ins = store;
     }
 
     current->add(ins);
 
     if (safety == SetElem_Normal)
@@ -7582,31 +7584,31 @@ IonBuilder::jsop_length_fastPath()
         return false;
 
     MDefinition *obj = current->peek(-1);
 
     if (obj->mightBeType(MIRType_String)) {
         if (obj->mightBeType(MIRType_Object))
             return false;
         current->pop();
-        MStringLength *ins = MStringLength::New(obj);
+        MStringLength *ins = MStringLength::New(alloc(), obj);
         current->add(ins);
         current->push(ins);
         return true;
     }
 
     if (obj->mightBeType(MIRType_Object)) {
         types::TemporaryTypeSet *objTypes = obj->resultTypeSet();
 
         if (objTypes &&
             objTypes->getKnownClass() == &ArrayObject::class_ &&
             !objTypes->hasObjectFlags(constraints(), types::OBJECT_FLAG_LENGTH_OVERFLOW))
         {
             current->pop();
-            MElements *elements = MElements::New(obj);
+            MElements *elements = MElements::New(alloc(), obj);
             current->add(elements);
 
             // Read length.
             MArrayLength *length = new MArrayLength(elements);
             current->add(length);
             current->push(length);
             return true;
         }
@@ -7639,17 +7641,17 @@ bool
 IonBuilder::jsop_arguments_length()
 {
     // Type Inference has guaranteed this is an optimized arguments object.
     MDefinition *args = current->pop();
     args->setFoldedUnchecked();
 
     // We don't know anything from the callee
     if (inliningDepth_ == 0) {
-        MInstruction *ins = MArgumentsLength::New();
+        MInstruction *ins = MArgumentsLength::New(alloc());
         current->add(ins);
         current->push(ins);
         return true;
     }
 
     // We are inlining and know the number of arguments the callee pushed
     return pushConstant(Int32Value(inlineCallInfo_->argv().length()));
 }
@@ -7657,57 +7659,57 @@ IonBuilder::jsop_arguments_length()
 bool
 IonBuilder::jsop_rest()
 {
     JSObject *templateObject = inspector->getTemplateObject(pc);
     JS_ASSERT(templateObject->is<ArrayObject>());
 
     if (inliningDepth_ == 0) {
         // We don't know anything about the callee.
-        MArgumentsLength *numActuals = MArgumentsLength::New();
+        MArgumentsLength *numActuals = MArgumentsLength::New(alloc());
         current->add(numActuals);
 
         // Pass in the number of actual arguments, the number of formals (not
         // including the rest parameter slot itself), and the template object.
-        MRest *rest = MRest::New(numActuals, info().nargs() - 1, templateObject);
+        MRest *rest = MRest::New(alloc(), numActuals, info().nargs() - 1, templateObject);
         current->add(rest);
         current->push(rest);
         return true;
     }
 
     // We know the exact number of arguments the callee pushed.
     unsigned numActuals = inlineCallInfo_->argv().length();
     unsigned numFormals = info().nargs() - 1;
     unsigned numRest = numActuals > numFormals ? numActuals - numFormals : 0;
 
-    MNewArray *array = new MNewArray(numRest, templateObject, MNewArray::NewArray_Allocating);
+    MNewArray *array = MNewArray::New(alloc(), numRest, templateObject, MNewArray::NewArray_Allocating);
     current->add(array);
 
     if (numActuals <= numFormals) {
         current->push(array);
         return true;
     }
 
-    MElements *elements = MElements::New(array);
+    MElements *elements = MElements::New(alloc(), array);
     current->add(elements);
 
     // Unroll the argument copy loop. We don't need to do any bounds or hole
     // checking here.
     MConstant *index;
     for (unsigned i = numFormals; i < numActuals; i++) {
-        index = MConstant::New(Int32Value(i - numFormals));
+        index = MConstant::New(alloc(), Int32Value(i - numFormals));
         current->add(index);
 
         MDefinition *arg = inlineCallInfo_->argv()[i];
-        MStoreElement *store = MStoreElement::New(elements, index, arg,
+        MStoreElement *store = MStoreElement::New(alloc(), elements, index, arg,
                                                   /* needsHoleCheck = */ false);
         current->add(store);
     }
 
-    MSetInitializedLength *initLength = MSetInitializedLength::New(elements, index);
+    MSetInitializedLength *initLength = MSetInitializedLength::New(alloc(), elements, index);
     current->add(initLength);
     current->push(array);
 
     return true;
 }
 
 bool
 IonBuilder::getDefiniteSlot(types::TemporaryTypeSet *types, PropertyName *name,
@@ -7726,17 +7728,17 @@ IonBuilder::getDefiniteSlot(types::Tempo
     return property->maybeTypes() &&
            property->maybeTypes()->definiteProperty() &&
            !property->configured(constraints(), type);
 }
 
 bool
 IonBuilder::jsop_runonce()
 {
-    MRunOncePrologue *ins = MRunOncePrologue::New();
+    MRunOncePrologue *ins = MRunOncePrologue::New(alloc());
     current->add(ins);
     return resumeAfter(ins);
 }
 
 bool
 IonBuilder::jsop_not()
 {
     MDefinition *value = current->pop();
@@ -7852,17 +7854,17 @@ IonBuilder::testCommonGetterSetter(types
     // ensure there isn't a lower shadowing getter or setter installed in the
     // future.
     freezePropertiesForCommonPrototype(types, name, foundProto);
 
     // Add a shape guard on the prototype we found the property on. The rest of
     // the prototype chain is guarded by TI freezes. Note that a shape guard is
     // good enough here, even in the proxy case, because we have ensured there
     // are no lookup hooks for this property.
-    MInstruction *wrapper = MConstant::New(ObjectValue(*foundProto));
+    MInstruction *wrapper = MConstant::New(alloc(), ObjectValue(*foundProto));
     current->add(wrapper);
 
     return addShapeGuard(wrapper, lastProperty, Bailout_ShapeGuard);
 }
 
 bool
 IonBuilder::annotateGetPropertyCache(MDefinition *obj, MGetPropertyCache *getPropCache,
                                      types::TemporaryTypeSet *objTypes,
@@ -7882,17 +7884,17 @@ IonBuilder::annotateGetPropertyCache(MDe
     // Object's typeset should be a proper object
     if (!objTypes || objTypes->baseFlags() || objTypes->unknownObject())
         return true;
 
     unsigned int objCount = objTypes->getObjectCount();
     if (objCount == 0)
         return true;
 
-    InlinePropertyTable *inlinePropTable = getPropCache->initInlinePropertyTable(pc);
+    InlinePropertyTable *inlinePropTable = getPropCache->initInlinePropertyTable(alloc(), pc);
     if (!inlinePropTable)
         return false;
 
     // Ensure that the relevant property typeset for each type object is
     // is a single-object typeset containing a JSFunction
     for (unsigned int i = 0; i < objCount; i++) {
         types::TypeObject *baseTypeObj = objTypes->getTypeObject(i);
         if (!baseTypeObj)
@@ -7908,17 +7910,17 @@ IonBuilder::annotateGetPropertyCache(MDe
         JSObject *singleton = testSingletonProperty(typeObj->proto().toObject(), name);
         if (!singleton)
             continue;
 
         // Don't add cases corresponding to non-observed pushes
         if (!pushedTypes->hasType(types::Type::ObjectType(singleton)))
             continue;
 
-        if (!inlinePropTable->addEntry(baseTypeObj, &singleton->as<JSFunction>()))
+        if (!inlinePropTable->addEntry(alloc(), baseTypeObj, &singleton->as<JSFunction>()))
             return false;
     }
 
     if (inlinePropTable->numEntries() == 0) {
         getPropCache->clearInlinePropertyTable();
         return true;
     }
 
@@ -7930,17 +7932,17 @@ IonBuilder::annotateGetPropertyCache(MDe
 
     // If we successfully annotated the GetPropertyCache and there are inline cases,
     // then keep a resume point of the state right before this instruction for use
     // later when we have to bail out to this point in the fallback case of a
     // PolyInlineDispatch.
     if (inlinePropTable->numEntries() > 0) {
         // Push the object back onto the stack temporarily to capture the resume point.
         current->push(obj);
-        MResumePoint *resumePoint = MResumePoint::New(current, pc, callerResumePoint_,
+        MResumePoint *resumePoint = MResumePoint::New(alloc(), current, pc, callerResumePoint_,
                                                       MResumePoint::ResumeAt);
         if (!resumePoint)
             return false;
         inlinePropTable->setPriorResumePoint(resumePoint);
         current->pop();
     }
     return true;
 }
@@ -7960,28 +7962,28 @@ IonBuilder::invalidatedIdempotentCache()
     return false;
 }
 
 bool
 IonBuilder::loadSlot(MDefinition *obj, size_t slot, size_t nfixed, MIRType rvalType,
                      bool barrier, types::TemporaryTypeSet *types)
 {
     if (slot < nfixed) {
-        MLoadFixedSlot *load = MLoadFixedSlot::New(obj, slot);
+        MLoadFixedSlot *load = MLoadFixedSlot::New(alloc(), obj, slot);
         current->add(load);
         current->push(load);
 
         load->setResultType(rvalType);
         return pushTypeBarrier(load, types, barrier);
     }
 
-    MSlots *slots = MSlots::New(obj);
+    MSlots *slots = MSlots::New(alloc(), obj);
     current->add(slots);
 
-    MLoadSlot *load = MLoadSlot::New(slots, slot - nfixed);
+    MLoadSlot *load = MLoadSlot::New(alloc(), slots, slot - nfixed);
     current->add(load);
     current->push(load);
 
     load->setResultType(rvalType);
     return pushTypeBarrier(load, types, barrier);
 }
 
 bool
@@ -7995,28 +7997,28 @@ IonBuilder::loadSlot(MDefinition *obj, S
 }
 
 bool
 IonBuilder::storeSlot(MDefinition *obj, size_t slot, size_t nfixed,
                       MDefinition *value, bool needsBarrier,
                       MIRType slotType /* = MIRType_None */)
 {
     if (slot < nfixed) {
-        MStoreFixedSlot *store = MStoreFixedSlot::New(obj, slot, value);
+        MStoreFixedSlot *store = MStoreFixedSlot::New(alloc(), obj, slot, value);
         current->add(store);
         current->push(value);
         if (needsBarrier)
             store->setNeedsBarrier();
         return resumeAfter(store);
     }
 
-    MSlots *slots = MSlots::New(obj);
+    MSlots *slots = MSlots::New(alloc(), obj);
     current->add(slots);
 
-    MStoreSlot *store = MStoreSlot::New(slots, slot - nfixed, value);
+    MStoreSlot *store = MStoreSlot::New(alloc(), slots, slot - nfixed, value);
     current->add(store);
     current->push(value);
     if (needsBarrier)
         store->setNeedsBarrier();
     if (slotType != MIRType_None)
         store->setSlotType(slotType);
     return resumeAfter(store);
 }
@@ -8046,17 +8048,17 @@ IonBuilder::jsop_getprop(PropertyName *n
                                                 current->peek(-1), name, types);
 
     // Always use a call if we are doing the definite properties analysis and
     // not actually emitting code, to simplify later analysis. Also skip deeper
     // analysis if there are no known types for this operation, as it will
     // always invalidate when executing.
     if (info().executionMode() == DefinitePropertiesAnalysis || types->empty()) {
         MDefinition *obj = current->peek(-1);
-        MCallGetProperty *call = MCallGetProperty::New(obj, name, *pc == JSOP_CALLPROP);
+        MCallGetProperty *call = MCallGetProperty::New(alloc(), obj, name, *pc == JSOP_CALLPROP);
         current->add(call);
 
         // During the definite properties analysis we can still try to bake in
         // constants read off the prototype chain, to allow inlining later on.
         // In this case we still need the getprop call so that the later
         // analysis knows when the |this| value has been read from.
         if (info().executionMode() == DefinitePropertiesAnalysis) {
             if (!getPropTryConstant(&emitted, name, types) || emitted)
@@ -8089,17 +8091,17 @@ IonBuilder::jsop_getprop(PropertyName *n
         return emitted;
 
     // Try to emit a polymorphic cache.
     if (!getPropTryCache(&emitted, name, barrier, types) || emitted)
         return emitted;
 
     // Emit a call.
     MDefinition *obj = current->pop();
-    MCallGetProperty *call = MCallGetProperty::New(obj, name, *pc == JSOP_CALLPROP);
+    MCallGetProperty *call = MCallGetProperty::New(alloc(), obj, name, *pc == JSOP_CALLPROP);
     current->add(call);
     current->push(call);
     if (!resumeAfter(call))
         return false;
 
     return pushTypeBarrier(call, types, true);
 }
 
@@ -8132,23 +8134,23 @@ IonBuilder::getPropTryConstant(bool *emi
     if (!testSingletonPropertyTypes(current->peek(-1), singleton, name, &testObject, &testString))
         return true;
 
     MDefinition *obj = current->pop();
 
     // Property access is a known constant -- safe to emit.
     JS_ASSERT(!testString || !testObject);
     if (testObject)
-        current->add(MGuardObject::New(obj));
+        current->add(MGuardObject::New(alloc(), obj));
     else if (testString)
-        current->add(MGuardString::New(obj));
+        current->add(MGuardString::New(alloc(), obj));
     else
         obj->setFoldedUnchecked();
 
-    MConstant *known = MConstant::New(ObjectValue(*singleton));
+    MConstant *known = MConstant::New(alloc(), ObjectValue(*singleton));
 
     current->add(known);
     current->push(known);
 
     *emitted = true;
     return true;
 }
 
@@ -8207,17 +8209,17 @@ IonBuilder::getPropTryScalarPropOfTypedO
 
     // Reading from an Uint32Array will result in a double for values
     // that don't fit in an int32. We have to bailout if this happens
     // and the instruction is not known to return a double.
     bool allowDouble = resultTypes->hasType(types::Type::DoubleType());
     MIRType knownType = MIRTypeForTypedArrayRead(fieldTypeRepr->type(), allowDouble);
 
     MLoadTypedArrayElement *load =
-        MLoadTypedArrayElement::New(elements, scaledOffset,
+        MLoadTypedArrayElement::New(alloc(), elements, scaledOffset,
                                     fieldTypeRepr->type());
     load->setResultType(knownType);
     load->setResultTypeSet(resultTypes);
     current->add(load);
     current->push(load);
     *emitted = true;
     return true;
 }
@@ -8266,22 +8268,22 @@ IonBuilder::getPropTryDefiniteSlot(bool 
     JS_ASSERT(*emitted == false);
     types::HeapTypeSetKey property;
     if (!getDefiniteSlot(current->peek(-1)->resultTypeSet(), name, &property))
         return true;
 
     MDefinition *obj = current->pop();
     MDefinition *useObj = obj;
     if (obj->type() != MIRType_Object) {
-        MGuardObject *guard = MGuardObject::New(obj);
+        MGuardObject *guard = MGuardObject::New(alloc(), obj);
         current->add(guard);
         useObj = guard;
     }
 
-    MLoadFixedSlot *fixed = MLoadFixedSlot::New(useObj, property.maybeTypes()->definiteSlot());
+    MLoadFixedSlot *fixed = MLoadFixedSlot::New(alloc(), useObj, property.maybeTypes()->definiteSlot());
     if (!barrier)
         fixed->setResultType(MIRTypeFromValueType(types->getKnownTypeTag()));
 
     current->add(fixed);
     current->push(fixed);
 
     if (!pushTypeBarrier(fixed, types, barrier))
         return false;
@@ -8309,46 +8311,46 @@ IonBuilder::getPropTryCommonGetter(bool 
         return true;
 
     bool isDOM = objTypes->isDOMClass();
 
     MDefinition *obj = current->pop();
 
     if (isDOM && testShouldDOMCall(objTypes, commonGetter, JSJitInfo::Getter)) {
         const JSJitInfo *jitinfo = commonGetter->jitInfo();
-        MGetDOMProperty *get = MGetDOMProperty::New(jitinfo, obj, guard);
+        MGetDOMProperty *get = MGetDOMProperty::New(alloc(), jitinfo, obj, guard);
         current->add(get);
         current->push(get);
 
         if (get->isEffectful() && !resumeAfter(get))
             return false;
         bool barrier = DOMCallNeedsBarrier(jitinfo, types);
-        MDefinition *replace = EnsureDefiniteType(get, jitinfo->returnType);
+        MDefinition *replace = ensureDefiniteType(get, jitinfo->returnType);
         if (replace != get) {
             current->pop();
             current->push(replace);
         }
         if (!pushTypeBarrier(replace, types, barrier))
             return false;
 
         *emitted = true;
         return true;
     }
 
     // Don't call the getter with a primitive value.
     if (objTypes->getKnownTypeTag() != JSVAL_TYPE_OBJECT) {
-        MGuardObject *guardObj = MGuardObject::New(obj);
+        MGuardObject *guardObj = MGuardObject::New(alloc(), obj);
         current->add(guardObj);
         obj = guardObj;
     }
 
     // Spoof stack to expected state for call.
     pushConstant(ObjectValue(*commonGetter));
 
-    MPassArg *wrapper = MPassArg::New(obj);
+    MPassArg *wrapper = MPassArg::New(alloc(), obj);
     current->add(wrapper);
     current->push(wrapper);
 
     CallInfo callInfo(false);
     if (!callInfo.init(current, 0))
         return false;
 
     // Inline if we can, otherwise, forget it and just generate a call.
@@ -8411,17 +8413,17 @@ IonBuilder::getPropTryInlineAccess(bool 
         JS_ASSERT(shape);
 
         if (!loadSlot(obj, shape, rvalType, barrier, types))
             return false;
     } else {
         JS_ASSERT(shapes.length() > 1);
         spew("Inlining polymorphic GETPROP");
 
-        MGetPropertyPolymorphic *load = MGetPropertyPolymorphic::New(obj, name);
+        MGetPropertyPolymorphic *load = MGetPropertyPolymorphic::New(alloc(), obj, name);
         current->add(load);
         current->push(load);
 
         for (size_t i = 0; i < shapes.length(); i++) {
             Shape *objShape = shapes[i];
             Shape *shape =  objShape->searchLinear(NameToId(name));
             JS_ASSERT(shape);
             if (!load->addShape(objShape, shape))
@@ -8453,17 +8455,17 @@ IonBuilder::getPropTryCache(bool *emitte
     // that it can be safely unboxed to an object.
     if (obj->type() != MIRType_Object) {
         types::TemporaryTypeSet *types = obj->resultTypeSet();
         if (!types || !types->objectOrSentinel())
             return true;
     }
 
     current->pop();
-    MGetPropertyCache *load = MGetPropertyCache::New(obj, name);
+    MGetPropertyCache *load = MGetPropertyCache::New(alloc(), obj, name);
 
     // Try to mark the cache as idempotent.
     //
     // In parallel execution, idempotency of caches is ignored, since we
     // repeat the entire ForkJoin workload if we bail out. Note that it's
     // overly restrictive to mark everything as idempotent, because we can
     // treat non-idempotent caches in parallel as repeatable.
     if (obj->type() == MIRType_Object && !invalidatedIdempotentCache() &&
@@ -8528,32 +8530,32 @@ IonBuilder::jsop_setprop(PropertyName *n
     MDefinition *value = current->pop();
     MDefinition *obj = current->pop();
 
     bool emitted = false;
 
     // Always use a call if we are doing the definite properties analysis and
     // not actually emitting code, to simplify later analysis.
     if (info().executionMode() == DefinitePropertiesAnalysis) {
-        MInstruction *ins = MCallSetProperty::New(obj, value, name, script()->strict);
+        MInstruction *ins = MCallSetProperty::New(alloc(), obj, value, name, script()->strict);
         current->add(ins);
         current->push(value);
         return resumeAfter(ins);
     }
 
     // Add post barrier if needed.
     if (NeedsPostBarrier(info(), value))
-        current->add(MPostWriteBarrier::New(obj, value));
+        current->add(MPostWriteBarrier::New(alloc(), obj, value));
 
     // Try to inline a common property setter, or make a call.
     if (!setPropTryCommonSetter(&emitted, obj, name, value) || emitted)
         return emitted;
 
     types::TemporaryTypeSet *objTypes = obj->resultTypeSet();
-    bool barrier = PropertyWriteNeedsTypeBarrier(constraints(), current, &obj, name, &value,
+    bool barrier = PropertyWriteNeedsTypeBarrier(alloc(), constraints(), current, &obj, name, &value,
                                                  /* canModify = */ true);
 
     // Try to emit stores to known binary data blocks
     if (!setPropTryTypedObject(&emitted, obj, name, value) || emitted)
         return emitted;
 
     // Try to emit store from definite slots.
     if (!setPropTryDefiniteSlot(&emitted, obj, name, value, barrier, objTypes) || emitted)
@@ -8563,17 +8565,17 @@ IonBuilder::jsop_setprop(PropertyName *n
     if (!setPropTryInlineAccess(&emitted, obj, name, value, barrier, objTypes) || emitted)
         return emitted;
 
     // Try to emit a polymorphic cache.
     if (!setPropTryCache(&emitted, obj, name, value, barrier, objTypes) || emitted)
         return emitted;
 
     // Emit call.
-    MInstruction *ins = MCallSetProperty::New(obj, value, name, script()->strict);
+    MInstruction *ins = MCallSetProperty::New(alloc(), obj, value, name, script()->strict);
     current->add(ins);
     current->push(value);
     return resumeAfter(ins);
 }
 
 bool
 IonBuilder::setPropTryCommonSetter(bool *emitted, MDefinition *obj,
                                    PropertyName *name, MDefinition *value)
@@ -8604,36 +8606,36 @@ IonBuilder::setPropTryCommonSetter(bool 
     if (!setPropTryCommonDOMSetter(emitted, obj, value, commonSetter, isDOM))
         return false;
 
     if (*emitted)
         return true;
 
     // Don't call the setter with a primitive value.
     if (objTypes->getKnownTypeTag() != JSVAL_TYPE_OBJECT) {
-        MGuardObject *guardObj = MGuardObject::New(obj);
+        MGuardObject *guardObj = MGuardObject::New(alloc(), obj);
         current->add(guardObj);
         obj = guardObj;
     }
 
     // Dummy up the stack, as in getprop. We are pushing an extra value, so
     // ensure there is enough space.
     uint32_t depth = current->stackDepth() + 3;
     if (depth > current->nslots()) {
         if (!current->increaseSlots(depth - current->nslots()))
             return false;
     }
 
     pushConstant(ObjectValue(*commonSetter));
 
-    MPassArg *wrapper = MPassArg::New(obj);
+    MPassArg *wrapper = MPassArg::New(alloc(), obj);
     current->push(wrapper);
     current->add(wrapper);
 
-    MPassArg *arg = MPassArg::New(value);
+    MPassArg *arg = MPassArg::New(alloc(), value);
     current->push(arg);
     current->add(arg);
 
     // Call the setter. Note that we have to push the original value, not
     // the setter's return value.
     CallInfo callInfo(false);
     if (!callInfo.init(current, 1))
         return false;
@@ -8673,17 +8675,17 @@ IonBuilder::setPropTryCommonDOMSetter(bo
         return true;
 
     types::TemporaryTypeSet *objTypes = obj->resultTypeSet();
     if (!testShouldDOMCall(objTypes, setter, JSJitInfo::Setter))
         return true;
 
     // Emit SetDOMProperty.
     JS_ASSERT(setter->jitInfo()->type == JSJitInfo::Setter);
-    MSetDOMProperty *set = MSetDOMProperty::New(setter->jitInfo()->setter, obj, value);
+    MSetDOMProperty *set = MSetDOMProperty::New(alloc(), setter->jitInfo()->setter, obj, value);
 
     current->add(set);
     current->push(value);
 
     if (!resumeAfter(set))
         return false;
 
     *emitted = true;
@@ -8750,17 +8752,17 @@ IonBuilder::setPropTryDefiniteSlot(bool 
 
     if (barrier)
         return true;
 
     types::HeapTypeSetKey property;
     if (!getDefiniteSlot(obj->resultTypeSet(), name, &property))
         return true;
 
-    MStoreFixedSlot *fixed = MStoreFixedSlot::New(obj, property.maybeTypes()->definiteSlot(), value);
+    MStoreFixedSlot *fixed = MStoreFixedSlot::New(alloc(), obj, property.maybeTypes()->definiteSlot(), value);
     current->add(fixed);
     current->push(value);
 
     if (property.needsBarrier(constraints()))
         fixed->setNeedsBarrier();
 
     if (!resumeAfter(fixed))
         return false;
@@ -8805,17 +8807,17 @@ IonBuilder::setPropTryInlineAccess(bool 
 
         bool needsBarrier = objTypes->propertyNeedsBarrier(constraints(), NameToId(name));
         if (!storeSlot(obj, shape, value, needsBarrier))
             return false;
     } else {
         JS_ASSERT(shapes.length() > 1);
         spew("Inlining polymorphic SETPROP");
 
-        MSetPropertyPolymorphic *ins = MSetPropertyPolymorphic::New(obj, value);
+        MSetPropertyPolymorphic *ins = MSetPropertyPolymorphic::New(alloc(), obj, value);
         current->add(ins);
         current->push(value);
 
         for (size_t i = 0; i < shapes.length(); i++) {
             Shape *objShape = shapes[i];
             Shape *shape =  objShape->searchLinear(NameToId(name));
             JS_ASSERT(shape);
             if (!ins->addShape(objShape, shape))
@@ -8836,17 +8838,17 @@ IonBuilder::setPropTryInlineAccess(bool 
 bool
 IonBuilder::setPropTryCache(bool *emitted, MDefinition *obj,
                             PropertyName *name, MDefinition *value,
                             bool barrier, types::TemporaryTypeSet *objTypes)
 {
     JS_ASSERT(*emitted == false);
 
     // Emit SetPropertyCache.
-    MSetPropertyCache *ins = MSetPropertyCache::New(obj, value, name, script()->strict, barrier);
+    MSetPropertyCache *ins = MSetPropertyCache::New(alloc(), obj, value, name, script()->strict, barrier);
 
     if (!objTypes || objTypes->propertyNeedsBarrier(constraints(), NameToId(name)))
         ins->setNeedsBarrier();
 
     current->add(ins);
     current->push(value);
 
     if (!resumeAfter(ins))
@@ -8856,31 +8858,31 @@ IonBuilder::setPropTryCache(bool *emitte
     return true;
 }
 
 bool
 IonBuilder::jsop_delprop(PropertyName *name)
 {
     MDefinition *obj = current->pop();
 
-    MInstruction *ins = MDeleteProperty::New(obj, name);
+    MInstruction *ins = MDeleteProperty::New(alloc(), obj, name);
 
     current->add(ins);
     current->push(ins);
 
     return resumeAfter(ins);
 }
 
 bool
 IonBuilder::jsop_delelem()
 {
     MDefinition *index = current->pop();
     MDefinition *obj = current->pop();
 
-    MDeleteElement *ins = MDeleteElement::New(obj, index);
+    MDeleteElement *ins = MDeleteElement::New(alloc(), obj, index);
     current->add(ins);
     current->push(ins);
 
     return resumeAfter(ins);
 }
 
 bool
 IonBuilder::jsop_regexp(RegExpObject *reobj)
@@ -8907,58 +8909,58 @@ IonBuilder::jsop_regexp(RegExpObject *re
         DebugOnly<uint32_t> origFlags = reobj->getFlags();
         DebugOnly<uint32_t> staticsFlags = res->getFlags();
         JS_ASSERT((origFlags & staticsFlags) == staticsFlags);
 
         if (!reobj->global() && !reobj->sticky())
             mustClone = false;
     }
 
-    MRegExp *regexp = MRegExp::New(reobj, prototype, mustClone);
+    MRegExp *regexp = MRegExp::New(alloc(), reobj, prototype, mustClone);
     current->add(regexp);
     current->push(regexp);
 
     regexp->setMovable();
 
     // The MRegExp is set to be movable.
     // That would be incorrect for global/sticky, because lastIndex could be wrong.
     // Therefore setting the lastIndex to 0. That is faster than removing the movable flag.
     if (reobj->sticky() || reobj->global()) {
         JS_ASSERT(mustClone);
-        MConstant *zero = MConstant::New(Int32Value(0));
+        MConstant *zero = MConstant::New(alloc(), Int32Value(0));
         current->add(zero);
 
         MStoreFixedSlot *lastIndex =
-            MStoreFixedSlot::New(regexp, RegExpObject::lastIndexSlot(), zero);
+            MStoreFixedSlot::New(alloc(), regexp, RegExpObject::lastIndexSlot(), zero);
         current->add(lastIndex);
     }
 
     return true;
 }
 
 bool
 IonBuilder::jsop_object(JSObject *obj)
 {
-    MConstant *ins = MConstant::New(ObjectValue(*obj));
+    MConstant *ins = MConstant::New(alloc(), ObjectValue(*obj));
     current->add(ins);
     current->push(ins);
 
     return true;
 }
 
 bool
 IonBuilder::jsop_lambda(JSFunction *fun)
 {
     JS_ASSERT(analysis().usesScopeChain());
     if (fun->isArrow())
         return abort("bound arrow function");
     if (fun->isNative() && IsAsmJSModuleNative(fun->native()))
         return abort("asm.js module function");
 
-    MLambda *ins = MLambda::New(current->scopeChain(), fun);
+    MLambda *ins = MLambda::New(alloc(), current->scopeChain(), fun);
     current->add(ins);
     current->push(ins);
 
     return resumeAfter(ins);
 }
 
 bool
 IonBuilder::jsop_setarg(uint32_t arg)
@@ -8969,31 +8971,31 @@ IonBuilder::jsop_setarg(uint32_t arg)
     // captured by the GETARG and by the resume point, only by
     // MGetFrameArgument.
     JS_ASSERT(analysis_.hasSetArg());
     MDefinition *val = current->peek(-1);
 
     // If an arguments object is in use, and it aliases formals, then all SETARGs
     // must go through the arguments object.
     if (info().argsObjAliasesFormals()) {
-        current->add(MSetArgumentsObjectArg::New(current->argumentsObject(), GET_SLOTNO(pc), val));
+        current->add(MSetArgumentsObjectArg::New(alloc(), current->argumentsObject(), GET_SLOTNO(pc), val));
         return true;
     }
 
     // Otherwise, if a magic arguments is in use, and it aliases formals, and there exist
     // arguments[...] GETELEM expressions in the script, then SetFrameArgument must be used.
     // If no arguments[...] GETELEM expressions are in the script, and an argsobj is not
     // required, then it means that any aliased argument set can never be observed, and
     // the frame does not actually need to be updated with the new arg value.
     if (info().argumentsAliasesFormals()) {
         // Try-catch within inline frames is not yet supported.
         if (isInlineBuilder())
             return abort("JSOP_SETARG with magic arguments in inlined function.");
 
-        MSetFrameArgument *store = MSetFrameArgument::New(arg, val);
+        MSetFrameArgument *store = MSetFrameArgument::New(alloc(), arg, val);
         current->add(store);
         current->setArg(arg);
         return true;
     }
 
     // If this assignment is at the start of the function and is coercing
     // the original value for the argument which was passed in, loosen
     // the type information for that original argument if it is currently
@@ -9012,17 +9014,17 @@ IonBuilder::jsop_setarg(uint32_t arg)
                 for (MUseDefIterator iter(op); iter; iter++) {
                     MDefinition *def = iter.def();
                     if (def == val)
                         continue;
                     otherUses = true;
                 }
                 if (!otherUses) {
                     JS_ASSERT(op->resultTypeSet() == &argTypes[arg]);
-                    if (!argTypes[arg].addType(types::Type::UnknownType(), temp_->lifoAlloc()))
+                    if (!argTypes[arg].addType(types::Type::UnknownType(), alloc_->lifoAlloc()))
                         return false;
                 }
             }
         }
     }
 
     current->setArg(arg);
     return true;
@@ -9039,32 +9041,32 @@ IonBuilder::jsop_defvar(uint32_t index)
     unsigned attrs = JSPROP_ENUMERATE | JSPROP_PERMANENT;
     if (JSOp(*pc) == JSOP_DEFCONST)
         attrs |= JSPROP_READONLY;
 
     // Pass the ScopeChain.
     JS_ASSERT(analysis().usesScopeChain());
 
     // Bake the name pointer into the MDefVar.
-    MDefVar *defvar = MDefVar::New(name, attrs, current->scopeChain());
+    MDefVar *defvar = MDefVar::New(alloc(), name, attrs, current->scopeChain());
     current->add(defvar);
 
     return resumeAfter(defvar);
 }
 
 bool
 IonBuilder::jsop_deffun(uint32_t index)
 {
     JSFunction *fun = script()->getFunction(index);
     if (fun->isNative() && IsAsmJSModuleNative(fun->native()))
         return abort("asm.js module function");
 
     JS_ASSERT(analysis().usesScopeChain());
 
-    MDefFun *deffun = MDefFun::New(fun, current->scopeChain());
+    MDefFun *deffun = MDefFun::New(alloc(), fun, current->scopeChain());
     current->add(deffun);
 
     return resumeAfter(deffun);
 }
 
 bool
 IonBuilder::jsop_this()
 {
@@ -9100,30 +9102,30 @@ IonBuilder::jsop_this()
     MDefinition *def = current->getSlot(info().thisSlot());
 
     if (def->type() == MIRType_Object) {
         // If we already computed a |this| object, we can reuse it.
         current->push(def);
         return true;
     }
 
-    MComputeThis *thisObj = MComputeThis::New(def);
+    MComputeThis *thisObj = MComputeThis::New(alloc(), def);
     current->add(thisObj);
     current->push(thisObj);
 
     current->setSlot(info().thisSlot(), thisObj);
 
     return resumeAfter(thisObj);
 }
 
 bool
 IonBuilder::jsop_typeof()
 {
     MDefinition *input = current->pop();
-    MTypeOf *ins = MTypeOf::New(input, input->type());
+    MTypeOf *ins = MTypeOf::New(alloc(), input, input->type());
 
     ins->infer();
 
     current->add(ins);
     current->push(ins);
 
     return true;
 }
@@ -9131,93 +9133,93 @@ IonBuilder::jsop_typeof()
 bool
 IonBuilder::jsop_toid()
 {
     // No-op if the index is an integer.
     if (current->peek(-1)->type() == MIRType_Int32)
         return true;
 
     MDefinition *index = current->pop();
-    MToId *ins = MToId::New(current->peek(-1), index);
+    MToId *ins = MToId::New(alloc(), current->peek(-1), index);
 
     current->add(ins);
     current->push(ins);
 
     return resumeAfter(ins);
 }
 
 bool
 IonBuilder::jsop_iter(uint8_t flags)
 {
     if (flags != JSITER_ENUMERATE)
         nonStringIteration_ = true;
 
     MDefinition *obj = current->pop();
-    MInstruction *ins = MIteratorStart::New(obj, flags);
+    MInstruction *ins = MIteratorStart::New(alloc(), obj, flags);
 
     if (!iterators_.append(ins))
         return false;
 
     current->add(ins);
     current->push(ins);
 
     return resumeAfter(ins);
 }
 
 bool
 IonBuilder::jsop_iternext()
 {
     MDefinition *iter = current->peek(-1);
-    MInstruction *ins = MIteratorNext::New(iter);
+    MInstruction *ins = MIteratorNext::New(alloc(), iter);
 
     current->add(ins);
     current->push(ins);
 
     if (!resumeAfter(ins))
         return false;
 
     if (!nonStringIteration_ && !inspector->hasSeenNonStringIterNext(pc)) {
-        ins = MUnbox::New(ins, MIRType_String, MUnbox::Fallible, Bailout_BaselineInfo);
+        ins = MUnbox::New(alloc(), ins, MIRType_String, MUnbox::Fallible, Bailout_BaselineInfo);
         current->add(ins);
         current->rewriteAtDepth(-1, ins);
     }
 
     return true;
 }
 
 bool
 IonBuilder::jsop_itermore()
 {
     MDefinition *iter = current->peek(-1);
-    MInstruction *ins = MIteratorMore::New(iter);
+    MInstruction *ins = MIteratorMore::New(alloc(), iter);
 
     current->add(ins);
     current->push(ins);
 
     return resumeAfter(ins);
 }
 
 bool
 IonBuilder::jsop_iterend()
 {
     MDefinition *iter = current->pop();
-    MInstruction *ins = MIteratorEnd::New(iter);
+    MInstruction *ins = MIteratorEnd::New(alloc(), iter);
 
     current->add(ins);
 
     return resumeAfter(ins);
 }
 
 MDefinition *
 IonBuilder::walkScopeChain(unsigned hops)
 {
     MDefinition *scope = current->getSlot(info().scopeChainSlot());
 
     for (unsigned i = 0; i < hops; i++) {
-        MInstruction *ins = MEnclosingScope::New(scope);
+        MInstruction *ins = MEnclosingScope::New(alloc(), scope);
         current->add(ins);
         scope = ins;
     }
 
     return scope;
 }
 
 bool
@@ -9289,22 +9291,22 @@ IonBuilder::jsop_getaliasedvar(ScopeCoor
     }
 
     MDefinition *obj = walkScopeChain(sc.hops);
 
     Shape *shape = ScopeCoordinateToStaticScopeShape(script(), pc);
 
     MInstruction *load;
     if (shape->numFixedSlots() <= sc.slot) {
-        MInstruction *slots = MSlots::New(obj);
+        MInstruction *slots = MSlots::New(alloc(), obj);
         current->add(slots);
 
-        load = MLoadSlot::New(slots, sc.slot - shape->numFixedSlots());
+        load = MLoadSlot::New(alloc(), slots, sc.slot - shape->numFixedSlots());
     } else {
-        load = MLoadFixedSlot::New(obj, sc.slot);
+        load = MLoadFixedSlot::New(alloc(), obj, sc.slot);
     }
 
     current->add(load);
     current->push(load);
 
     types::TemporaryTypeSet *types = bytecodeTypes(pc);
     return pushTypeBarrier(load, types, true);
 }
@@ -9320,17 +9322,17 @@ IonBuilder::jsop_setaliasedvar(ScopeCoor
                 return false;
         }
         MDefinition *value = current->pop();
         PropertyName *name = ScopeCoordinateName(script(), pc);
 
         if (call) {
             // Push the object on the stack to match the bound object expected in
             // the global and property set cases.
-            MInstruction *constant = MConstant::New(ObjectValue(*call));
+            MInstruction *constant = MConstant::New(alloc(), ObjectValue(*call));
             current->add(constant);
             current->push(constant);
             current->push(value);
             return setStaticName(call, name);
         }
 
         // The call object has type information we need to respect but we
         // couldn't find it. Just do a normal property assign.
@@ -9341,26 +9343,26 @@ IonBuilder::jsop_setaliasedvar(ScopeCoor
     }
 
     MDefinition *rval = current->peek(-1);
     MDefinition *obj = walkScopeChain(sc.hops);
 
     Shape *shape = ScopeCoordinateToStaticScopeShape(script(), pc);
 
     if (NeedsPostBarrier(info(), rval))
-        current->add(MPostWriteBarrier::New(obj, rval));
+        current->add(MPostWriteBarrier::New(alloc(), obj, rval));
 
     MInstruction *store;
     if (shape->numFixedSlots() <= sc.slot) {
-        MInstruction *slots = MSlots::New(obj);
+        MInstruction *slots = MSlots::New(alloc(), obj);
         current->add(slots);
 
-        store = MStoreSlot::NewBarriered(slots, sc.slot - shape->numFixedSlots(), rval);
+        store = MStoreSlot::NewBarriered(alloc(), slots, sc.slot - shape->numFixedSlots(), rval);
     } else {
-        store = MStoreFixedSlot::NewBarriered(obj, sc.slot, rval);
+        store = MStoreFixedSlot::NewBarriered(alloc(), obj, sc.slot, rval);
     }
 
     current->add(store);
     return resumeAfter(store);
 }
 
 bool
 IonBuilder::jsop_in()
@@ -9388,29 +9390,29 @@ bool
 IonBuilder::jsop_in_dense()
 {
     MDefinition *obj = current->pop();
     MDefinition *id = current->pop();
 
     bool needsHoleCheck = !ElementAccessIsPacked(constraints(), obj);
 
     // Ensure id is an integer.
-    MInstruction *idInt32 = MToInt32::New(id);
+    MInstruction *idInt32 = MToInt32::New(alloc(), id);
     current->add(idInt32);
     id = idInt32;
 
     // Get the elements vector.
-    MElements *elements = MElements::New(obj);
+    MElements *elements = MElements::New(alloc(), obj);
     current->add(elements);
 
-    MInitializedLength *initLength = MInitializedLength::New(elements);
+    MInitializedLength *initLength = MInitializedLength::New(alloc(), elements);
     current->add(initLength);
 
     // Check if id < initLength and elem[id] not a hole.
-    MInArray *ins = MInArray::New(elements, id, initLength, obj, needsHoleCheck);
+    MInArray *ins = MInArray::New(alloc(), elements, id, initLength, obj, needsHoleCheck);
 
     current->add(ins);
     current->push(ins);
 
     return true;
 }
 
 bool
@@ -9453,38 +9455,38 @@ IonBuilder::jsop_instanceof()
     current->push(ins);
 
     return resumeAfter(ins);
 }
 
 MInstruction *
 IonBuilder::addConvertElementsToDoubles(MDefinition *elements)
 {
-    MInstruction *convert = MConvertElementsToDoubles::New(elements);
+    MInstruction *convert = MConvertElementsToDoubles::New(alloc(), elements);
     current->add(convert);
     return convert;
 }
 
 MInstruction *
 IonBuilder::addBoundsCheck(MDefinition *index, MDefinition *length)
 {
-    MInstruction *check = MBoundsCheck::New(index, length);
+    MInstruction *check = MBoundsCheck::New(alloc(), index, length);
     current->add(check);
 
     // If a bounds check failed in the past, don't optimize bounds checks.
     if (failedBoundsCheck_)
         check->setNotMovable();
 
     return check;
 }
 
 MInstruction *
 IonBuilder::addShapeGuard(MDefinition *obj, Shape *const shape, BailoutKind bailoutKind)
 {
-    MGuardShape *guard = MGuardShape::New(obj, shape, bailoutKind);
+    MGuardShape *guard = MGuardShape::New(alloc(), obj, shape, bailoutKind);
     current->add(guard);
 
     // If a shape guard failed in the past, don't optimize shape guard.
     if (failedShapeGuard_)
         guard->setNotMovable();
 
     return guard;
 }
@@ -9494,18 +9496,17 @@ IonBuilder::bytecodeTypes(jsbytecode *pc
 {
     return types::TypeScript::BytecodeTypes(script(), pc, &typeArrayHint, typeArray);
 }
 
 TypeRepresentationSetHash *
 IonBuilder::getOrCreateReprSetHash()
 {
     if (!reprSetHash_) {
-        TypeRepresentationSetHash *hash =
-            temp_->lifoAlloc()->new_<TypeRepresentationSetHash>();
+        TypeRepresentationSetHash *hash = alloc_->lifoAlloc()->new_<TypeRepresentationSetHash>();
         if (!hash || !hash->init())
             return nullptr;
 
         reprSetHash_ = hash;
     }
     return reprSetHash_;
 }
 
@@ -9552,17 +9553,17 @@ IonBuilder::loadTypedObjectType(MDefinit
 {
     // Shortcircuit derived type objects, meaning the intermediate
     // objects created to represent `a.b` in an expression like
     // `a.b.c`. In that case, the type object can be simply pulled
     // from the operands of that instruction.
     if (typedObj->isNewDerivedTypedObject())
         return typedObj->toNewDerivedTypedObject()->type();
 
-    MInstruction *load = MLoadFixedSlot::New(typedObj,
+    MInstruction *load = MLoadFixedSlot::New(alloc(), typedObj,
                                              JS_DATUM_SLOT_TYPE_OBJ);
     current->add(load);
     return load;
 }
 
 // Given a typed object `typedObj` and an offset `offset` into that
 // object's data, returns another typed object and adusted offset
 // where the data can be found. Often, these returned values are the
@@ -9583,17 +9584,17 @@ IonBuilder::loadTypedObjectData(MDefinit
     // objects created to represent `a.b` in an expression like
     // `a.b.c`. In that case, the owned and a base offset can be
     // pulled from the operands of the instruction and combined with
     // `offset`.
     if (typedObj->isNewDerivedTypedObject()) {
         // If we see that the
         MNewDerivedTypedObject *ins = typedObj->toNewDerivedTypedObject();
 
-        MAdd *offsetAdd = MAdd::NewAsmJS(ins->offset(), offset, MIRType_Int32);
+        MAdd *offsetAdd = MAdd::NewAsmJS(alloc(), ins->offset(), offset, MIRType_Int32);
         current->add(offsetAdd);
 
         *owner = ins->owner();
         *ownerOffset = offsetAdd;
         return;
     }
 
     *owner = typedObj;
@@ -9611,22 +9612,22 @@ IonBuilder::loadTypedObjectElements(MDef
                                     int32_t unit,
                                     MDefinition **ownerElements,
                                     MDefinition **ownerScaledOffset)
 {
     MDefinition *owner, *ownerOffset;
     loadTypedObjectData(typedObj, offset, &owner, &ownerOffset);
 
     // Load the element data.
-    MTypedObjectElements *elements = MTypedObjectElements::New(owner);
+    MTypedObjectElements *elements = MTypedObjectElements::New(alloc(), owner);
     current->add(elements);
 
     // Scale to a different unit for compat with typed array MIRs.
     if (unit != 1) {
-        MDiv *scaledOffset = MDiv::NewAsmJS(ownerOffset, constantInt(unit), MIRType_Int32);
+        MDiv *scaledOffset = MDiv::NewAsmJS(alloc(), ownerOffset, constantInt(unit), MIRType_Int32);
         current->add(scaledOffset);
         *ownerScaledOffset = scaledOffset;
     } else {
         *ownerScaledOffset = ownerOffset;
     }
 
     *ownerElements = elements;
 }
@@ -9668,48 +9669,48 @@ IonBuilder::lookupTypedObjectField(MDefi
     JS_ASSERT(*fieldOffset >= 0);
 
     return true;
 }
 
 MDefinition *
 IonBuilder::typeObjectForElementFromArrayStructType(MDefinition *typeObj)
 {
-    MInstruction *elemType = MLoadFixedSlot::New(typeObj, JS_TYPEOBJ_SLOT_ARRAY_ELEM_TYPE);
+    MInstruction *elemType = MLoadFixedSlot::New(alloc(), typeObj, JS_TYPEOBJ_SLOT_ARRAY_ELEM_TYPE);
     current->add(elemType);
 
-    MInstruction *unboxElemType = MUnbox::New(elemType, MIRType_Object, MUnbox::Infallible);
+    MInstruction *unboxElemType = MUnbox::New(alloc(), elemType, MIRType_Object, MUnbox::Infallible);
     current->add(unboxElemType);
 
     return unboxElemType;
 }
 
 MDefinition *
 IonBuilder::typeObjectForFieldFromStructType(MDefinition *typeObj,
                                              size_t fieldIndex)
 {
     // Load list of field type objects.
 
-    MInstruction *fieldTypes = MLoadFixedSlot::New(typeObj, JS_TYPEOBJ_SLOT_STRUCT_FIELD_TYPES);
+    MInstruction *fieldTypes = MLoadFixedSlot::New(alloc(), typeObj, JS_TYPEOBJ_SLOT_STRUCT_FIELD_TYPES);
     current->add(fieldTypes);
 
-    MInstruction *unboxFieldTypes = MUnbox::New(fieldTypes, MIRType_Object, MUnbox::Infallible);
+    MInstruction *unboxFieldTypes = MUnbox::New(alloc(), fieldTypes, MIRType_Object, MUnbox::Infallible);
     current->add(unboxFieldTypes);
 
     // Index into list with index of field.
 
-    MInstruction *fieldTypesElements = MElements::New(unboxFieldTypes);
+    MInstruction *fieldTypesElements = MElements::New(alloc(), unboxFieldTypes);
     current->add(fieldTypesElements);
 
     MConstant *fieldIndexDef = constantInt(fieldIndex);
 
-    MInstruction *fieldType = MLoadElement::New(fieldTypesElements, fieldIndexDef, false, false);
+    MInstruction *fieldType = MLoadElement::New(alloc(), fieldTypesElements, fieldIndexDef, false, false);
     current->add(fieldType);
 
-    MInstruction *unboxFieldType = MUnbox::New(fieldType, MIRType_Object, MUnbox::Infallible);
+    MInstruction *unboxFieldType = MUnbox::New(alloc(), fieldType, MIRType_Object, MUnbox::Infallible);
     current->add(unboxFieldType);
 
     return unboxFieldType;
 }
 
 bool
 IonBuilder::storeScalarTypedObjectValue(MDefinition *typedObj,
                                         MDefinition *offset,
@@ -9718,32 +9719,32 @@ IonBuilder::storeScalarTypedObjectValue(
 {
     // Find location within the owner object.
     MDefinition *elements, *scaledOffset;
     loadTypedObjectElements(typedObj, offset, typeRepr->alignment(), &elements, &scaledOffset);
 
     // Clamp value to [0, 255] when type is Uint8Clamped
     MDefinition *toWrite = value;
     if (typeRepr->type() == ScalarTypeRepresentation::TYPE_UINT8_CLAMPED) {
-        toWrite = MClampToUint8::New(value);
+        toWrite = MClampToUint8::New(alloc(), value);
         current->add(toWrite->toInstruction());
     }
 
     MStoreTypedArrayElement *store =
-        MStoreTypedArrayElement::New(elements, scaledOffset, toWrite,
+        MStoreTypedArrayElement::New(alloc(), elements, scaledOffset, toWrite,
                                      typeRepr->type());
     current->add(store);
 
     return true;
 }
 
 MConstant *
 IonBuilder::constant(const Value &v)
 {
-    MConstant *c = MConstant::New(v);
+    MConstant *c = MConstant::New(alloc(), v);
     current->add(c);
     return c;
 }
 
 MConstant *
 IonBuilder::constantInt(int32_t i)
 {
     return constant(Int32Value(i));
--- a/js/src/jit/IonBuilder.h
+++ b/js/src/jit/IonBuilder.h
@@ -333,17 +333,17 @@ class IonBuilder : public MIRGenerator
     // Add a guard which ensure that the set of type which goes through this
     // generated code correspond to the observed types for the bytecode.
     bool pushTypeBarrier(MDefinition *def, types::TemporaryTypeSet *observed, bool needBarrier);
 
     // If definiteType is not known or def already has the right type, just
     // returns def.  Otherwise, returns an MInstruction that has that definite
     // type, infallibly unboxing ins as needed.  The new instruction will be
     // added to |current| in this case.
-    MDefinition *EnsureDefiniteType(MDefinition* def, JSValueType definiteType);
+    MDefinition *ensureDefiniteType(MDefinition* def, JSValueType definiteType);
 
     JSObject *getSingletonPrototype(JSFunction *target);
 
     MDefinition *createThisScripted(MDefinition *callee);
     MDefinition *createThisScriptedSingleton(JSFunction *target, MDefinition *callee);
     MDefinition *createThis(JSFunction *target, MDefinition *callee);
     MInstruction *createDeclEnvObject(MDefinition *callee, MDefinition *scopeObj);
     MInstruction *createCallObject(MDefinition *callee, MDefinition *scopeObj);
@@ -915,20 +915,20 @@ class CallInfo
 
     bool isSetter() const {
         return setter_;
     }
     void markAsSetter() {
         setter_ = true;
     }
 
-    void wrapArgs(MBasicBlock *current) {
-        thisArg_ = wrap(current, thisArg_);
+    void wrapArgs(TempAllocator &alloc, MBasicBlock *current) {
+        thisArg_ = wrap(alloc, current, thisArg_);
         for (uint32_t i = 0; i < argc(); i++)
-            args_[i] = wrap(current, args_[i]);
+            args_[i] = wrap(alloc, current, args_[i]);
     }
 
     void unwrapArgs() {
         thisArg_ = unwrap(thisArg_);
         for (uint32_t i = 0; i < argc(); i++)
             args_[i] = unwrap(args_[i]);
     }
 
@@ -959,19 +959,19 @@ class CallInfo
         MPassArg *passArg = arg->toPassArg();
         MBasicBlock *block = passArg->block();
         MDefinition *wrapped = passArg->getArgument();
         wrapped->setFoldedUnchecked();
         passArg->replaceAllUsesWith(wrapped);
         block->discard(passArg);
         return wrapped;
     }
-    static MDefinition *wrap(MBasicBlock *current, MDefinition *arg) {
+    static MDefinition *wrap(TempAllocator &alloc, MBasicBlock *current, MDefinition *arg) {
         JS_ASSERT(!arg->isPassArg());
-        MPassArg *passArg = MPassArg::New(arg);
+        MPassArg *passArg = MPassArg::New(alloc, arg);
         current->add(passArg);
         return passArg;
     }
 };
 
 bool TypeSetIncludes(types::TypeSet *types, MIRType input, types::TypeSet *inputTypes);
 
 bool NeedsPostBarrier(CompileInfo &info, MDefinition *value);
--- a/js/src/jit/Lowering.cpp
+++ b/js/src/jit/Lowering.cpp
@@ -2269,17 +2269,17 @@ LIRGenerator::visitNot(MNot *ins)
 
     // - boolean: x xor 1
     // - int32: LCompare(x, 0)
     // - double: LCompare(x, 0)
     // - null or undefined: true
     // - object: false if it never emulates undefined, else LNotO(x)
     switch (op->type()) {
       case MIRType_Boolean: {
-        MConstant *cons = MConstant::New(Int32Value(1));
+        MConstant *cons = MConstant::New(alloc(), Int32Value(1));
         ins->block()->insertBefore(ins, cons);
         return lowerForALU(new LBitOpI(JSOP_BITXOR), ins, op, cons);
       }
       case MIRType_Int32: {
         return define(new LNotI(useRegisterAtStart(op)), ins);
       }
       case MIRType_Double:
         return define(new LNotD(useRegister(op)), ins);
--- a/js/src/jit/MCallOptimize.cpp
+++ b/js/src/jit/MCallOptimize.cpp
@@ -189,17 +189,17 @@ IonBuilder::inlineMathFunction(CallInfo 
         return InliningStatus_NotInlined;
 
     MathCache *cache = compartment->runtimeFromAnyThread()->maybeGetMathCache();
     if (!cache)
         return InliningStatus_NotInlined;
 
     callInfo.unwrapArgs();
 
-    MMathFunction *ins = MMathFunction::New(callInfo.getArg(0), function, cache);
+    MMathFunction *ins = MMathFunction::New(alloc(), callInfo.getArg(0), function, cache);
     current->add(ins);
     current->push(ins);
     return InliningStatus_Inlined;
 }
 
 IonBuilder::InliningStatus
 IonBuilder::inlineArray(CallInfo &callInfo)
 {
@@ -246,49 +246,49 @@ IonBuilder::inlineArray(CallInfo &callIn
 
     callInfo.unwrapArgs();
 
     types::TemporaryTypeSet::DoubleConversion conversion =
         getInlineReturnTypeSet()->convertDoubleElements(constraints());
     if (conversion == types::TemporaryTypeSet::AlwaysConvertToDoubles)
         templateObject->setShouldConvertDoubleElements();
 
-    MNewArray *ins = new MNewArray(initLength, templateObject, allocating);
+    MNewArray *ins = MNewArray::New(alloc(), initLength, templateObject, allocating);
     current->add(ins);
     current->push(ins);
 
     if (callInfo.argc() >= 2) {
         // Get the elements vector.
-        MElements *elements = MElements::New(ins);
+        MElements *elements = MElements::New(alloc(), ins);
         current->add(elements);
 
         // Store all values, no need to initialize the length after each as
         // jsop_initelem_array is doing because we do not expect to bailout
         // because the memory is supposed to be allocated by now. There is no
         // need for a post barrier on these writes, as as the MNewAray will use
         // the nursery if possible, triggering a minor collection if it can't.
         MConstant *id = nullptr;
         for (uint32_t i = 0; i < initLength; i++) {
-            id = MConstant::New(Int32Value(i));
+            id = MConstant::New(alloc(), Int32Value(i));
             current->add(id);
 
             MDefinition *value = callInfo.getArg(i);
             if (conversion == types::TemporaryTypeSet::AlwaysConvertToDoubles) {
-                MInstruction *valueDouble = MToDouble::New(value);
+                MInstruction *valueDouble = MToDouble::New(alloc(), value);
                 current->add(valueDouble);
                 value = valueDouble;
             }
 
-            MStoreElement *store = MStoreElement::New(elements, id, value,
+            MStoreElement *store = MStoreElement::New(alloc(), elements, id, value,
                                                       /* needsHoleCheck = */ false);
             current->add(store);
         }
 
         // Update the length.
-        MSetInitializedLength *length = MSetInitializedLength::New(elements, id);
+        MSetInitializedLength *length = MSetInitializedLength::New(alloc(), elements, id);
         current->add(length);
 
         if (!resumeAfter(length))
             return InliningStatus_Error;
     }
 
     return InliningStatus_Inlined;
 }
@@ -328,17 +328,17 @@ IonBuilder::inlineArrayPopShift(CallInfo
     bool needsHoleCheck = thisTypes->hasObjectFlags(constraints(), types::OBJECT_FLAG_NON_PACKED);
     bool maybeUndefined = returnTypes->hasType(types::Type::UndefinedType());
 
     bool barrier = PropertyReadNeedsTypeBarrier(analysisContext, constraints(),
                                                 callInfo.thisArg(), nullptr, returnTypes);
     if (barrier)
         returnType = MIRType_Value;
 
-    MArrayPopShift *ins = MArrayPopShift::New(callInfo.thisArg(), mode,
+    MArrayPopShift *ins = MArrayPopShift::New(alloc(), callInfo.thisArg(), mode,
                                               needsHoleCheck, maybeUndefined);
     current->add(ins);
     current->push(ins);
     ins->setResultType(returnType);
 
     if (!resumeAfter(ins))
         return InliningStatus_Error;
 
@@ -351,17 +351,17 @@ IonBuilder::inlineArrayPopShift(CallInfo
 IonBuilder::InliningStatus
 IonBuilder::inlineArrayPush(CallInfo &callInfo)
 {
     if (callInfo.argc() != 1 || callInfo.constructing())
         return InliningStatus_NotInlined;
 
     MDefinition *obj = callInfo.thisArg();
     MDefinition *value = callInfo.getArg(0);
-    if (PropertyWriteNeedsTypeBarrier(constraints(), current,
+    if (PropertyWriteNeedsTypeBarrier(alloc(), constraints(), current,
                                       &obj, nullptr, &value, /* canModify = */ false))
     {
         return InliningStatus_NotInlined;
     }
     JS_ASSERT(obj == callInfo.thisArg() && value == callInfo.getArg(0));
 
     if (getInlineReturnType() != MIRType_Int32)
         return InliningStatus_NotInlined;
@@ -386,25 +386,25 @@ IonBuilder::inlineArrayPush(CallInfo &ca
         return InliningStatus_NotInlined;
 
     callInfo.unwrapArgs();
     value = callInfo.getArg(0);
 
     if (conversion == types::TemporaryTypeSet::AlwaysConvertToDoubles ||
         conversion == types::TemporaryTypeSet::MaybeConvertToDoubles)
     {
-        MInstruction *valueDouble = MToDouble::New(value);
+        MInstruction *valueDouble = MToDouble::New(alloc(), value);
         current->add(valueDouble);
         value = valueDouble;
     }
 
     if (NeedsPostBarrier(info(), value))
-        current->add(MPostWriteBarrier::New(callInfo.thisArg(), value));
+        current->add(MPostWriteBarrier::New(alloc(), callInfo.thisArg(), value));
 
-    MArrayPush *ins = MArrayPush::New(callInfo.thisArg(), value);
+    MArrayPush *ins = MArrayPush::New(alloc(), callInfo.thisArg(), value);
     current->add(ins);
     current->push(ins);
 
     if (!resumeAfter(ins))
         return InliningStatus_Error;
     return InliningStatus_Inlined;
 }
 
@@ -496,17 +496,17 @@ IonBuilder::inlineArrayConcat(CallInfo &
     // Inline the call.
     JSObject *templateObj = inspector->getTemplateObjectForNative(pc, js::array_concat);
     if (!templateObj || templateObj->type() != baseThisType)
         return InliningStatus_NotInlined;
     JS_ASSERT(templateObj->is<ArrayObject>());
 
     callInfo.unwrapArgs();
 
-    MArrayConcat *ins = MArrayConcat::New(callInfo.thisArg(), callInfo.getArg(0), templateObj);
+    MArrayConcat *ins = MArrayConcat::New(alloc(), callInfo.thisArg(), callInfo.getArg(0), templateObj);
     current->add(ins);
     current->push(ins);
 
     if (!resumeAfter(ins))
         return InliningStatus_Error;
     return InliningStatus_Inlined;
 }
 
@@ -533,21 +533,21 @@ IonBuilder::inlineMathAbs(CallInfo &call
         return InliningStatus_NotInlined;
     }
 
     callInfo.unwrapArgs();
 
     // If the arg is a Float32, we specialize the op as double, it will be specialized
     // as float32 if necessary later.
     MIRType absType = (argType == MIRType_Float32) ? MIRType_Double : argType;
-    MInstruction *ins = MAbs::New(callInfo.getArg(0), absType);
+    MInstruction *ins = MAbs::New(alloc(), callInfo.getArg(0), absType);
     current->add(ins);
 
     if (IsFloatingPointType(argType) && returnType == MIRType_Int32) {
-        MToInt32 *toInt = MToInt32::New(ins);
+        MToInt32 *toInt = MToInt32::New(alloc(), ins);
         toInt->setCanBeNegativeZero(false);
         current->add(toInt);
         ins = toInt;
     }
 
     current->push(ins);
     return InliningStatus_Inlined;
 }
@@ -576,17 +576,17 @@ IonBuilder::inlineMathFloor(CallInfo &ca
         MFloor *ins = new MFloor(callInfo.getArg(0));
         current->add(ins);
         current->push(ins);
         return InliningStatus_Inlined;
     }
 
     if (IsFloatingPointType(argType) && returnType == MIRType_Double) {
         callInfo.unwrapArgs();
-        MMathFunction *ins = MMathFunction::New(callInfo.getArg(0), MMathFunction::Floor, nullptr);
+        MMathFunction *ins = MMathFunction::New(alloc(), callInfo.getArg(0), MMathFunction::Floor, nullptr);
         current->add(ins);
         current->push(ins);
         return InliningStatus_Inlined;
     }
 
     return InliningStatus_NotInlined;
 }
 
@@ -614,17 +614,17 @@ IonBuilder::inlineMathRound(CallInfo &ca
         MRound *ins = new MRound(callInfo.getArg(0));
         current->add(ins);
         current->push(ins);
         return InliningStatus_Inlined;
     }
 
     if (argType == MIRType_Double && returnType == MIRType_Double) {
         callInfo.unwrapArgs();
-        MMathFunction *ins = MMathFunction::New(callInfo.getArg(0), MMathFunction::Round, nullptr);
+        MMathFunction *ins = MMathFunction::New(alloc(), callInfo.getArg(0), MMathFunction::Round, nullptr);
         current->add(ins);
         current->push(ins);
         return InliningStatus_Inlined;
     }
 
     return InliningStatus_NotInlined;
 }
 
@@ -640,17 +640,17 @@ IonBuilder::inlineMathSqrt(CallInfo &cal
     MIRType argType = callInfo.getArg(0)->type();
     if (getInlineReturnType() != MIRType_Double)
         return InliningStatus_NotInlined;
     if (!IsNumberType(argType))
         return InliningStatus_NotInlined;
 
     callInfo.unwrapArgs();
 
-    MSqrt *sqrt = MSqrt::New(callInfo.getArg(0));
+    MSqrt *sqrt = MSqrt::New(alloc(), callInfo.getArg(0));
     current->add(sqrt);
     current->push(sqrt);
     return InliningStatus_Inlined;
 }
 
 IonBuilder::InliningStatus
 IonBuilder::inlineMathAtan2(CallInfo &callInfo)
 {
@@ -666,17 +666,17 @@ IonBuilder::inlineMathAtan2(CallInfo &ca
     MIRType argType0 = callInfo.getArg(0)->type();
     MIRType argType1 = callInfo.getArg(1)->type();
 
     if (!IsNumberType(argType0) || !IsNumberType(argType1))
         return InliningStatus_NotInlined;
 
     callInfo.unwrapArgs();
 
-    MAtan2 *atan2 = MAtan2::New(callInfo.getArg(0), callInfo.getArg(1));
+    MAtan2 *atan2 = MAtan2::New(alloc(), callInfo.getArg(0), callInfo.getArg(1));
     current->add(atan2);
     current->push(atan2);
     return InliningStatus_Inlined;
 }
 
 IonBuilder::InliningStatus
 IonBuilder::inlineMathHypot(CallInfo &callInfo)
 {
@@ -692,17 +692,17 @@ IonBuilder::inlineMathHypot(CallInfo &ca
     MIRType argType0 = callInfo.getArg(0)->type();
     MIRType argType1 = callInfo.getArg(1)->type();
 
     if (!IsNumberType(argType0) || !IsNumberType(argType1))
         return InliningStatus_NotInlined;
 
     callInfo.unwrapArgs();
 
-    MHypot *hypot = MHypot::New(callInfo.getArg(0), callInfo.getArg(1));
+    MHypot *hypot = MHypot::New(alloc(), callInfo.getArg(0), callInfo.getArg(1));
     current->add(hypot);
     current->push(hypot);
     return InliningStatus_Inlined;
 }
 
 IonBuilder::InliningStatus
 IonBuilder::inlineMathPow(CallInfo &callInfo)
 {
@@ -733,77 +733,77 @@ IonBuilder::inlineMathPow(CallInfo &call
     // Optimize some constant powers.
     if (callInfo.getArg(1)->isConstant() &&
         callInfo.getArg(1)->toConstant()->value().isNumber())
     {
         double pow = callInfo.getArg(1)->toConstant()->value().toNumber();
 
         // Math.pow(x, 0.5) is a sqrt with edge-case detection.
         if (pow == 0.5) {
-            MPowHalf *half = MPowHalf::New(base);
+            MPowHalf *half = MPowHalf::New(alloc(), base);
             current->add(half);
             output = half;
         }
 
         // Math.pow(x, -0.5) == 1 / Math.pow(x, 0.5), even for edge cases.
         if (pow == -0.5) {
-            MPowHalf *half = MPowHalf::New(base);
+            MPowHalf *half = MPowHalf::New(alloc(), base);
             current->add(half);
-            MConstant *one = MConstant::New(DoubleValue(1.0));
+            MConstant *one = MConstant::New(alloc(), DoubleValue(1.0));
             current->add(one);
-            MDiv *div = MDiv::New(one, half, MIRType_Double);
+            MDiv *div = MDiv::New(alloc(), one, half, MIRType_Double);
             current->add(div);
             output = div;
         }
 
         // Math.pow(x, 1) == x.
         if (pow == 1.0)
             output = base;
 
         // Math.pow(x, 2) == x*x.
         if (pow == 2.0) {
-            MMul *mul = MMul::New(base, base, outputType);
+            MMul *mul = MMul::New(alloc(), base, base, outputType);
             current->add(mul);
             output = mul;
         }
 
         // Math.pow(x, 3) == x*x*x.
         if (pow == 3.0) {
-            MMul *mul1 = MMul::New(base, base, outputType);
+            MMul *mul1 = MMul::New(alloc(), base, base, outputType);
             current->add(mul1);
-            MMul *mul2 = MMul::New(base, mul1, outputType);
+            MMul *mul2 = MMul::New(alloc(), base, mul1, outputType);
             current->add(mul2);
             output = mul2;
         }
 
         // Math.pow(x, 4) == y*y, where y = x*x.
         if (pow == 4.0) {
-            MMul *y = MMul::New(base, base, outputType);
+            MMul *y = MMul::New(alloc(), base, base, outputType);
             current->add(y);
-            MMul *mul = MMul::New(y, y, outputType);
+            MMul *mul = MMul::New(alloc(), y, y, outputType);
             current->add(mul);
             output = mul;
         }
     }
 
     // Use MPow for other powers
     if (!output) {
-        MPow *pow = MPow::New(base, power, powerType);
+        MPow *pow = MPow::New(alloc(), base, power, powerType);
         current->add(pow);
         output = pow;
     }
 
     // Cast to the right type
     if (outputType == MIRType_Int32 && output->type() != MIRType_Int32) {
-        MToInt32 *toInt = MToInt32::New(output);
+        MToInt32 *toInt = MToInt32::New(alloc(), output);
         current->add(toInt);
         output = toInt;
     }
     if (outputType == MIRType_Double && output->type() != MIRType_Double) {
-        MToDouble *toDouble = MToDouble::New(output);
+        MToDouble *toDouble = MToDouble::New(alloc(), output);
         current->add(toDouble);
         output = toDouble;
     }
 
     current->push(output);
     return InliningStatus_Inlined;
 }
 
@@ -813,17 +813,17 @@ IonBuilder::inlineMathRandom(CallInfo &c
     if (callInfo.constructing())
         return InliningStatus_NotInlined;
 
     if (getInlineReturnType() != MIRType_Double)
         return InliningStatus_NotInlined;
 
     callInfo.unwrapArgs();
 
-    MRandom *rand = MRandom::New();
+    MRandom *rand = MRandom::New(alloc());
     current->add(rand);
     current->push(rand);
     return InliningStatus_Inlined;
 }
 
 IonBuilder::InliningStatus
 IonBuilder::inlineMathImul(CallInfo &callInfo)
 {
@@ -836,23 +836,23 @@ IonBuilder::inlineMathImul(CallInfo &cal
 
     if (!IsNumberType(callInfo.getArg(0)->type()))
         return InliningStatus_NotInlined;
     if (!IsNumberType(callInfo.getArg(1)->type()))
         return InliningStatus_NotInlined;
 
     callInfo.unwrapArgs();
 
-    MInstruction *first = MTruncateToInt32::New(callInfo.getArg(0));
+    MInstruction *first = MTruncateToInt32::New(alloc(), callInfo.getArg(0));
     current->add(first);
 
-    MInstruction *second = MTruncateToInt32::New(callInfo.getArg(1));
+    MInstruction *second = MTruncateToInt32::New(alloc(), callInfo.getArg(1));
     current->add(second);
 
-    MMul *ins = MMul::New(first, second, MIRType_Int32, MMul::Integer);
+    MMul *ins = MMul::New(alloc(), first, second, MIRType_Int32, MMul::Integer);
     current->add(ins);
     current->push(ins);
     return InliningStatus_Inlined;
 }
 
 IonBuilder::InliningStatus
 IonBuilder::inlineMathFRound(CallInfo &callInfo)
 {
@@ -869,17 +869,17 @@ IonBuilder::inlineMathFRound(CallInfo &c
         return InliningStatus_NotInlined;
 
     MIRType arg = callInfo.getArg(0)->type();
     if (!IsNumberType(arg))
         return InliningStatus_NotInlined;
 
     callInfo.unwrapArgs();
 
-    MToFloat32 *ins = MToFloat32::New(callInfo.getArg(0));
+    MToFloat32 *ins = MToFloat32::New(alloc(), callInfo.getArg(0));
     current->add(ins);
     current->push(ins);
     return InliningStatus_Inlined;
 }
 
 IonBuilder::InliningStatus
 IonBuilder::inlineMathMinMax(CallInfo &callInfo, bool max)
 {
@@ -898,21 +898,21 @@ IonBuilder::inlineMathMinMax(CallInfo &c
         // We would need to inform TI if we happen to return a double.
         if (returnType == MIRType_Int32 && IsFloatingPointType(argType))
             return InliningStatus_NotInlined;
     }
 
     callInfo.unwrapArgs();
 
     // Chain N-1 MMinMax instructions to compute the MinMax.
-    MMinMax *last = MMinMax::New(callInfo.getArg(0), callInfo.getArg(1), returnType, max);
+    MMinMax *last = MMinMax::New(alloc(), callInfo.getArg(0), callInfo.getArg(1), returnType, max);
     current->add(last);
 
     for (unsigned i = 2; i < callInfo.argc(); i++) {
-        MMinMax *ins = MMinMax::New(last, callInfo.getArg(i), returnType, max);
+        MMinMax *ins = MMinMax::New(alloc(), last, callInfo.getArg(i), returnType, max);
         current->add(ins);
         last = ins;
     }
 
     current->push(last);
     return InliningStatus_Inlined;
 }
 
@@ -929,17 +929,17 @@ IonBuilder::inlineStringObject(CallInfo 
 
     JSObject *templateObj = inspector->getTemplateObjectForNative(pc, js_String);
     if (!templateObj)
         return InliningStatus_NotInlined;
     JS_ASSERT(templateObj->is<StringObject>());
 
     callInfo.unwrapArgs();
 
-    MNewStringObject *ins = MNewStringObject::New(callInfo.getArg(0), templateObj);
+    MNewStringObject *ins = MNewStringObject::New(alloc(), callInfo.getArg(0), templateObj);
     current->add(ins);
     current->push(ins);
 
     if (!resumeAfter(ins))
         return InliningStatus_Error;
 
     return InliningStatus_Inlined;
 }
@@ -969,17 +969,17 @@ IonBuilder::inlineStringSplit(CallInfo &
 
     if (!key.maybeTypes()->hasType(types::Type::StringType())) {
         key.freeze(constraints());
         return InliningStatus_NotInlined;
     }
 
     callInfo.unwrapArgs();
 
-    MStringSplit *ins = MStringSplit::New(callInfo.thisArg(), callInfo.getArg(0), templateObject);
+    MStringSplit *ins = MStringSplit::New(alloc(), callInfo.thisArg(), callInfo.getArg(0), templateObject);
     current->add(ins);
     current->push(ins);
 
     return InliningStatus_Inlined;
 }
 
 IonBuilder::InliningStatus
 IonBuilder::inlineStrCharCodeAt(CallInfo &callInfo)
@@ -992,25 +992,25 @@ IonBuilder::inlineStrCharCodeAt(CallInfo
     if (callInfo.thisArg()->type() != MIRType_String && callInfo.thisArg()->type() != MIRType_Value)
         return InliningStatus_NotInlined;
     MIRType argType = callInfo.getArg(0)->type();
     if (argType != MIRType_Int32 && argType != MIRType_Double)
         return InliningStatus_NotInlined;
 
     callInfo.unwrapArgs();
 
-    MInstruction *index = MToInt32::New(callInfo.getArg(0));
+    MInstruction *index = MToInt32::New(alloc(), callInfo.getArg(0));
     current->add(index);
 
-    MStringLength *length = MStringLength::New(callInfo.thisArg());
+    MStringLength *length = MStringLength::New(alloc(), callInfo.thisArg());
     current->add(length);
 
     index = addBoundsCheck(index, length);
 
-    MCharCodeAt *charCode = MCharCodeAt::New(callInfo.thisArg(), index);
+    MCharCodeAt *charCode = MCharCodeAt::New(alloc(), callInfo.thisArg(), index);
     current->add(charCode);
     current->push(charCode);
     return InliningStatus_Inlined;
 }
 
 IonBuilder::InliningStatus
 IonBuilder::inlineStrFromCharCode(CallInfo &callInfo)
 {
@@ -1019,20 +1019,20 @@ IonBuilder::inlineStrFromCharCode(CallIn
 
     if (getInlineReturnType() != MIRType_String)
         return InliningStatus_NotInlined;
     if (callInfo.getArg(0)->type() != MIRType_Int32)
         return InliningStatus_NotInlined;
 
     callInfo.unwrapArgs();
 
-    MToInt32 *charCode = MToInt32::New(callInfo.getArg(0));
+    MToInt32 *charCode = MToInt32::New(alloc(), callInfo.getArg(0));
     current->add(charCode);
 
-    MFromCharCode *string = MFromCharCode::New(charCode);
+    MFromCharCode *string = MFromCharCode::New(alloc(), charCode);
     current->add(string);
     current->push(string);
     return InliningStatus_Inlined;
 }
 
 IonBuilder::InliningStatus
 IonBuilder::inlineStrCharAt(CallInfo &callInfo)
 {
@@ -1044,29 +1044,29 @@ IonBuilder::inlineStrCharAt(CallInfo &ca
     if (callInfo.thisArg()->type() != MIRType_String)
         return InliningStatus_NotInlined;
     MIRType argType = callInfo.getArg(0)->type();
     if (argType != MIRType_Int32 && argType != MIRType_Double)
         return InliningStatus_NotInlined;
 
     callInfo.unwrapArgs();
 
-    MInstruction *index = MToInt32::New(callInfo.getArg(0));
+    MInstruction *index = MToInt32::New(alloc(), callInfo.getArg(0));
     current->add(index);
 
-    MStringLength *length = MStringLength::New(callInfo.thisArg());
+    MStringLength *length = MStringLength::New(alloc(), callInfo.thisArg());
     current->add(length);
 
     index = addBoundsCheck(index, length);
 
     // String.charAt(x) = String.fromCharCode(String.charCodeAt(x))
-    MCharCodeAt *charCode = MCharCodeAt::New(callInfo.thisArg(), index);
+    MCharCodeAt *charCode = MCharCodeAt::New(alloc(), callInfo.thisArg(), index);
     current->add(charCode);
 
-    MFromCharCode *string = MFromCharCode::New(charCode);
+    MFromCharCode *string = MFromCharCode::New(alloc(), charCode);
     current->add(string);
     current->push(string);
     return InliningStatus_Inlined;
 }
 
 IonBuilder::InliningStatus
 IonBuilder::inlineRegExpTest(CallInfo &callInfo)
 {
@@ -1083,17 +1083,17 @@ IonBuilder::inlineRegExpTest(CallInfo &c
     const Class *clasp = thisTypes ? thisTypes->getKnownClass() : nullptr;
     if (clasp != &RegExpObject::class_)
         return InliningStatus_NotInlined;
     if (callInfo.getArg(0)->type() != MIRType_String)
         return InliningStatus_NotInlined;
 
     callInfo.unwrapArgs();
 
-    MInstruction *match = MRegExpTest::New(callInfo.thisArg(), callInfo.getArg(0));
+    MInstruction *match = MRegExpTest::New(alloc(), callInfo.thisArg(), callInfo.getArg(0));
     current->add(match);
     current->push(match);
     if (!resumeAfter(match))
         return InliningStatus_Error;
 
     return InliningStatus_Inlined;
 }
 
@@ -1120,17 +1120,17 @@ IonBuilder::inlineUnsafePutElements(Call
         MDefinition *obj = callInfo.getArg(arri);
         MDefinition *id = callInfo.getArg(idxi);
         MDefinition *elem = callInfo.getArg(elemi);
 
         bool isDenseNative = ElementAccessIsDenseNative(obj, id);
 
         bool writeNeedsBarrier = false;
         if (isDenseNative) {
-            writeNeedsBarrier = PropertyWriteNeedsTypeBarrier(constraints(), current,
+            writeNeedsBarrier = PropertyWriteNeedsTypeBarrier(alloc(), constraints(), current,
                                                               &obj, nullptr, &elem,
                                                               /* canModify = */ false);
         }
 
         // We can only inline setelem on dense arrays that do not need type
         // barriers and on typed arrays.
         ScalarTypeRepresentation::Type arrayType;
         if ((!isDenseNative || writeNeedsBarrier) &&
@@ -1139,17 +1139,17 @@ IonBuilder::inlineUnsafePutElements(Call
             return InliningStatus_NotInlined;
         }
     }
 
     callInfo.unwrapArgs();
 
     // Push the result first so that the stack depth matches up for
     // the potential bailouts that will occur in the stores below.
-    MConstant *udef = MConstant::New(UndefinedValue());
+    MConstant *udef = MConstant::New(alloc(), UndefinedValue());
     current->add(udef);
     current->push(udef);
 
     for (uint32_t base = 0; base < argc; base += 3) {
         uint32_t arri = base + 0;
         uint32_t idxi = base + 1;
 
         MDefinition *obj = callInfo.getArg(arri);
@@ -1229,17 +1229,17 @@ IonBuilder::inlineForceSequentialOrInPar
         // access the "in warmup" flag of the runtime.
         return InliningStatus_NotInlined;
 
       case ParallelExecution: {
         // During Parallel Exec, we always force sequential, so
         // replace with true.  This permits UCE to eliminate the
         // entire path as dead, which is important.
         callInfo.unwrapArgs();
-        MConstant *ins = MConstant::New(BooleanValue(true));
+        MConstant *ins = MConstant::New(alloc(), BooleanValue(true));
         current->add(ins);
         current->push(ins);
         return InliningStatus_Inlined;
       }
     }
 
     MOZ_ASSUME_UNREACHABLE("Invalid execution mode");
 }
@@ -1289,17 +1289,17 @@ IonBuilder::inlineParallelArray(CallInfo
     JSFunction *target = ParallelArrayObject::maybeGetConstructor(&script()->global(), argc);
     if (!target)
         return InliningStatus_NotInlined;
 
     JS_ASSERT(target->nonLazyScript()->shouldCloneAtCallsite);
     if (JSFunction *clone = ExistingCloneFunctionAtCallsite(compartment, target, script(), pc))
         target = clone;
 
-    MConstant *ctor = MConstant::New(ObjectValue(*target));
+    MConstant *ctor = MConstant::New(alloc(), ObjectValue(*target));
     current->add(ctor);
 
     return inlineParallelArrayTail(callInfo, target, ctor, nullptr, 0,
                                    ParallelArrayObject::construct);
 }
 
 IonBuilder::InliningStatus
 IonBuilder::inlineParallelArrayTail(CallInfo &callInfo,
@@ -1331,56 +1331,56 @@ IonBuilder::inlineParallelArrayTail(Call
     if (!templateObject || templateObject->type() != typeObject)
         return InliningStatus_NotInlined;
 
     // Create the call and add in the non-this arguments.
     uint32_t targetArgs = argc;
     if (target && !target->isNative())
         targetArgs = Max<uint32_t>(target->nargs, argc);
 
-    MCall *call = MCall::New(target, targetArgs + 1, argc, false);
+    MCall *call = MCall::New(alloc(), target, targetArgs + 1, argc, false);
     if (!call)
         return InliningStatus_Error;
 
     callInfo.unwrapArgs();
 
     // Explicitly pad any missing arguments with |undefined|.
     // This permits skipping the argumentsRectifier.
     for (uint32_t i = targetArgs; i > argc; i--) {
         JS_ASSERT_IF(target, !target->isNative());
-        MConstant *undef = MConstant::New(UndefinedValue());
+        MConstant *undef = MConstant::New(alloc(), UndefinedValue());
         current->add(undef);
-        MPassArg *pass = MPassArg::New(undef);
+        MPassArg *pass = MPassArg::New(alloc(), undef);
         current->add(pass);
         call->addArg(i, pass);
     }
 
-    MPassArg *oldThis = MPassArg::New(callInfo.thisArg());
+    MPassArg *oldThis = MPassArg::New(alloc(), callInfo.thisArg());
     current->add(oldThis);
 
     // Add explicit arguments.
     // Skip addArg(0) because it is reserved for this
     for (uint32_t i = 0; i < argc; i++) {
         MDefinition *arg = callInfo.getArg(i + discards);
-        MPassArg *passArg = MPassArg::New(arg);
+        MPassArg *passArg = MPassArg::New(alloc(), arg);
         current->add(passArg);
         call->addArg(i + 1, passArg);
     }
 
     // Place an MPrepareCall before the first passed argument, before we
     // potentially perform rearrangement.
     MPrepareCall *start = new MPrepareCall;
     oldThis->block()->insertBefore(oldThis, start);
     call->initPrepareCall(start);
 
     // Create the MIR to allocate the new parallel array.  Take the type
     // object is taken from the prediction set.
-    MNewParallelArray *newObject = MNewParallelArray::New(templateObject);
+    MNewParallelArray *newObject = MNewParallelArray::New(alloc(), templateObject);
     current->add(newObject);
-    MPassArg *newThis = MPassArg::New(newObject);
+    MPassArg *newThis = MPassArg::New(alloc(), newObject);
     current->add(newThis);
     call->addArg(0, newThis);
 
     // Set the new callee.
     call->initFunction(ctor);
 
     current->add(call);
     current->push(newObject);
@@ -1463,22 +1463,22 @@ IonBuilder::inlineUnsafeSetReservedSlot(
     // Don't inline if we don't have a constant slot.
     MDefinition *arg = callInfo.getArg(1)->toPassArg()->getArgument();
     if (!arg->isConstant())
         return InliningStatus_NotInlined;
     uint32_t slot = arg->toConstant()->value().toPrivateUint32();
 
     callInfo.unwrapArgs();
 
-    MStoreFixedSlot *store = MStoreFixedSlot::New(callInfo.getArg(0), slot, callInfo.getArg(2));
+    MStoreFixedSlot *store = MStoreFixedSlot::New(alloc(), callInfo.getArg(0), slot, callInfo.getArg(2));
     current->add(store);
     current->push(store);
 
     if (NeedsPostBarrier(info(), callInfo.getArg(2)))
-        current->add(MPostWriteBarrier::New(callInfo.thisArg(), callInfo.getArg(2)));
+        current->add(MPostWriteBarrier::New(alloc(), callInfo.thisArg(), callInfo.getArg(2)));
 
     return InliningStatus_Inlined;
 }
 
 IonBuilder::InliningStatus
 IonBuilder::inlineUnsafeGetReservedSlot(CallInfo &callInfo)
 {
     if (callInfo.argc() != 2 || callInfo.constructing())
@@ -1491,17 +1491,17 @@ IonBuilder::inlineUnsafeGetReservedSlot(
     // Don't inline if we don't have a constant slot.
     MDefinition *arg = callInfo.getArg(1)->toPassArg()->getArgument();
     if (!arg->isConstant())
         return InliningStatus_NotInlined;
     uint32_t slot = arg->toConstant()->value().toPrivateUint32();
 
     callInfo.unwrapArgs();
 
-    MLoadFixedSlot *load = MLoadFixedSlot::New(callInfo.getArg(0), slot);
+    MLoadFixedSlot *load = MLoadFixedSlot::New(alloc(), callInfo.getArg(0), slot);
     current->add(load);
     current->push(load);
 
     // We don't track reserved slot types, so always emit a barrier.
     if (!pushTypeBarrier(load, getInlineReturnTypeSet(), true))
         return InliningStatus_Error;
 
     return InliningStatus_Inlined;
@@ -1517,25 +1517,25 @@ IonBuilder::inlineHaveSameClass(CallInfo
     if (callInfo.getArg(1)->type() != MIRType_Object)
         return InliningStatus_NotInlined;
 
     types::TemporaryTypeSet *arg1Types = callInfo.getArg(0)->resultTypeSet();
     types::TemporaryTypeSet *arg2Types = callInfo.getArg(1)->resultTypeSet();
     const Class *arg1Clasp = arg1Types ? arg1Types->getKnownClass() : nullptr;
     const Class *arg2Clasp = arg2Types ? arg2Types->getKnownClass() : nullptr;
     if (arg1Clasp && arg2Clasp) {
-        MConstant *constant = MConstant::New(BooleanValue(arg1Clasp == arg2Clasp));
+        MConstant *constant = MConstant::New(alloc(), BooleanValue(arg1Clasp == arg2Clasp));
         current->add(constant);
         current->push(constant);
         return InliningStatus_Inlined;
     }
 
     callInfo.unwrapArgs();
 
-    MHaveSameClass *sameClass = MHaveSameClass::New(callInfo.getArg(0), callInfo.getArg(1));
+    MHaveSameClass *sameClass = MHaveSameClass::New(alloc(), callInfo.getArg(0), callInfo.getArg(1));
     current->add(sameClass);
     current->push(sameClass);
 
     return InliningStatus_Inlined;
 }
 
 IonBuilder::InliningStatus
 IonBuilder::inlineIsCallable(CallInfo &callInfo)
@@ -1560,25 +1560,25 @@ IonBuilder::inlineIsCallable(CallInfo &c
         const Class *clasp = types ? types->getKnownClass() : nullptr;
         if (clasp) {
             isCallableKnown = true;
             isCallableConstant = clasp->isCallable();
         }
     }
 
     if (isCallableKnown) {
-        MConstant *constant = MConstant::New(BooleanValue(isCallableConstant));
+        MConstant *constant = MConstant::New(alloc(), BooleanValue(isCallableConstant));
         current->add(constant);
         current->push(constant);
         return InliningStatus_Inlined;
     }
 
     callInfo.unwrapArgs();
 
-    MIsCallable *isCallable = MIsCallable::New(callInfo.getArg(0));
+    MIsCallable *isCallable = MIsCallable::New(alloc(), callInfo.getArg(0));
     current->add(isCallable);
     current->push(isCallable);
 
     return InliningStatus_Inlined;
 }
 
 IonBuilder::InliningStatus
 IonBuilder::inlineToObject(CallInfo &callInfo)
@@ -1599,37 +1599,37 @@ IonBuilder::inlineToObject(CallInfo &cal
     return InliningStatus_Inlined;
 }
 
 IonBuilder::InliningStatus
 IonBuilder::inlineBailout(CallInfo &callInfo)
 {
     callInfo.unwrapArgs();
 
-    current->add(MBail::New());
+    current->add(MBail::New(alloc()));
 
-    MConstant *undefined = MConstant::New(UndefinedValue());
+    MConstant *undefined = MConstant::New(alloc(), UndefinedValue());
     current->add(undefined);
     current->push(undefined);
     return InliningStatus_Inlined;
 }
 
 IonBuilder::InliningStatus
 IonBuilder::inlineAssertFloat32(CallInfo &callInfo)
 {
     callInfo.unwrapArgs();
 
     MDefinition *secondArg = callInfo.getArg(1);
 
     JS_ASSERT(secondArg->type() == MIRType_Boolean);
     JS_ASSERT(secondArg->isConstant());
 
     bool mustBeFloat32 = JSVAL_TO_BOOLEAN(secondArg->toConstant()->value());
-    current->add(MAssertFloat32::New(callInfo.getArg(0), mustBeFloat32));
+    current->add(MAssertFloat32::New(alloc(), callInfo.getArg(0), mustBeFloat32));
 
-    MConstant *undefined = MConstant::New(UndefinedValue());
+    MConstant *undefined = MConstant::New(alloc(), UndefinedValue());
     current->add(undefined);
     current->push(undefined);
     return InliningStatus_Inlined;
 }
 
 } // namespace jit
 } // namespace js
--- a/js/src/jit/MIR.cpp
+++ b/js/src/jit/MIR.cpp
@@ -26,19 +26,19 @@
 using namespace js;
 using namespace js::jit;
 
 using mozilla::DoublesAreIdentical;
 using mozilla::IsFloat32Representable;
 using mozilla::Maybe;
 
 template<size_t Op> static void
-ConvertDefinitionToDouble(MDefinition *def, MInstruction *consumer)
+ConvertDefinitionToDouble(TempAllocator &alloc, MDefinition *def, MInstruction *consumer)
 {
-    MInstruction *replace = MToDouble::New(def);
+    MInstruction *replace = MToDouble::New(alloc, def);
     consumer->replaceOperand(Op, replace);
     consumer->block()->insertBefore(consumer, replace);
 }
 
 static bool
 CheckUsesAreFloat32Consumers(MInstruction *ins)
 {
     bool allConsumerUses = true;
@@ -84,17 +84,17 @@ EqualValues(bool useGVN, MDefinition *le
 {
     if (useGVN)
         return left->valueNumber() == right->valueNumber();
 
     return left->id() == right->id();
 }
 
 static MConstant *
-EvaluateConstantOperands(MBinaryInstruction *ins, bool *ptypeChange = nullptr)
+EvaluateConstantOperands(TempAllocator &alloc, MBinaryInstruction *ins, bool *ptypeChange = nullptr)
 {
     MDefinition *left = ins->getOperand(0);
     MDefinition *right = ins->getOperand(1);
 
     if (!left->isConstant() || !right->isConstant())
         return nullptr;
 
     Value lhs = left->toConstant()->value();
@@ -147,17 +147,17 @@ EvaluateConstantOperands(MBinaryInstruct
         ret.setDouble(ret.toNumber());
 
     if (ins->type() != MIRTypeFromValue(ret)) {
         if (ptypeChange)
             *ptypeChange = true;
         return nullptr;
     }
 
-    return MConstant::New(ret);
+    return MConstant::New(alloc, ret);
 }
 
 void
 MDefinition::printName(FILE *fp) const
 {
     PrintOpcodeName(fp, op());
     fprintf(fp, "%u", id());
 
@@ -195,17 +195,17 @@ MDefinition::congruentIfOperandsEqual(MD
         if (getOperand(i)->valueNumber() != ins->getOperand(i)->valueNumber())
             return false;
     }
 
     return true;
 }
 
 MDefinition *
-MDefinition::foldsTo(bool useValueNumbers)
+MDefinition::foldsTo(TempAllocator &alloc, bool useValueNumbers)
 {
     // In the default case, there are no constants to fold.
     return this;
 }
 
 void
 MDefinition::analyzeEdgeCasesForward()
 {
@@ -247,22 +247,22 @@ MTest::infer()
 {
     JS_ASSERT(operandMightEmulateUndefined());
 
     if (!MaybeEmulatesUndefined(getOperand(0)))
         markOperandCantEmulateUndefined();
 }
 
 MDefinition *
-MTest::foldsTo(bool useValueNumbers)
+MTest::foldsTo(TempAllocator &alloc, bool useValueNumbers)
 {
     MDefinition *op = getOperand(0);
 
     if (op->isNot())
-        return MTest::New(op->toNot()->operand(), ifFalse(), ifTrue());
+        return MTest::New(alloc, op->toNot()->operand(), ifFalse(), ifTrue());
 
     return this;
 }
 
 void
 MDefinition::printOpcode(FILE *fp) const
 {
     PrintOpcodeName(fp, op());
@@ -408,25 +408,25 @@ MDefinition::replaceAllUsesWith(MDefinit
 
 bool
 MDefinition::emptyResultTypeSet() const
 {
     return resultTypeSet() && resultTypeSet()->empty();
 }
 
 MConstant *
-MConstant::New(const Value &v)
+MConstant::New(TempAllocator &alloc, const Value &v)
 {
-    return new MConstant(v);
+    return new(alloc) MConstant(v);
 }
 
 MConstant *
-MConstant::NewAsmJS(const Value &v, MIRType type)
+MConstant::NewAsmJS(TempAllocator &alloc, const Value &v, MIRType type)
 {
-    MConstant *constant = new MConstant(v);
+    MConstant *constant = new(alloc) MConstant(v);
     constant->setResultType(type);
     return constant;
 }
 
 types::TemporaryTypeSet *
 jit::MakeSingletonTypeSet(JSObject *obj)
 {
     LifoAlloc *alloc = GetIonContext()->temp->lifoAlloc();
@@ -606,19 +606,19 @@ MMathFunction::FunctionName(Function fun
 void
 MMathFunction::printOpcode(FILE *fp) const
 {
     MDefinition::printOpcode(fp);
     fprintf(fp, " %s", FunctionName(function()));
 }
 
 MParameter *
-MParameter::New(int32_t index, types::TemporaryTypeSet *types)
+MParameter::New(TempAllocator &alloc, int32_t index, types::TemporaryTypeSet *types)
 {
-    return new MParameter(index, types);
+    return new(alloc) MParameter(index, types);
 }
 
 void
 MParameter::printOpcode(FILE *fp) const
 {
     PrintOpcodeName(fp, op());
     fprintf(fp, " %d", index());
 }
@@ -634,95 +634,98 @@ MParameter::congruentTo(MDefinition *ins
 {
     if (!ins->isParameter())
         return false;
 
     return ins->toParameter()->index() == index_;
 }
 
 MCall *
-MCall::New(JSFunction *target, size_t maxArgc, size_t numActualArgs, bool construct)
+MCall::New(TempAllocator &alloc, JSFunction *target, size_t maxArgc, size_t numActualArgs,
+           bool construct)
 {
     JS_ASSERT(maxArgc >= numActualArgs);
-    MCall *ins = new MCall(target, numActualArgs, construct);
+    MCall *ins = new(alloc) MCall(target, numActualArgs, construct);
     if (!ins->init(maxArgc + NumNonArgumentOperands))
         return nullptr;
     return ins;
 }
 
 MApplyArgs *
-MApplyArgs::New(JSFunction *target, MDefinition *fun, MDefinition *argc, MDefinition *self)
+MApplyArgs::New(TempAllocator &alloc, JSFunction *target, MDefinition *fun, MDefinition *argc,
+                MDefinition *self)
 {
-    return new MApplyArgs(target, fun, argc, self);
+    return new(alloc) MApplyArgs(target, fun, argc, self);
 }
 
 MDefinition*
-MStringLength::foldsTo(bool useValueNumbers)
+MStringLength::foldsTo(TempAllocator &alloc, bool useValueNumbers)
 {
     if ((type() == MIRType_Int32) && (string()->isConstant())) {
         Value value = string()->toConstant()->value();
         size_t length = JS_GetStringLength(value.toString());
 
-        return MConstant::New(Int32Value(length));
+        return MConstant::New(alloc, Int32Value(length));
     }
 
     return this;
 }
 
 void
-MFloor::trySpecializeFloat32()
+MFloor::trySpecializeFloat32(TempAllocator &alloc)
 {
     // No need to look at the output, as it's an integer (see IonBuilder::inlineMathFloor)
     if (!input()->canProduceFloat32()) {
         if (input()->type() == MIRType_Float32)
-            ConvertDefinitionToDouble<0>(input(), this);
+            ConvertDefinitionToDouble<0>(alloc, input(), this);
         return;
     }
 
     if (type() == MIRType_Double)
         setResultType(MIRType_Float32);
 
     setPolicyType(MIRType_Float32);
 }
 
 MTest *
-MTest::New(MDefinition *ins, MBasicBlock *ifTrue, MBasicBlock *ifFalse)
+MTest::New(TempAllocator &alloc, MDefinition *ins, MBasicBlock *ifTrue, MBasicBlock *ifFalse)
 {
-    return new MTest(ins, ifTrue, ifFalse);
+    return new(alloc) MTest(ins, ifTrue, ifFalse);
 }
 
 MCompare *
-MCompare::New(MDefinition *left, MDefinition *right, JSOp op)
+MCompare::New(TempAllocator &alloc, MDefinition *left, MDefinition *right, JSOp op)
 {
-    return new MCompare(left, right, op);
+    return new(alloc) MCompare(left, right, op);
 }
 
 MCompare *
-MCompare::NewAsmJS(MDefinition *left, MDefinition *right, JSOp op, CompareType compareType)
+MCompare::NewAsmJS(TempAllocator &alloc, MDefinition *left, MDefinition *right, JSOp op,
+                   CompareType compareType)
 {
     JS_ASSERT(compareType == Compare_Int32 || compareType == Compare_UInt32 ||
               compareType == Compare_Double || compareType == Compare_Float32);
-    MCompare *comp = new MCompare(left, right, op);
+    MCompare *comp = new(alloc) MCompare(left, right, op);
     comp->compareType_ = compareType;
     comp->operandMightEmulateUndefined_ = false;
     comp->setResultType(MIRType_Int32);
     return comp;
 }
 
 MTableSwitch *
-MTableSwitch::New(MDefinition *ins, int32_t low, int32_t high)
+MTableSwitch::New(TempAllocator &alloc, MDefinition *ins, int32_t low, int32_t high)
 {
-    return new MTableSwitch(ins, low, high);
+    return new(alloc) MTableSwitch(ins, low, high);
 }
 
 MGoto *
-MGoto::New(MBasicBlock *target)
+MGoto::New(TempAllocator &alloc, MBasicBlock *target)
 {
     JS_ASSERT(target);
-    return new MGoto(target);
+    return new(alloc) MGoto(target);
 }
 
 void
 MUnbox::printOpcode(FILE *fp) const
 {
     PrintOpcodeName(fp, op());
     fprintf(fp, " ");
     getOperand(0)->printName(fp);
@@ -778,17 +781,17 @@ MPhi::removeOperand(size_t index)
         MPhi::setOperand(i, next->producer());
     }
 
     // truncate the inputs_ list:
     inputs_.shrinkBy(1);
 }
 
 MDefinition *
-MPhi::foldsTo(bool useValueNumbers)
+MPhi::foldsTo(TempAllocator &alloc, bool useValueNumbers)
 {
     JS_ASSERT(inputs_.length() != 0);
 
     MDefinition *first = getOperand(0);
 
     for (size_t i = 1; i < inputs_.length(); i++) {
         // Phis need dominator information to fold based on value numbers. For
         // simplicity, we only compare SSA names right now (bug 714727).
@@ -1045,22 +1048,22 @@ IsConstant(MDefinition *def, double v)
 {
     if (!def->isConstant())
         return false;
 
     return DoublesAreIdentical(def->toConstant()->value().toNumber(), v);
 }
 
 MDefinition *
-MBinaryBitwiseInstruction::foldsTo(bool useValueNumbers)
+MBinaryBitwiseInstruction::foldsTo(TempAllocator &alloc, bool useValueNumbers)
 {
     if (specialization_ != MIRType_Int32)
         return this;
 
-    if (MDefinition *folded = EvaluateConstantOperands(this))
+    if (MDefinition *folded = EvaluateConstantOperands(alloc, this))
         return folded;
 
     return this;
 }
 
 MDefinition *
 MBinaryBitwiseInstruction::foldUnnecessaryBitop()
 {
@@ -1237,24 +1240,24 @@ NeedNegativeZeroCheck(MDefinition *def)
           default:
             return true;
         }
     }
     return false;
 }
 
 MDefinition *
-MBinaryArithInstruction::foldsTo(bool useValueNumbers)
+MBinaryArithInstruction::foldsTo(TempAllocator &alloc, bool useValueNumbers)
 {
     if (specialization_ == MIRType_None)
         return this;
 
     MDefinition *lhs = getOperand(0);
     MDefinition *rhs = getOperand(1);
-    if (MDefinition *folded = EvaluateConstantOperands(this))
+    if (MDefinition *folded = EvaluateConstantOperands(alloc, this))
         return folded;
 
     // 0 + -0 = 0. So we can't remove addition
     if (isAdd() && specialization_ != MIRType_Int32)
         return this;
 
     if (IsConstant(rhs, getIdentity()))
         return lhs;
@@ -1265,61 +1268,61 @@ MBinaryArithInstruction::foldsTo(bool us
 
     if (IsConstant(lhs, getIdentity()))
         return rhs; // x op id => x
 
     return this;
 }
 
 void
-MBinaryArithInstruction::trySpecializeFloat32()
+MBinaryArithInstruction::trySpecializeFloat32(TempAllocator &alloc)
 {
     MDefinition *left = lhs();
     MDefinition *right = rhs();
 
     if (!left->canProduceFloat32() || !right->canProduceFloat32()
         || !CheckUsesAreFloat32Consumers(this))
     {
         if (left->type() == MIRType_Float32)
-            ConvertDefinitionToDouble<0>(left, this);
+            ConvertDefinitionToDouble<0>(alloc, left, this);
         if (right->type() == MIRType_Float32)
-            ConvertDefinitionToDouble<1>(right, this);
+            ConvertDefinitionToDouble<1>(alloc, right, this);
         return;
     }
 
     specialization_ = MIRType_Float32;
     setResultType(MIRType_Float32);
 }
 
 bool
 MAbs::fallible() const
 {
     return !implicitTruncate_ && (!range() || !range()->hasInt32Bounds());
 }
 
 void
-MAbs::trySpecializeFloat32()
+MAbs::trySpecializeFloat32(TempAllocator &alloc)
 {
     if (!input()->canProduceFloat32() || !CheckUsesAreFloat32Consumers(this)) {
         if (input()->type() == MIRType_Float32)
-            ConvertDefinitionToDouble<0>(input(), this);
+            ConvertDefinitionToDouble<0>(alloc, input(), this);
         return;
     }
 
     setResultType(MIRType_Float32);
     specialization_ = MIRType_Float32;
 }
 
 MDefinition *
-MDiv::foldsTo(bool useValueNumbers)
+MDiv::foldsTo(TempAllocator &alloc, bool useValueNumbers)
 {
     if (specialization_ == MIRType_None)
         return this;
 
-    if (MDefinition *folded = EvaluateConstantOperands(this))
+    if (MDefinition *folded = EvaluateConstantOperands(alloc, this))
         return folded;
 
     return this;
 }
 
 void
 MDiv::analyzeEdgeCasesForward()
 {
@@ -1383,39 +1386,39 @@ MMod::canBePowerOfTwoDivisor() const
     int32_t i = rhs()->toConstant()->value().toInt32();
     if (i <= 0 || !IsPowerOfTwo(i))
         return false;
 
     return true;
 }
 
 MDefinition *
-MMod::foldsTo(bool useValueNumbers)
+MMod::foldsTo(TempAllocator &alloc, bool useValueNumbers)
 {
     if (specialization_ == MIRType_None)
         return this;
 
-    if (MDefinition *folded = EvaluateConstantOperands(this))
+    if (MDefinition *folded = EvaluateConstantOperands(alloc, this))
         return folded;
 
     return this;
 }
 
 bool
 MMod::fallible()
 {
     return !isTruncated();
 }
 
 void
-MMathFunction::trySpecializeFloat32()
+MMathFunction::trySpecializeFloat32(TempAllocator &alloc)
 {
     if (!input()->canProduceFloat32() || !CheckUsesAreFloat32Consumers(this)) {
         if (input()->type() == MIRType_Float32)
-            ConvertDefinitionToDouble<0>(input(), this);
+            ConvertDefinitionToDouble<0>(alloc, input(), this);
         return;
     }
 
     setResultType(MIRType_Float32);
     setPolicyType(MIRType_Float32);
 }
 
 bool
@@ -1437,19 +1440,19 @@ MSub::fallible()
     if (isTruncated())
         return false;
     if (range() && range()->hasInt32Bounds())
         return false;
     return true;
 }
 
 MDefinition *
-MMul::foldsTo(bool useValueNumbers)
+MMul::foldsTo(TempAllocator &alloc, bool useValueNumbers)
 {
-    MDefinition *out = MBinaryArithInstruction::foldsTo(useValueNumbers);
+    MDefinition *out = MBinaryArithInstruction::foldsTo(alloc, useValueNumbers);
     if (out != this)
         return out;
 
     if (specialization() != MIRType_Int32)
         return this;
 
     if (EqualValues(useValueNumbers, lhs(), rhs()))
         setCanBeNegativeZero(false);
@@ -1519,17 +1522,17 @@ static inline bool
 KnownNonStringPrimitive(MDefinition *op)
 {
     return !op->mightBeType(MIRType_Object)
         && !op->mightBeType(MIRType_String)
         && !op->mightBeType(MIRType_Magic);
 }
 
 void
-MBinaryArithInstruction::infer(BaselineInspector *inspector, jsbytecode *pc)
+MBinaryArithInstruction::infer(TempAllocator &alloc, BaselineInspector *inspector, jsbytecode *pc)
 {
     JS_ASSERT(this->type() == MIRType_Value);
 
     specialization_ = MIRType_None;
 
     // Don't specialize if one operand could be an object. If we specialize
     // as int32 or double based on baseline feedback, we could DCE this
     // instruction and fail to invoke any valueOf methods.
@@ -1559,17 +1562,17 @@ MBinaryArithInstruction::infer(BaselineI
     // If the operation has ever overflowed, use a double specialization.
     if (inspector->hasSeenDoubleResult(pc))
         setResultType(MIRType_Double);
 
     // If the operation will always overflow on its constant operands, use a
     // double specialization so that it can be constant folded later.
     if ((isMul() || isDiv()) && lhs == MIRType_Int32 && rhs == MIRType_Int32) {
         bool typeChange = false;
-        EvaluateConstantOperands(this, &typeChange);
+        EvaluateConstantOperands(alloc, this, &typeChange);
         if (typeChange)
             setResultType(MIRType_Double);
     }
 
     JS_ASSERT(lhs < MIRType_String || lhs == MIRType_Value);
     JS_ASSERT(rhs < MIRType_String || rhs == MIRType_Value);
 
     MIRType rval = this->type();
@@ -1885,53 +1888,53 @@ MCompare::infer(BaselineInspector *inspe
     // instruction's type policy to insert fallible unboxes to the appropriate
     // input types.
 
     if (!strictEq)
         compareType_ = inspector->expectedCompareType(pc);
 }
 
 MBitNot *
-MBitNot::New(MDefinition *input)
+MBitNot::New(TempAllocator &alloc, MDefinition *input)
 {
-    return new MBitNot(input);
+    return new(alloc) MBitNot(input);
 }
 
 MBitNot *
-MBitNot::NewAsmJS(MDefinition *input)
+MBitNot::NewAsmJS(TempAllocator &alloc, MDefinition *input)
 {
-    MBitNot *ins = new MBitNot(input);
+    MBitNot *ins = new(alloc) MBitNot(input);
     ins->specialization_ = MIRType_Int32;
     JS_ASSERT(ins->type() == MIRType_Int32);
     return ins;
 }
 
 MDefinition *
-MBitNot::foldsTo(bool useValueNumbers)
+MBitNot::foldsTo(TempAllocator &alloc, bool useValueNumbers)
 {
     if (specialization_ != MIRType_Int32)
         return this;
 
     MDefinition *input = getOperand(0);
 
     if (input->isConstant()) {
         js::Value v = Int32Value(~(input->toConstant()->value().toInt32()));
-        return MConstant::New(v);
+        return MConstant::New(alloc, v);
     }
 
     if (input->isBitNot() && input->toBitNot()->specialization_ == MIRType_Int32) {
         JS_ASSERT(input->toBitNot()->getOperand(0)->type() == MIRType_Int32);
         return input->toBitNot()->getOperand(0); // ~~x => x
     }
 
     return this;
 }
 
 MDefinition *
-MTypeOf::foldsTo(bool useValueNumbers)
+MTypeOf::foldsTo(TempAllocator &alloc, bool useValueNumbers)
 {
     // Note: we can't use input->type() here, type analysis has
     // boxed the input.
     JS_ASSERT(input()->type() == MIRType_Value);
 
     JSType type;
 
     switch (inputType()) {
@@ -1959,124 +1962,125 @@ MTypeOf::foldsTo(bool useValueNumbers)
             break;
         }
         // FALL THROUGH
       default:
         return this;
     }
 
     JSRuntime *rt = GetIonContext()->runtime;
-    return MConstant::New(StringValue(TypeName(type, rt)));
+    return MConstant::New(alloc, StringValue(TypeName(type, rt)));
 }
 
 void
 MTypeOf::infer()
 {
     JS_ASSERT(inputMaybeCallableOrEmulatesUndefined());
 
     if (!MaybeEmulatesUndefined(input()) && !MaybeCallable(input()))
         markInputNotCallableOrEmulatesUndefined();
 }
 
 MBitAnd *
-MBitAnd::New(MDefinition *left, MDefinition *right)
+MBitAnd::New(TempAllocator &alloc, MDefinition *left, MDefinition *right)
 {
-    return new MBitAnd(left, right);
+    return new(alloc) MBitAnd(left, right);
 }
 
 MBitAnd *
-MBitAnd::NewAsmJS(MDefinition *left, MDefinition *right)
+MBitAnd::NewAsmJS(TempAllocator &alloc, MDefinition *left, MDefinition *right)
 {
-    MBitAnd *ins = new MBitAnd(left, right);
+    MBitAnd *ins = new(alloc) MBitAnd(left, right);
     ins->specializeForAsmJS();
     return ins;
 }
 
 MBitOr *
-MBitOr::New(MDefinition *left, MDefinition *right)
+MBitOr::New(TempAllocator &alloc, MDefinition *left, MDefinition *right)
 {
-    return new MBitOr(left, right);
+    return new(alloc) MBitOr(left, right);
 }
 
 MBitOr *
-MBitOr::NewAsmJS(MDefinition *left, MDefinition *right)
+MBitOr::NewAsmJS(TempAllocator &alloc, MDefinition *left, MDefinition *right)
 {
-    MBitOr *ins = new MBitOr(left, right);
+    MBitOr *ins = new(alloc) MBitOr(left, right);
     ins->specializeForAsmJS();
     return ins;
 }
 
 MBitXor *
-MBitXor::New(MDefinition *left, MDefinition *right)
+MBitXor::New(TempAllocator &alloc, MDefinition *left, MDefinition *right)
 {
-    return new MBitXor(left, right);
+    return new(alloc) MBitXor(left, right);
 }
 
 MBitXor *
-MBitXor::NewAsmJS(MDefinition *left, MDefinition *right)
+MBitXor::NewAsmJS(TempAllocator &alloc, MDefinition *left, MDefinition *right)
 {
-    MBitXor *ins = new MBitXor(left, right);
+    MBitXor *ins = new(alloc) MBitXor(left, right);
     ins->specializeForAsmJS();
     return ins;
 }
 
 MLsh *
-MLsh::New(MDefinition *left, MDefinition *right)
+MLsh::New(TempAllocator &alloc, MDefinition *left, MDefinition *right)
 {
-    return new MLsh(left, right);
+    return new(alloc) MLsh(left, right);
 }
 
 MLsh *
-MLsh::NewAsmJS(MDefinition *left, MDefinition *right)
+MLsh::NewAsmJS(TempAllocator &alloc, MDefinition *left, MDefinition *right)
 {
-    MLsh *ins = new MLsh(left, right);
+    MLsh *ins = new(alloc) MLsh(left, right);
     ins->specializeForAsmJS();
     return ins;
 }
 
 MRsh *
-MRsh::New(MDefinition *left, MDefinition *right)
+MRsh::New(TempAllocator &alloc, MDefinition *left, MDefinition *right)
 {
-    return new MRsh(left, right);
+    return new(alloc) MRsh(left, right);
 }
 
 MRsh *
-MRsh::NewAsmJS(MDefinition *left, MDefinition *right)
+MRsh::NewAsmJS(TempAllocator &alloc, MDefinition *left, MDefinition *right)
 {
-    MRsh *ins = new MRsh(left, right);
+    MRsh *ins = new(alloc) MRsh(left, right);
     ins->specializeForAsmJS();
     return ins;
 }
 
 MUrsh *
-MUrsh::New(MDefinition *left, MDefinition *right)
+MUrsh::New(TempAllocator &alloc, MDefinition *left, MDefinition *right)
 {
-    return new MUrsh(left, right);
+    return new(alloc) MUrsh(left, right);
 }
 
 MUrsh *
-MUrsh::NewAsmJS(MDefinition *left, MDefinition *right)
+MUrsh::NewAsmJS(TempAllocator &alloc, MDefinition *left, MDefinition *right)
 {
-    MUrsh *ins = new MUrsh(left, right);
+    MUrsh *ins = new(alloc) MUrsh(left, right);
     ins->specializeForAsmJS();
 
     // Since Ion has no UInt32 type, we use Int32 and we have a special
     // exception to the type rules: we can return values in
     // (INT32_MIN,UINT32_MAX] and still claim that we have an Int32 type
     // without bailing out. This is necessary because Ion has no UInt32
     // type and we can't have bailouts in asm.js code.
     ins->bailoutsDisabled_ = true;
 
     return ins;
 }
 
 MResumePoint *
-MResumePoint::New(MBasicBlock *block, jsbytecode *pc, MResumePoint *parent, Mode mode)
+MResumePoint::New(TempAllocator &alloc, MBasicBlock *block, jsbytecode *pc, MResumePoint *parent,
+                  Mode mode)
 {
-    MResumePoint *resume = new MResumePoint(block, pc, parent, mode);
+    MResumePoint *resume = new(alloc) MResumePoint(block, pc, parent, mode);
     if (!resume->init())
         return nullptr;
     resume->inherit(block);
     return resume;
 }
 
 MResumePoint::MResumePoint(MBasicBlock *block, jsbytecode *pc, MResumePoint *caller,
                            Mode mode)
@@ -2099,114 +2103,114 @@ MResumePoint::inherit(MBasicBlock *block
         // and LStackArg does not define a value.
         if (def->isPassArg())
             def = def->toPassArg()->getArgument();
         setOperand(i, def);
     }
 }
 
 MDefinition *
-MToInt32::foldsTo(bool useValueNumbers)
+MToInt32::foldsTo(TempAllocator &alloc, bool useValueNumbers)
 {
     MDefinition *input = getOperand(0);
     if (input->type() == MIRType_Int32)
         return input;
     return this;
 }
 
 void
 MToInt32::analyzeEdgeCasesBackward()
 {
     if (!NeedNegativeZeroCheck(this))
         setCanBeNegativeZero(false);
 }
 
 MDefinition *
-MTruncateToInt32::foldsTo(bool useValueNumbers)
+MTruncateToInt32::foldsTo(TempAllocator &alloc, bool useValueNumbers)
 {
     MDefinition *input = getOperand(0);
     if (input->type() == MIRType_Int32)
         return input;
 
     if (input->type() == MIRType_Double && input->isConstant()) {
         const Value &v = input->toConstant()->value();
         int32_t ret = ToInt32(v.toDouble());
-        return MConstant::New(Int32Value(ret));
+        return MConstant::New(alloc, Int32Value(ret));
     }
 
     return this;
 }
 
 MDefinition *
-MToDouble::foldsTo(bool useValueNumbers)
+MToDouble::foldsTo(TempAllocator &alloc, bool useValueNumbers)
 {
     MDefinition *in = input();
     if (in->type() == MIRType_Double)
         return in;
 
     if (in->isConstant()) {
         const Value &v = in->toConstant()->value();
         if (v.isNumber()) {
             double out = v.toNumber();
-            return MConstant::New(DoubleValue(out));
+            return MConstant::New(alloc, DoubleValue(out));
         }
     }
 
     // Fold unnecessary numeric conversions.
     if (input()->isToInt32()) {
         replaceOperand(0, input()->getOperand(0));
         conversion_ = NonStringPrimitives;
     }
 
     return this;
 }
 
 MDefinition *
-MToFloat32::foldsTo(bool useValueNumbers)
+MToFloat32::foldsTo(TempAllocator &alloc, bool useValueNumbers)
 {
     if (input()->type() == MIRType_Float32)
         return input();
 
     // If x is a Float32, Float32(Double(x)) == x
     if (input()->isToDouble() && input()->toToDouble()->input()->type() == MIRType_Float32)
         return input()->toToDouble()->input();
 
     if (input()->isConstant()) {
         const Value &v = input()->toConstant()->value();
         if (v.isNumber()) {
             float out = v.toNumber();
-            MConstant *c = MConstant::New(DoubleValue(out));
+            MConstant *c = MConstant::New(alloc, DoubleValue(out));
             c->setResultType(MIRType_Float32);
             return c;
         }
     }
     return this;
 }
 
 MDefinition *
-MToString::foldsTo(bool useValueNumbers)
+MToString::foldsTo(TempAllocator &alloc, bool useValueNumbers)
 {
     MDefinition *in = input();
     if (in->type() == MIRType_String)
         return in;
     return this;
 }
 
 MDefinition *
-MClampToUint8::foldsTo(bool useValueNumbers)
+MClampToUint8::foldsTo(TempAllocator &alloc, bool useValueNumbers)
 {
     if (input()->isConstant()) {
         const Value &v = input()->toConstant()->value();
         if (v.isDouble()) {
             int32_t clamped = ClampDoubleToUint8(v.toDouble());
-            return MConstant::New(Int32Value(clamped));
+            return MConstant::New(alloc, Int32Value(clamped));
         }
         if (v.isInt32()) {
             int32_t clamped = ClampIntForUint8Array(v.toInt32());
-            return MConstant::New(Int32Value(clamped));
+            return MConstant::New(alloc, Int32Value(clamped));
         }
     }
     return this;
 }
 
 bool
 MCompare::tryFold(bool *result)
 {
@@ -2406,89 +2410,89 @@ MCompare::evaluateConstantOperands(bool 
       default:
         return false;
     }
 
     return true;
 }
 
 MDefinition *
-MCompare::foldsTo(bool useValueNumbers)
+MCompare::foldsTo(TempAllocator &alloc, bool useValueNumbers)
 {
     bool result;
 
     if (tryFold(&result) || evaluateConstantOperands(&result)) {
         if (type() == MIRType_Int32)
-            return MConstant::New(Int32Value(result));
+            return MConstant::New(alloc, Int32Value(result));
 
         JS_ASSERT(type() == MIRType_Boolean);
-        return MConstant::New(BooleanValue(result));
+        return MConstant::New(alloc, BooleanValue(result));
     }
 
     return this;
 }
 
 void
-MCompare::trySpecializeFloat32()
+MCompare::trySpecializeFloat32(TempAllocator &alloc)
 {
     MDefinition *lhs = getOperand(0);
     MDefinition *rhs = getOperand(1);
 
     if (compareType_ == Compare_Float32)
         return;
 
     if (lhs->canProduceFloat32() && rhs->canProduceFloat32() && compareType_ == Compare_Double) {
         compareType_ = Compare_Float32;
     } else {
         if (lhs->type() == MIRType_Float32)
-            ConvertDefinitionToDouble<0>(lhs, this);
+            ConvertDefinitionToDouble<0>(alloc, lhs, this);
         if (rhs->type() == MIRType_Float32)
-            ConvertDefinitionToDouble<1>(rhs, this);
+            ConvertDefinitionToDouble<1>(alloc, rhs, this);
     }
 }
 
 void
 MNot::infer()
 {
     JS_ASSERT(operandMightEmulateUndefined());
 
     if (!MaybeEmulatesUndefined(getOperand(0)))
         markOperandCantEmulateUndefined();
 }
 
 MDefinition *
-MNot::foldsTo(bool useValueNumbers)
+MNot::foldsTo(TempAllocator &alloc, bool useValueNumbers)
 {
     // Fold if the input is constant
     if (operand()->isConstant()) {
         bool result = operand()->toConstant()->valueToBoolean();
         if (type() == MIRType_Int32)
-            return MConstant::New(Int32Value(!result));
+            return MConstant::New(alloc, Int32Value(!result));
 
         // ToBoolean can't cause side effects, so this is safe.
-        return MConstant::New(BooleanValue(!result));
+        return MConstant::New(alloc, BooleanValue(!result));
     }
 
     // NOT of an undefined or null value is always true
     if (operand()->type() == MIRType_Undefined || operand()->type() == MIRType_Null)
-        return MConstant::New(BooleanValue(true));
+        return MConstant::New(alloc, BooleanValue(true));
 
     // NOT of an object that can't emulate undefined is always false.
     if (operand()->type() == MIRType_Object && !operandMightEmulateUndefined())
-        return MConstant::New(BooleanValue(false));
+        return MConstant::New(alloc, BooleanValue(false));
 
     return this;
 }
 
 void
-MNot::trySpecializeFloat32()
+MNot::trySpecializeFloat32(TempAllocator &alloc)
 {
     MDefinition *in = input();
     if (!in->canProduceFloat32() && in->type() == MIRType_Float32)
-        ConvertDefinitionToDouble<0>(in, this);
+        ConvertDefinitionToDouble<0>(alloc, in, this);
 }
 
 void
 MBeta::printOpcode(FILE *fp) const
 {
     MDefinition::printOpcode(fp);
 
     Sprinter sp(GetIonContext()->cx);
@@ -2723,46 +2727,47 @@ MGetPropertyCache::setBlock(MBasicBlock 
 bool
 MGetPropertyCache::updateForReplacement(MDefinition *ins) {
     MGetPropertyCache *other = ins->toGetPropertyCache();
     location_.append(&other->location_);
     return true;
 }
 
 MDefinition *
-MAsmJSUnsignedToDouble::foldsTo(bool useValueNumbers)
+MAsmJSUnsignedToDouble::foldsTo(TempAllocator &alloc, bool useValueNumbers)
 {
     if (input()->isConstant()) {
         const Value &v = input()->toConstant()->value();
         if (v.isInt32())
-            return MConstant::New(DoubleValue(uint32_t(v.toInt32())));
+            return MConstant::New(alloc, DoubleValue(uint32_t(v.toInt32())));
     }
 
     return this;
 }
 
 MDefinition *
-MAsmJSUnsignedToFloat32::foldsTo(bool useValueNumbers)
+MAsmJSUnsignedToFloat32::foldsTo(TempAllocator &alloc, bool useValueNumbers)
 {
     if (input()->isConstant()) {
         const Value &v = input()->toConstant()->value();
         if (v.isInt32()) {
             double dval = double(uint32_t(v.toInt32()));
             if (IsFloat32Representable(dval))
-                return MConstant::NewAsmJS(JS::Float32Value(float(dval)), MIRType_Float32);
+                return MConstant::NewAsmJS(alloc, JS::Float32Value(float(dval)), MIRType_Float32);
         }
     }
 
     return this;
 }
 
 MAsmJSCall *
-MAsmJSCall::New(Callee callee, const Args &args, MIRType resultType, size_t spIncrement)
+MAsmJSCall::New(TempAllocator &alloc, Callee callee, const Args &args, MIRType resultType,
+                size_t spIncrement)
 {
-    MAsmJSCall *call = new MAsmJSCall;
+    MAsmJSCall *call = new(alloc) MAsmJSCall;
     call->spIncrement_ = spIncrement;
     call->callee_ = callee;
     call->setResultType(resultType);
 
     call->numArgs_ = args.length();
     call->argRegs_ = (AnyRegister *)GetIonContext()->temp->allocate(call->numArgs_ * sizeof(AnyRegister));
     if (!call->argRegs_)
         return nullptr;
@@ -2777,20 +2782,20 @@ MAsmJSCall::New(Callee callee, const Arg
         call->setOperand(i, args[i].def);
     if (callee.which() == Callee::Dynamic)
         call->setOperand(call->numArgs_, callee.dynamic());
 
     return call;
 }
 
 void
-MSqrt::trySpecializeFloat32() {
+MSqrt::trySpecializeFloat32(TempAllocator &alloc) {
     if (!input()->canProduceFloat32() || !CheckUsesAreFloat32Consumers(this)) {
         if (input()->type() == MIRType_Float32)
-            ConvertDefinitionToDouble<0>(input(), this);
+            ConvertDefinitionToDouble<0>(alloc, input(), this);
         return;
     }
 
     setResultType(MIRType_Float32);
     setPolicyType(MIRType_Float32);
 }
 
 bool
@@ -3068,17 +3073,17 @@ jit::AddObjectsForPropertyRead(MDefiniti
                 return false;
         }
     }
 
     return true;
 }
 
 static bool
-TryAddTypeBarrierForWrite(types::CompilerConstraintList *constraints,
+TryAddTypeBarrierForWrite(TempAllocator &alloc, types::CompilerConstraintList *constraints,
                           MBasicBlock *current, types::TemporaryTypeSet *objTypes,
                           PropertyName *name, MDefinition **pvalue)
 {
     // Return whether pvalue was modified to include a type barrier ensuring
     // that writing the value to objTypes/id will not require changing type
     // information.
 
     // All objects in the set must have the same types for name. Otherwise, we
@@ -3129,58 +3134,58 @@ TryAddTypeBarrierForWrite(types::Compile
         // The property is a particular primitive type, guard by unboxing the
         // value before the write.
         if ((*pvalue)->type() != MIRType_Value) {
             // The value is a different primitive, just do a VM call as it will
             // always trigger invalidation of the compiled code.
             JS_ASSERT((*pvalue)->type() != propertyType);
             return false;
         }
-        MInstruction *ins = MUnbox::New(*pvalue, propertyType, MUnbox::Fallible);
+        MInstruction *ins = MUnbox::New(alloc, *pvalue, propertyType, MUnbox::Fallible);
         current->add(ins);
         *pvalue = ins;
         return true;
       }
       default:;
     }
 
     if ((*pvalue)->type() != MIRType_Value)
         return false;
 
     types::TemporaryTypeSet *types =
         aggregateProperty.ref().maybeTypes()->clone(GetIonContext()->temp->lifoAlloc());
     if (!types)
         return false;
 
-    MInstruction *ins = MMonitorTypes::New(*pvalue, types);
+    MInstruction *ins = MMonitorTypes::New(alloc, *pvalue, types);
     current->add(ins);
     return true;
 }
 
 static MInstruction *
-AddTypeGuard(MBasicBlock *current, MDefinition *obj, types::TypeObjectKey *type,
-             bool bailOnEquality)
+AddTypeGuard(TempAllocator &alloc, MBasicBlock *current, MDefinition *obj,
+             types::TypeObjectKey *type, bool bailOnEquality)
 {
     MInstruction *guard;
 
     if (type->isTypeObject())
-        guard = MGuardObjectType::New(obj, type->asTypeObject(), bailOnEquality);
+        guard = MGuardObjectType::New(alloc, obj, type->asTypeObject(), bailOnEquality);
     else
-        guard = MGuardObjectIdentity::New(obj, type->asSingleObject(), bailOnEquality);
+        guard = MGuardObjectIdentity::New(alloc, obj, type->asSingleObject(), bailOnEquality);
 
     current->add(guard);
 
     // For now, never move type object guards.
     guard->setNotMovable();
 
     return guard;
 }
 
 bool
-jit::PropertyWriteNeedsTypeBarrier(types::CompilerConstraintList *constraints,
+jit::PropertyWriteNeedsTypeBarrier(TempAllocator &alloc, types::CompilerConstraintList *constraints,
                                    MBasicBlock *current, MDefinition **pobj,
                                    PropertyName *name, MDefinition **pvalue, bool canModify)
 {
     // If any value being written is not reflected in the type information for
     // objects which obj could represent, a type barrier is needed when writing
     // the value. As for propertyReadNeedsTypeBarrier, this only applies for
     // properties that are accounted for by type information, i.e. normal data
     // properties and elements.
@@ -3209,17 +3214,17 @@ jit::PropertyWriteNeedsTypeBarrier(types
         types::HeapTypeSetKey property = object->property(id);
         if (!TypeSetIncludes(property.maybeTypes(), (*pvalue)->type(), (*pvalue)->resultTypeSet())) {
             // Either pobj or pvalue needs to be modified to filter out the
             // types which the value could have but are not in the property,
             // or a VM call is required. A VM call is always required if pobj
             // and pvalue cannot be modified.
             if (!canModify)
                 return true;
-            success = TryAddTypeBarrierForWrite(constraints, current, types, name, pvalue);
+            success = TryAddTypeBarrierForWrite(alloc, constraints, current, types, name, pvalue);
             break;
         }
     }
 
     if (success)
         return false;
 
     // If all of the objects except one have property types which reflect the
@@ -3244,11 +3249,11 @@ jit::PropertyWriteNeedsTypeBarrier(types
 
         if ((property.maybeTypes() && !property.maybeTypes()->empty()) || excluded)
             return true;
         excluded = object;
     }
 
     JS_ASSERT(excluded);
 
-    *pobj = AddTypeGuard(current, *pobj, excluded, /* bailOnEquality = */ true);
+    *pobj = AddTypeGuard(alloc, current, *pobj, excluded, /* bailOnEquality = */ true);
     return false;
 }
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -373,17 +373,17 @@ class MDefinition : public MNode
         range_ = range;
     }
 
     virtual HashNumber valueHash() const;
     virtual bool congruentTo(MDefinition *ins) const {
         return false;
     }
     bool congruentIfOperandsEqual(MDefinition *ins) const;
-    virtual MDefinition *foldsTo(bool useValueNumbers);
+    virtual MDefinition *foldsTo(TempAllocator &alloc, bool useValueNumbers);
     virtual void analyzeEdgeCasesForward();
     virtual void analyzeEdgeCasesBackward();
 
     virtual bool truncate();
     virtual bool isOperandTruncated(size_t index) const;
 
     bool earlyAbortCheck();
 
@@ -465,17 +465,17 @@ class MDefinition : public MNode
         return !resultTypeSet() || resultTypeSet()->mightBeType(ValueTypeFromMIRType(type));
     }
 
     // Float32 specialization operations (see big comment in IonAnalysis before the Float32
     // specialization algorithm).
     virtual bool isFloat32Commutative() const { return false; }
     virtual bool canProduceFloat32() const { return false; }
     virtual bool canConsumeFloat32() const { return false; }
-    virtual void trySpecializeFloat32() {}
+    virtual void trySpecializeFloat32(TempAllocator &alloc) {}
 #ifdef DEBUG
     // Used during the pass that checks that Float32 flow into valid MDefinitions
     virtual bool isConsistentFloat32Use() const {
         return type() == MIRType_Float32 || canConsumeFloat32();
     }
 #endif
 
     // Returns the beginning of this definition's use chain.
@@ -896,18 +896,18 @@ class MStart : public MNullaryInstructio
 
   private:
     MStart(StartType startType)
       : startType_(startType)
     { }
 
   public:
     INSTRUCTION_HEADER(Start)
-    static MStart *New(StartType startType) {
-        return new MStart(startType);
+    static MStart *New(TempAllocator &alloc, StartType startType) {
+        return new(alloc) MStart(startType);
     }
 
     StartType startType() {
         return startType_;
     }
 };
 
 // Instruction marking on entrypoint for on-stack replacement.
@@ -917,33 +917,33 @@ class MOsrEntry : public MNullaryInstruc
 {
   protected:
     MOsrEntry() {
         setResultType(MIRType_Pointer);
     }
 
   public:
     INSTRUCTION_HEADER(OsrEntry)
-    static MOsrEntry *New() {
-        return new MOsrEntry;
+    static MOsrEntry *New(TempAllocator &alloc) {
+        return new(alloc) MOsrEntry;
     }
 };
 
 // No-op instruction. This cannot be moved or eliminated, and is intended for
 // anchoring resume points at arbitrary points in a block.
 class MNop : public MNullaryInstruction
 {
   protected:
     MNop() {
     }
 
   public:
     INSTRUCTION_HEADER(Nop)
-    static MNop *New() {
-        return new MNop();
+    static MNop *New(TempAllocator &alloc) {
+        return new(alloc) MNop();
     }
 
     AliasSet getAliasSet() const {
         return AliasSet::None();
     }
 };
 
 // A constant js::Value.
@@ -951,18 +951,18 @@ class MConstant : public MNullaryInstruc
 {
     Value value_;
 
   protected:
     MConstant(const Value &v);
 
   public:
     INSTRUCTION_HEADER(Constant)
-    static MConstant *New(const Value &v);
-    static MConstant *NewAsmJS(const Value &v, MIRType type);
+    static MConstant *New(TempAllocator &alloc, const Value &v);
+    static MConstant *NewAsmJS(TempAllocator &alloc, const Value &v, MIRType type);
 
     const js::Value &value() const {
         return value_;
     }
     const js::Value *vp() const {
         return &value_;
     }
     const bool valueToBoolean() const {
@@ -1007,17 +1007,17 @@ class MParameter : public MNullaryInstru
       : index_(index)
     {
         setResultType(MIRType_Value);
         setResultTypeSet(types);
     }
 
   public:
     INSTRUCTION_HEADER(Parameter)
-    static MParameter *New(int32_t index, types::TemporaryTypeSet *types);
+    static MParameter *New(TempAllocator &alloc, int32_t index, types::TemporaryTypeSet *types);
 
     int32_t index() const {
         return index_;
     }
     void printOpcode(FILE *fp) const;
 
     HashNumber valueHash() const;
     bool congruentTo(MDefinition *ins) const;
@@ -1034,18 +1034,18 @@ class MCallee : public MNullaryInstructi
 
   public:
     INSTRUCTION_HEADER(Callee)
 
     bool congruentTo(MDefinition *ins) const {
         return congruentIfOperandsEqual(ins);
     }
 
-    static MCallee *New() {
-        return new MCallee();
+    static MCallee *New(TempAllocator &alloc) {
+        return new(alloc) MCallee();
     }
     AliasSet getAliasSet() const {
         return AliasSet::None();
     }
 };
 
 class MControlInstruction : public MInstruction
 {
@@ -1101,17 +1101,17 @@ class MTableSwitch MOZ_FINAL
 
     MUse *getUseFor(size_t index) {
         JS_ASSERT(index == 0);
         return &operand_;
     }
 
   public:
     INSTRUCTION_HEADER(TableSwitch)
-    static MTableSwitch *New(MDefinition *ins, int32_t low, int32_t high);
+    static MTableSwitch *New(TempAllocator &alloc, MDefinition *ins, int32_t low, int32_t high);
 
     size_t numSuccessors() const {
         return successors_.length();
     }
 
     size_t addSuccessor(MBasicBlock *successor) {
         JS_ASSERT(successors_.length() < (size_t)(high_ - low_ + 2));
         JS_ASSERT(successors_.length() != 0);
@@ -1231,17 +1231,17 @@ class MAryControlInstruction : public MC
 class MGoto : public MAryControlInstruction<0, 1>
 {
     MGoto(MBasicBlock *target) {
         setSuccessor(0, target);
     }
 
   public:
     INSTRUCTION_HEADER(Goto)
-    static MGoto *New(MBasicBlock *target);
+    static MGoto *New(TempAllocator &alloc, MBasicBlock *target);
 
     MBasicBlock *target() {
         return getSuccessor(0);
     }
     AliasSet getAliasSet() const {
         return AliasSet::None();
     }
 };
@@ -1270,17 +1270,17 @@ class MTest
     {
         setOperand(0, ins);
         setSuccessor(0, if_true);
         setSuccessor(1, if_false);
     }
 
   public:
     INSTRUCTION_HEADER(Test)
-    static MTest *New(MDefinition *ins,
+    static MTest *New(TempAllocator &alloc, MDefinition *ins,
                       MBasicBlock *ifTrue, MBasicBlock *ifFalse);
 
     MBasicBlock *ifTrue() const {
         return getSuccessor(0);
     }
     MBasicBlock *ifFalse() const {
         return getSuccessor(1);
     }
@@ -1290,17 +1290,17 @@ class MTest
     TypePolicy *typePolicy() {
         return this;
     }
 
     AliasSet getAliasSet() const {
         return AliasSet::None();
     }
     void infer();
-    MDefinition *foldsTo(bool useValueNumbers);
+    MDefinition *foldsTo(TempAllocator &alloc, bool useValueNumbers);
 
     void markOperandCantEmulateUndefined() {
         operandMightEmulateUndefined_ = false;
     }
     bool operandMightEmulateUndefined() const {
         return operandMightEmulateUndefined_;
     }
 #ifdef DEBUG
@@ -1316,18 +1316,18 @@ class MReturn
     public BoxInputsPolicy
 {
     MReturn(MDefinition *ins) {
         setOperand(0, ins);
     }
 
   public:
     INSTRUCTION_HEADER(Return)
-    static MReturn *New(MDefinition *ins) {
-        return new MReturn(ins);
+    static MReturn *New(TempAllocator &alloc, MDefinition *ins) {
+        return new(alloc) MReturn(ins);
     }
 
     MDefinition *input() const {
         return getOperand(0);
     }
     TypePolicy *typePolicy() {
         return this;
     }
@@ -1341,18 +1341,18 @@ class MThrow
     public BoxInputsPolicy
 {
     MThrow(MDefinition *ins) {
         setOperand(0, ins);
     }
 
   public:
     INSTRUCTION_HEADER(Throw)
-    static MThrow *New(MDefinition *ins) {
-        return new MThrow(ins);
+    static MThrow *New(TempAllocator &alloc, MDefinition *ins) {
+        return new(alloc) MThrow(ins);
     }
 
     TypePolicy *typePolicy() {
         return this;
     }
     virtual AliasSet getAliasSet() const {
         return AliasSet::None();
     }
@@ -1369,18 +1369,18 @@ class MNewParallelArray : public MNullar
       : templateObject_(templateObject)
     {
         setResultType(MIRType_Object);
     }
 
   public:
     INSTRUCTION_HEADER(NewParallelArray);
 
-    static MNewParallelArray *New(JSObject *templateObject) {
-        return new MNewParallelArray(templateObject);
+    static MNewParallelArray *New(TempAllocator &alloc, JSObject *templateObject) {
+        return new(alloc) MNewParallelArray(templateObject);
     }
 
     AliasSet getAliasSet() const {
         return AliasSet::None();
     }
 
     JSObject *templateObject() const {
         return templateObject_;
@@ -1406,28 +1406,34 @@ class MNewArray : public MNullaryInstruc
   private:
     // Number of space to allocate for the array.
     uint32_t count_;
     // Template for the created object.
     CompilerRootObject templateObject_;
     // Allocate space at initialization or not
     AllocatingBehaviour allocating_;
 
-  public:
-    INSTRUCTION_HEADER(NewArray)
-
     MNewArray(uint32_t count, JSObject *templateObject, AllocatingBehaviour allocating)
       : count_(count),
         templateObject_(templateObject),
         allocating_(allocating)
     {
         setResultType(MIRType_Object);
         setResultTypeSet(MakeSingletonTypeSet(templateObject));
     }
 
+  public:
+    INSTRUCTION_HEADER(NewArray)
+
+    static MNewArray *New(TempAllocator &alloc, uint32_t count, JSObject *templateObject,
+                          AllocatingBehaviour allocating)
+    {
+        return new(alloc) MNewArray(count, templateObject, allocating);
+    }
+
     uint32_t count() const {
         return count_;
     }
 
     JSObject *templateObject() const {
         return templateObject_;
     }
 
@@ -1462,18 +1468,20 @@ class MNewObject : public MNullaryInstru
         JS_ASSERT_IF(templateObjectIsClassPrototype, !shouldUseVM());
         setResultType(MIRType_Object);
         setResultTypeSet(MakeSingletonTypeSet(templateObject));
     }
 
   public:
     INSTRUCTION_HEADER(NewObject)
 
-    static MNewObject *New(JSObject *templateObject, bool templateObjectIsClassPrototype) {
-        return new MNewObject(templateObject, templateObjectIsClassPrototype);
+    static MNewObject *New(TempAllocator &alloc, JSObject *templateObject,
+                           bool templateObjectIsClassPrototype)
+    {
+        return new(alloc) MNewObject(templateObject, templateObjectIsClassPrototype);
     }
 
     // Returns true if the code generator should call through to the
     // VM rather than the fast path.
     bool shouldUseVM() const;
 
     bool templateObjectIsClassPrototype() const {
         return templateObjectIsClassPrototype_;
@@ -1566,25 +1574,29 @@ class MNewDerivedTypedObject
     virtual AliasSet getAliasSet() const {
         return AliasSet::None();
     }
 };
 
 // Abort parallel execution.
 class MAbortPar : public MAryControlInstruction<0, 0>
 {
-  public:
-    INSTRUCTION_HEADER(AbortPar);
-
     MAbortPar()
       : MAryControlInstruction<0, 0>()
     {
         setResultType(MIRType_Undefined);
         setGuard();
     }
+
+  public:
+    INSTRUCTION_HEADER(AbortPar);
+
+    static MAbortPar *New(TempAllocator &alloc) {
+        return new(alloc) MAbortPar();
+    }
 };
 
 // Slow path for adding a property to an object without a known base.
 class MInitProp
   : public MAryInstruction<2>,
     public MixPolicy<ObjectPolicy<0>, BoxPolicy<1> >
 {
   public:
@@ -1597,18 +1609,20 @@ class MInitProp
         setOperand(0, obj);
         setOperand(1, value);
         setResultType(MIRType_None);
     }
 
   public:
     INSTRUCTION_HEADER(InitProp)
 
-    static MInitProp *New(MDefinition *obj, PropertyName *name, MDefinition *value) {
-        return new MInitProp(obj, name, value);
+    static MInitProp *New(TempAllocator &alloc, MDefinition *obj, PropertyName *name,
+                          MDefinition *value)
+    {
+        return new(alloc) MInitProp(obj, name, value);
     }
 
     MDefinition *getObject() const {
         return getOperand(0);
     }
     MDefinition *getValue() const {
         return getOperand(1);
     }
@@ -1633,18 +1647,20 @@ class MInitPropGetterSetter
     MInitPropGetterSetter(MDefinition *obj, PropertyName *name, MDefinition *value)
       : MBinaryInstruction(obj, value),
         name_(name)
     { }
 
   public:
     INSTRUCTION_HEADER(InitPropGetterSetter)
 
-    static MInitPropGetterSetter *New(MDefinition *obj, PropertyName *name, MDefinition *value) {
-        return new MInitPropGetterSetter(obj, name, value);
+    static MInitPropGetterSetter *New(TempAllocator &alloc, MDefinition *obj, PropertyName *name,
+                                      MDefinition *value)
+    {
+        return new(alloc) MInitPropGetterSetter(obj, name, value);
     }
 
     MDefinition *object() const {
         return getOperand(0);
     }
     MDefinition *value() const {
         return getOperand(1);
     }
@@ -1666,18 +1682,20 @@ class MInitElem
         setOperand(1, id);
         setOperand(2, value);
         setResultType(MIRType_None);
     }
 
   public:
     INSTRUCTION_HEADER(InitElem)
 
-    static MInitElem *New(MDefinition *obj, MDefinition *id, MDefinition *value) {
-        return new MInitElem(obj, id, value);
+    static MInitElem *New(TempAllocator &alloc, MDefinition *obj, MDefinition *id,
+                          MDefinition *value)
+    {
+        return new(alloc) MInitElem(obj, id, value);
     }
 
     MDefinition *getObject() const {
         return getOperand(0);
     }
     MDefinition *getId() const {
         return getOperand(1);
     }
@@ -1698,18 +1716,20 @@ class MInitElemGetterSetter
 {
     MInitElemGetterSetter(MDefinition *obj, MDefinition *id, MDefinition *value)
       : MTernaryInstruction(obj, id, value)
     { }
 
   public:
     INSTRUCTION_HEADER(InitElemGetterSetter)
 
-    static MInitElemGetterSetter *New(MDefinition *obj, MDefinition *id, MDefinition *value) {
-        return new MInitElemGetterSetter(obj, id, value);
+    static MInitElemGetterSetter *New(TempAllocator &alloc, MDefinition *obj, MDefinition *id,
+                                      MDefinition *value)
+    {
+        return new(alloc) MInitElemGetterSetter(obj, id, value);
     }
 
     MDefinition *object() const {
         return getOperand(0);
     }
     MDefinition *idValue() const {
         return getOperand(1);
     }
@@ -1794,17 +1814,18 @@ class MCall
         numActualArgs_(numActualArgs),
         needsArgCheck_(true)
     {
         setResultType(MIRType_Value);
     }
 
   public:
     INSTRUCTION_HEADER(Call)
-    static MCall *New(JSFunction *target, size_t maxArgc, size_t numActualArgs, bool construct);
+    static MCall *New(TempAllocator &alloc, JSFunction *target, size_t maxArgc, size_t numActualArgs,
+                      bool construct);
 
     void initPrepareCall(MDefinition *start) {
         JS_ASSERT(start->isPrepareCall());
         return setOperand(PrepareCallOperandIndex, start);
     }
     void initFunction(MDefinition *func) {
         JS_ASSERT(!func->isPassArg());
         return setOperand(FunctionOperandIndex, func);
@@ -1894,18 +1915,18 @@ class MApplyArgs
         setOperand(0, fun);
         setOperand(1, argc);
         setOperand(2, self);
         setResultType(MIRType_Value);
     }
 
   public:
     INSTRUCTION_HEADER(ApplyArgs)
-    static MApplyArgs *New(JSFunction *target, MDefinition *fun, MDefinition *argc,
-                           MDefinition *self);
+    static MApplyArgs *New(TempAllocator &alloc, JSFunction *target, MDefinition *fun,
+                           MDefinition *argc, MDefinition *self);
 
     MDefinition *getFunction() const {
         return getOperand(0);
     }
 
     // For TI-informed monomorphic callsites.
     JSFunction *getSingleTarget() const {
         return target_;
@@ -1933,18 +1954,18 @@ class MBail : public MNullaryInstruction
     {
         setGuard();
     }
 
   public:
     INSTRUCTION_HEADER(Bail)
 
     static MBail *
-    New() {
-        return new MBail();
+    New(TempAllocator &alloc) {
+        return new(alloc) MBail();
     }
 
 };
 
 class MAssertFloat32 : public MUnaryInstruction
 {
   protected:
     bool mustBeFloat32_;
@@ -1952,18 +1973,18 @@ class MAssertFloat32 : public MUnaryInst
     MAssertFloat32(MDefinition *value, bool mustBeFloat32)
       : MUnaryInstruction(value), mustBeFloat32_(mustBeFloat32)
     {
     }
 
   public:
     INSTRUCTION_HEADER(AssertFloat32)
 
-    static MAssertFloat32 *New(MDefinition *value, bool mustBeFloat32) {
-        return new MAssertFloat32(value, mustBeFloat32);
+    static MAssertFloat32 *New(TempAllocator &alloc, MDefinition *value, bool mustBeFloat32) {
+        return new(alloc) MAssertFloat32(value, mustBeFloat32);
     }
 
     bool canConsumeFloat32() const { return true; }
 
     bool mustBeFloat32() { return mustBeFloat32_; }
 };
 
 class MGetDynamicName
@@ -1977,18 +1998,18 @@ class MGetDynamicName
         setOperand(1, name);
         setResultType(MIRType_Value);
     }
 
   public:
     INSTRUCTION_HEADER(GetDynamicName)
 
     static MGetDynamicName *
-    New(MDefinition *scopeChain, MDefinition *name) {
-        return new MGetDynamicName(scopeChain, name);
+    New(TempAllocator &alloc, MDefinition *scopeChain, MDefinition *name) {
+        return new(alloc) MGetDynamicName(scopeChain, name);
     }
 
     MDefinition *getScopeChain() const {
         return getOperand(0);
     }
     MDefinition *getName() const {
         return getOperand(1);
     }
@@ -2012,18 +2033,18 @@ class MFilterArgumentsOrEval
         setOperand(0, string);
         setGuard();
         setResultType(MIRType_None);
     }
 
   public:
     INSTRUCTION_HEADER(FilterArgumentsOrEval)
 
-    static MFilterArgumentsOrEval *New(MDefinition *string) {
-        return new MFilterArgumentsOrEval(string);
+    static MFilterArgumentsOrEval *New(TempAllocator &alloc, MDefinition *string) {
+        return new(alloc) MFilterArgumentsOrEval(string);
     }
 
     MDefinition *getString() const {
         return getOperand(0);
     }
 
     TypePolicy *typePolicy() {
         return this;
@@ -2047,19 +2068,20 @@ class MCallDirectEval
         setOperand(2, thisValue);
         setResultType(MIRType_Value);
     }
 
   public:
     INSTRUCTION_HEADER(CallDirectEval)
 
     static MCallDirectEval *
-    New(MDefinition *scopeChain, MDefinition *string, MDefinition *thisValue,
-        jsbytecode *pc) {
-        return new MCallDirectEval(scopeChain, string, thisValue, pc);
+    New(TempAllocator &alloc, MDefinition *scopeChain, MDefinition *string, MDefinition *thisValue,
+        jsbytecode *pc)
+    {
+        return new(alloc) MCallDirectEval(scopeChain, string, thisValue, pc);
     }
 
     MDefinition *getScopeChain() const {
         return getOperand(0);
     }
     MDefinition *getString() const {
         return getOperand(1);
     }
@@ -2156,22 +2178,23 @@ class MCompare
         operandsAreNeverNaN_(false)
     {
         setResultType(MIRType_Boolean);
         setMovable();
     }
 
   public:
     INSTRUCTION_HEADER(Compare)
-    static MCompare *New(MDefinition *left, MDefinition *right, JSOp op);
-    static MCompare *NewAsmJS(MDefinition *left, MDefinition *right, JSOp op, CompareType compareType);
+    static MCompare *New(TempAllocator &alloc, MDefinition *left, MDefinition *right, JSOp op);
+    static MCompare *NewAsmJS(TempAllocator &alloc, MDefinition *left, MDefinition *right, JSOp op,
+                              CompareType compareType);
 
     bool tryFold(bool *result);
     bool evaluateConstantOperands(bool *result);
-    MDefinition *foldsTo(bool useValueNumbers);
+    MDefinition *foldsTo(TempAllocator &alloc, bool useValueNumbers);
 
     void infer(BaselineInspector *inspector, jsbytecode *pc);
     CompareType compareType() const {
         return compareType_;
     }
     bool isDoubleComparison() const {
         return compareType() == Compare_Double ||
                compareType() == Compare_DoubleMaybeCoerceLHS ||
@@ -2208,17 +2231,17 @@ class MCompare
             return AliasSet::Store(AliasSet::Any);
         JS_ASSERT(compareType_ <= Compare_Value);
         return AliasSet::None();
     }
 
     void printOpcode(FILE *fp) const;
     void collectRangeInfo();
 
-    void trySpecializeFloat32();
+    void trySpecializeFloat32(TempAllocator &alloc);
     bool isFloat32Commutative() const { return true; }
 
 # ifdef DEBUG
     bool isConsistentFloat32Use() const {
         return compareType_ == Compare_Float32;
     }
 # endif
 
@@ -2246,22 +2269,22 @@ class MBox : public MUnaryInstruction
                                 : types::Type::PrimitiveType(ValueTypeFromMIRType(ins->type()));
             setResultTypeSet(GetIonContext()->temp->lifoAlloc()->new_<types::TemporaryTypeSet>(ntype));
         }
         setMovable();
     }
 
   public:
     INSTRUCTION_HEADER(Box)
-    static MBox *New(MDefinition *ins)
+    static MBox *New(TempAllocator &alloc, MDefinition *ins)
     {
         // Cannot box a box.
         JS_ASSERT(ins->type() != MIRType_Value);
 
-        return new MBox(ins);
+        return new(alloc) MBox(ins);
     }
 
     bool congruentTo(MDefinition *ins) const {
         return congruentIfOperandsEqual(ins);
     }
     AliasSet getAliasSet() const {
         return AliasSet::None();
     }
@@ -2310,24 +2333,25 @@ class MUnbox : public MUnaryInstruction,
 
         if (mode_ == TypeBarrier || mode_ == Fallible)
             setGuard();
 
         bailoutKind_ = kind;
     }
   public:
     INSTRUCTION_HEADER(Unbox)
-    static MUnbox *New(MDefinition *ins, MIRType type, Mode mode)
-    {
-        return new MUnbox(ins, type, mode, Bailout_Normal);
-    }
-
-    static MUnbox *New(MDefinition *ins, MIRType type, Mode mode, BailoutKind kind)
-    {
-        return new MUnbox(ins, type, mode, kind);
+    static MUnbox *New(TempAllocator &alloc, MDefinition *ins, MIRType type, Mode mode)
+    {
+        return new(alloc) MUnbox(ins, type, mode, Bailout_Normal);
+    }
+
+    static MUnbox *New(TempAllocator &alloc, MDefinition *ins, MIRType type, Mode mode,
+                       BailoutKind kind)
+    {
+        return new(alloc) MUnbox(ins, type, mode, kind);
     }
 
     TypePolicy *typePolicy() {
         return this;
     }
 
     Mode mode() const {
         return mode_;
@@ -2359,18 +2383,18 @@ class MGuardObject : public MUnaryInstru
         setGuard();
         setMovable();
         setResultType(MIRType_Object);
     }
 
   public:
     INSTRUCTION_HEADER(GuardObject)
 
-    static MGuardObject *New(MDefinition *ins) {
-        return new MGuardObject(ins);
+    static MGuardObject *New(TempAllocator &alloc, MDefinition *ins) {
+        return new(alloc) MGuardObject(ins);
     }
 
     TypePolicy *typePolicy() {
         return this;
     }
     AliasSet getAliasSet() const {
         return AliasSet::None();
     }
@@ -2386,18 +2410,18 @@ class MGuardString
         setGuard();
         setMovable();
         setResultType(MIRType_String);
     }
 
   public:
     INSTRUCTION_HEADER(GuardString)
 
-    static MGuardString *New(MDefinition *ins) {
-        return new MGuardString(ins);
+    static MGuardString *New(TempAllocator &alloc, MDefinition *ins) {
+        return new(alloc) MGuardString(ins);
     }
 
     TypePolicy *typePolicy() {
         return this;
     }
     AliasSet getAliasSet() const {
         return AliasSet::None();
     }
@@ -2417,18 +2441,18 @@ class MAssertRange
         setGuard();
         setMovable();
         setResultType(MIRType_None);
     }
 
   public:
     INSTRUCTION_HEADER(AssertRange)
 
-    static MAssertRange *New(MDefinition *ins, const Range *assertedRange) {
-        return new MAssertRange(ins, assertedRange);
+    static MAssertRange *New(TempAllocator &alloc, MDefinition *ins, const Range *assertedRange) {
+        return new(alloc) MAssertRange(ins, assertedRange);
     }
 
     const Range *assertedRange() const {
         return assertedRange_;
     }
 
     AliasSet getAliasSet() const {
         return AliasSet::None();
@@ -2449,19 +2473,19 @@ class MCreateThisWithTemplate
       : templateObject_(templateObject)
     {
         setResultType(MIRType_Object);
         setResultTypeSet(MakeSingletonTypeSet(templateObject));
     }
 
   public:
     INSTRUCTION_HEADER(CreateThisWithTemplate);
-    static MCreateThisWithTemplate *New(JSObject *templateObject)
-    {
-        return new MCreateThisWithTemplate(templateObject);
+    static MCreateThisWithTemplate *New(TempAllocator &alloc, JSObject *templateObject)
+    {
+        return new(alloc) MCreateThisWithTemplate(templateObject);
     }
     JSObject *templateObject() const {
         return templateObject_;
     }
 
     // Although creation of |this| modifies global state, it is safely repeatable.
     AliasSet getAliasSet() const {
         return AliasSet::None();
@@ -2477,19 +2501,20 @@ class MCreateThisWithProto
     MCreateThisWithProto(MDefinition *callee, MDefinition *prototype)
       : MBinaryInstruction(callee, prototype)
     {
         setResultType(MIRType_Object);
     }
 
   public:
     INSTRUCTION_HEADER(CreateThisWithProto)
-    static MCreateThisWithProto *New(MDefinition *callee, MDefinition *prototype)
-    {
-        return new MCreateThisWithProto(callee, prototype);
+    static MCreateThisWithProto *New(TempAllocator &alloc, MDefinition *callee,
+                                     MDefinition *prototype)
+    {
+        return new(alloc) MCreateThisWithProto(callee, prototype);
     }
 
     MDefinition *getCallee() const {
         return getOperand(0);
     }
     MDefinition *getPrototype() const {
         return getOperand(1);
     }
@@ -2515,19 +2540,19 @@ class MCreateThis
     MCreateThis(MDefinition *callee)
       : MUnaryInstruction(callee)
     {
         setResultType(MIRType_Value);
     }
 
   public:
     INSTRUCTION_HEADER(CreateThis)
-    static MCreateThis *New(MDefinition *callee)
-    {
-        return new MCreateThis(callee);
+    static MCreateThis *New(TempAllocator &alloc, MDefinition *callee)
+    {
+        return new(alloc) MCreateThis(callee);
     }
 
     MDefinition *getCallee() const {
         return getOperand(0);
     }
 
     // Although creation of |this| modifies global state, it is safely repeatable.
     AliasSet getAliasSet() const {
@@ -2550,18 +2575,18 @@ class MCreateArgumentsObject
       : MUnaryInstruction(callObj)
     {
         setResultType(MIRType_Object);
         setGuard();
     }
 
   public:
     INSTRUCTION_HEADER(CreateArgumentsObject)
-    static MCreateArgumentsObject *New(MDefinition *callObj) {
-        return new MCreateArgumentsObject(callObj);
+    static MCreateArgumentsObject *New(TempAllocator &alloc, MDefinition *callObj) {
+        return new(alloc) MCreateArgumentsObject(callObj);
     }
 
     MDefinition *getCallObject() const {
         return getOperand(0);
     }
 
     AliasSet getAliasSet() const {
         return AliasSet::None();
@@ -2585,19 +2610,19 @@ class MGetArgumentsObjectArg
       : MUnaryInstruction(argsObject),
         argno_(argno)
     {
         setResultType(MIRType_Value);
     }
 
   public:
     INSTRUCTION_HEADER(GetArgumentsObjectArg)
-    static MGetArgumentsObjectArg *New(MDefinition *argsObj, size_t argno)
-    {
-        return new MGetArgumentsObjectArg(argsObj, argno);
+    static MGetArgumentsObjectArg *New(TempAllocator &alloc, MDefinition *argsObj, size_t argno)
+    {
+        return new(alloc) MGetArgumentsObjectArg(argsObj, argno);
     }
 
     MDefinition *getArgsObject() const {
         return getOperand(0);
     }
 
     size_t argno() const {
         return argno_;
@@ -2621,19 +2646,20 @@ class MSetArgumentsObjectArg
     MSetArgumentsObjectArg(MDefinition *argsObj, size_t argno, MDefinition *value)
       : MBinaryInstruction(argsObj, value),
         argno_(argno)
     {
     }
 
   public:
     INSTRUCTION_HEADER(SetArgumentsObjectArg)
-    static MSetArgumentsObjectArg *New(MDefinition *argsObj, size_t argno, MDefinition *value)
-    {
-        return new MSetArgumentsObjectArg(argsObj, argno, value);
+    static MSetArgumentsObjectArg *New(TempAllocator &alloc, MDefinition *argsObj, size_t argno,
+                                       MDefinition *value)
+    {
+        return new(alloc) MSetArgumentsObjectArg(argsObj, argno, value);
     }
 
     MDefinition *getArgsObject() const {
         return getOperand(0);
     }
 
     size_t argno() const {
         return argno_;
@@ -2659,18 +2685,18 @@ class MRunOncePrologue
     MRunOncePrologue()
     {
         setGuard();
     }
 
   public:
     INSTRUCTION_HEADER(RunOncePrologue)
 
-    static MRunOncePrologue *New() {
-        return new MRunOncePrologue();
+    static MRunOncePrologue *New(TempAllocator &alloc) {
+        return new(alloc) MRunOncePrologue();
     }
     bool possiblyCalls() const {
         return true;
     }
 };
 
 // Given a MIRType_Value A and a MIRType_Object B:
 // If the Value may be safely unboxed to an Object, return Object(A).
@@ -2683,19 +2709,19 @@ class MReturnFromCtor
     MReturnFromCtor(MDefinition *value, MDefinition *object) {
         setOperand(0, value);
         setOperand(1, object);
         setResultType(MIRType_Object);
     }
 
   public:
     INSTRUCTION_HEADER(ReturnFromCtor)
-    static MReturnFromCtor *New(MDefinition *value, MDefinition *object)
-    {
-        return new MReturnFromCtor(value, object);
+    static MReturnFromCtor *New(TempAllocator &alloc, MDefinition *value, MDefinition *object)
+    {
+        return new(alloc) MReturnFromCtor(value, object);
     }
 
     MDefinition *getValue() const {
         return getOperand(0);
     }
     MDefinition *getObject() const {
         return getOperand(1);
     }
@@ -2724,19 +2750,19 @@ class MPassArg
       : MUnaryInstruction(def), argnum_(-1)
     {
         setResultType(def->type());
         setResultTypeSet(def->resultTypeSet());
     }
 
   public:
     INSTRUCTION_HEADER(PassArg)
-    static MPassArg *New(MDefinition *def)
-    {
-        return new MPassArg(def);
+    static MPassArg *New(TempAllocator &alloc, MDefinition *def)
+    {
+        return new(alloc) MPassArg(def);
     }
 
     MDefinition *getArgument() const {
         return getOperand(0);
     }
 
     // Set by the MCall.
     void setArgnum(uint32_t argnum) {
@@ -2777,32 +2803,34 @@ class MToDouble
       : MUnaryInstruction(def), conversion_(conversion)
     {
         setResultType(MIRType_Double);
         setMovable();
     }
 
   public:
     INSTRUCTION_HEADER(ToDouble)
-    static MToDouble *New(MDefinition *def, ConversionKind conversion = NonStringPrimitives) {
-        return new MToDouble(def, conversion);
-    }
-    static MToDouble *NewAsmJS(MDefinition *def) {
-        return new MToDouble(def);
+    static MToDouble *New(TempAllocator &alloc, MDefinition *def,
+                          ConversionKind conversion = NonStringPrimitives)
+    {
+        return new(alloc) MToDouble(def, conversion);
+    }
+    static MToDouble *NewAsmJS(TempAllocator &alloc, MDefinition *def) {
+        return new(alloc) MToDouble(def);
     }
 
     ConversionKind conversion() const {
         return conversion_;
     }
 
     TypePolicy *typePolicy() {
         return this;
     }
 
-    MDefinition *foldsTo(bool useValueNumbers);
+    MDefinition *foldsTo(TempAllocator &alloc, bool useValueNumbers);
     bool congruentTo(MDefinition *ins) const {
         if (!ins->isToDouble() || ins->toToDouble()->conversion() != conversion())
             return false;
         return congruentIfOperandsEqual(ins);
     }
     AliasSet getAliasSet() const {
         return AliasSet::None();
     }
@@ -2837,32 +2865,34 @@ class MToFloat32
       : MUnaryInstruction(def), conversion_(conversion)
     {
         setResultType(MIRType_Float32);
         setMovable();
     }
 
   public:
     INSTRUCTION_HEADER(ToFloat32)
-    static MToFloat32 *New(MDefinition *def, ConversionKind conversion = NonStringPrimitives) {
-        return new MToFloat32(def, conversion);
-    }
-    static MToFloat32 *NewAsmJS(MDefinition *def) {
-        return new MToFloat32(def, NonStringPrimitives);
+    static MToFloat32 *New(TempAllocator &alloc, MDefinition *def,
+                           ConversionKind conversion = NonStringPrimitives)
+    {
+        return new(alloc) MToFloat32(def, conversion);
+    }
+    static MToFloat32 *NewAsmJS(TempAllocator &alloc, MDefinition *def) {
+        return new(alloc) MToFloat32(def, NonStringPrimitives);
     }
 
     ConversionKind conversion() const {
         return conversion_;
     }
 
     TypePolicy *typePolicy() {
         return this;
     }
 
-    virtual MDefinition *foldsTo(bool useValueNumbers);
+    virtual MDefinition *foldsTo(TempAllocator &alloc, bool useValueNumbers);
     bool congruentTo(MDefinition *ins) const {
         if (!ins->isToFloat32() || ins->toToFloat32()->conversion() != conversion())
             return false;
         return congruentIfOperandsEqual(ins);
     }
     AliasSet getAliasSet() const {
         return AliasSet::None();
     }
@@ -2881,21 +2911,21 @@ class MAsmJSUnsignedToDouble
       : MUnaryInstruction(def)
     {
         setResultType(MIRType_Double);
         setMovable();
     }
 
   public:
     INSTRUCTION_HEADER(AsmJSUnsignedToDouble);
-    static MAsmJSUnsignedToDouble *NewAsmJS(MDefinition *def) {
-        return new MAsmJSUnsignedToDouble(def);
-    }
-
-    MDefinition *foldsTo(bool useValueNumbers);
+    static MAsmJSUnsignedToDouble *NewAsmJS(TempAllocator &alloc, MDefinition *def) {
+        return new(alloc) MAsmJSUnsignedToDouble(def);
+    }
+
+    MDefinition *foldsTo(TempAllocator &alloc, bool useValueNumbers);
     bool congruentTo(MDefinition *ins) const {
         return congruentIfOperandsEqual(ins);
     }
     AliasSet getAliasSet() const {
         return AliasSet::None();
     }
 };
 
@@ -2907,21 +2937,21 @@ class MAsmJSUnsignedToFloat32
       : MUnaryInstruction(def)
     {
         setResultType(MIRType_Float32);
         setMovable();
     }
 
   public:
     INSTRUCTION_HEADER(AsmJSUnsignedToFloat32);
-    static MAsmJSUnsignedToFloat32 *NewAsmJS(MDefinition *def) {
-        return new MAsmJSUnsignedToFloat32(def);
-    }
-
-    MDefinition *foldsTo(bool useValueNumbers);
+    static MAsmJSUnsignedToFloat32 *NewAsmJS(TempAllocator &alloc, MDefinition *def) {
+        return new(alloc) MAsmJSUnsignedToFloat32(def);
+    }
+
+    MDefinition *foldsTo(TempAllocator &alloc, bool useValueNumbers);
     bool congruentTo(MDefinition *ins) const {
         return congruentIfOperandsEqual(ins);
     }
     AliasSet getAliasSet() const {
         return AliasSet::None();
     }
 
     bool canProduceFloat32() const { return true; }
@@ -2941,22 +2971,22 @@ class MToInt32
         canBeNegativeZero_(true)
     {
         setResultType(MIRType_Int32);
         setMovable();
     }
 
   public:
     INSTRUCTION_HEADER(ToInt32)
-    static MToInt32 *New(MDefinition *def)
-    {
-        return new MToInt32(def);
-    }
-
-    MDefinition *foldsTo(bool useValueNumbers);
+    static MToInt32 *New(TempAllocator &alloc, MDefinition *def)
+    {
+        return new(alloc) MToInt32(def);
+    }
+
+    MDefinition *foldsTo(TempAllocator &alloc, bool useValueNumbers);
 
     // this only has backwards information flow.
     void analyzeEdgeCasesBackward();
 
     bool canBeNegativeZero() {
         return canBeNegativeZero_;
     }
     void setCanBeNegativeZero(bool negativeZero) {
@@ -2989,24 +3019,24 @@ class MTruncateToInt32 : public MUnaryIn
       : MUnaryInstruction(def)
     {
         setResultType(MIRType_Int32);
         setMovable();
     }
 
   public:
     INSTRUCTION_HEADER(TruncateToInt32)
-    static MTruncateToInt32 *New(MDefinition *def) {
-        return new MTruncateToInt32(def);
-    }
-    static MTruncateToInt32 *NewAsmJS(MDefinition *def) {
-        return new MTruncateToInt32(def);
-    }
-
-    MDefinition *foldsTo(bool useValueNumbers);
+    static MTruncateToInt32 *New(TempAllocator &alloc, MDefinition *def) {
+        return new(alloc) MTruncateToInt32(def);
+    }
+    static MTruncateToInt32 *NewAsmJS(TempAllocator &alloc, MDefinition *def) {
+        return new(alloc) MTruncateToInt32(def);
+    }
+
+    MDefinition *foldsTo(TempAllocator &alloc, bool useValueNumbers);
 
     bool congruentTo(MDefinition *ins) const {
         return congruentIfOperandsEqual(ins);
     }
     AliasSet getAliasSet() const {
         return AliasSet::None();
     }
 
@@ -3026,22 +3056,22 @@ class MToString : public MUnaryInstructi
       : MUnaryInstruction(def)
     {
         setResultType(MIRType_String);
         setMovable();
     }
 
   public:
     INSTRUCTION_HEADER(ToString)
-    static MToString *New(MDefinition *def)
-    {
-        return new MToString(def);
-    }
-
-    MDefinition *foldsTo(bool useValueNumbers);
+    static MToString *New(TempAllocator &alloc, MDefinition *def)
+    {
+        return new(alloc) MToString(def);
+    }
+
+    MDefinition *foldsTo(TempAllocator &alloc, bool useValueNumbers);
 
     bool congruentTo(MDefinition *ins) const {
         return congruentIfOperandsEqual(ins);
     }
     AliasSet getAliasSet() const {
         JS_ASSERT(input()->type() < MIRType_Object);
         return AliasSet::None();
     }
@@ -3056,24 +3086,24 @@ class MBitNot
       : MUnaryInstruction(input)
     {
         setResultType(MIRType_Int32);
         setMovable();
     }
 
   public:
     INSTRUCTION_HEADER(BitNot)
-    static MBitNot *New(MDefinition *input);
-    static MBitNot *NewAsmJS(MDefinition *input);
-
-    TypePolicy *typePolicy() {
-        return this;
-    }
-
-    MDefinition *foldsTo(bool useValueNumbers);
+    static MBitNot *New(TempAllocator &alloc, MDefinition *input);
+    static MBitNot *NewAsmJS(TempAllocator &alloc, MDefinition *input);
+
+    TypePolicy *typePolicy() {
+        return this;
+    }
+
+    MDefinition *foldsTo(TempAllocator &alloc, bool useValueNumbers);
     void infer();
 
     bool congruentTo(MDefinition *ins) const {
         return congruentIfOperandsEqual(ins);
     }
     AliasSet getAliasSet() const {
         if (specialization_ == MIRType_None)
             return AliasSet::Store(AliasSet::Any);
@@ -3095,28 +3125,28 @@ class MTypeOf
     {
         setResultType(MIRType_String);
         setMovable();
     }
 
   public:
     INSTRUCTION_HEADER(TypeOf)
 
-    static MTypeOf *New(MDefinition *def, MIRType inputType) {
-        return new MTypeOf(def, inputType);
+    static MTypeOf *New(TempAllocator &alloc, MDefinition *def, MIRType inputType) {
+        return new(alloc) MTypeOf(def, inputType);
     }
 
     TypePolicy *typePolicy() {
         return this;
     }
     MIRType inputType() const {
         return inputType_;
     }
 
-    MDefinition *foldsTo(bool useValueNumbers);
+    MDefinition *foldsTo(TempAllocator &alloc, bool useValueNumbers);
     void infer();
 
     bool inputMaybeCallableOrEmulatesUndefined() const {
         return inputMaybeCallableOrEmulatesUndefined_;
     }
     void markInputNotCallableOrEmulatesUndefined() {
         inputMaybeCallableOrEmulatesUndefined_ = false;
     }
@@ -3134,18 +3164,18 @@ class MToId
       : MBinaryInstruction(object, index)
     {
         setResultType(MIRType_Value);
     }
 
   public:
     INSTRUCTION_HEADER(ToId)
 
-    static MToId *New(MDefinition *object, MDefinition *index) {
-        return new MToId(object, index);
+    static MToId *New(TempAllocator &alloc, MDefinition *object, MDefinition *index) {
+        return new(alloc) MToId(object, index);
     }
 
     TypePolicy *typePolicy() {
         return this;
     }
 };
 
 class MBinaryBitwiseInstruction
@@ -3162,17 +3192,17 @@ class MBinaryBitwiseInstruction
 
     void specializeForAsmJS();
 
   public:
     TypePolicy *typePolicy() {
         return this;
     }
 
-    MDefinition *foldsTo(bool useValueNumbers);
+    MDefinition *foldsTo(TempAllocator &alloc, bool useValueNumbers);
     MDefinition *foldUnnecessaryBitop();
     virtual MDefinition *foldIfZero(size_t operand) = 0;
     virtual MDefinition *foldIfNegOne(size_t operand) = 0;
     virtual MDefinition *foldIfEqual()  = 0;
     virtual void infer(BaselineInspector *inspector, jsbytecode *pc);
 
     bool congruentTo(MDefinition *ins) const {
         return congruentIfOperandsEqual(ins);
@@ -3189,18 +3219,18 @@ class MBinaryBitwiseInstruction
 class MBitAnd : public MBinaryBitwiseInstruction
 {
     MBitAnd(MDefinition *left, MDefinition *right)
       : MBinaryBitwiseInstruction(left, right)
     { }
 
   public:
     INSTRUCTION_HEADER(BitAnd)
-    static MBitAnd *New(MDefinition *left, MDefinition *right);
-    static MBitAnd *NewAsmJS(MDefinition *left, MDefinition *right);
+    static MBitAnd *New(TempAllocator &alloc, MDefinition *left, MDefinition *right);
+    static MBitAnd *NewAsmJS(TempAllocator &alloc, MDefinition *left, MDefinition *right);
 
     MDefinition *foldIfZero(size_t operand) {
         return getOperand(operand); // 0 & x => 0;
     }
     MDefinition *foldIfNegOne(size_t operand) {
         return getOperand(1 - operand); // x & -1 => x
     }
     MDefinition *foldIfEqual() {
@@ -3212,18 +3242,18 @@ class MBitAnd : public MBinaryBitwiseIns
 class MBitOr : public MBinaryBitwiseInstruction
 {
     MBitOr(MDefinition *left, MDefinition *right)
       : MBinaryBitwiseInstruction(left, right)
     { }
 
   public:
     INSTRUCTION_HEADER(BitOr)
-    static MBitOr *New(MDefinition *left, MDefinition *right);
-    static MBitOr *NewAsmJS(MDefinition *left, MDefinition *right);
+    static MBitOr *New(TempAllocator &alloc, MDefinition *left, MDefinition *right);
+    static MBitOr *NewAsmJS(TempAllocator &alloc, MDefinition *left, MDefinition *right);
 
     MDefinition *foldIfZero(size_t operand) {
         return getOperand(1 - operand); // 0 | x => x, so if ith is 0, return (1-i)th
     }
     MDefinition *foldIfNegOne(size_t operand) {
         return getOperand(operand); // x | -1 => -1
     }
     MDefinition *foldIfEqual() {
@@ -3235,18 +3265,18 @@ class MBitOr : public MBinaryBitwiseInst
 class MBitXor : public MBinaryBitwiseInstruction
 {
     MBitXor(MDefinition *left, MDefinition *right)
       : MBinaryBitwiseInstruction(left, right)
     { }
 
   public:
     INSTRUCTION_HEADER(BitXor)
-    static MBitXor *New(MDefinition *left, MDefinition *right);
-    static MBitXor *NewAsmJS(MDefinition *left, MDefinition *right);
+    static MBitXor *New(TempAllocator &alloc, MDefinition *left, MDefinition *right);
+    static MBitXor *NewAsmJS(TempAllocator &alloc, MDefinition *left, MDefinition *right);
 
     MDefinition *foldIfZero(size_t operand) {
         return getOperand(1 - operand); // 0 ^ x => x
     }
     MDefinition *foldIfNegOne(size_t operand) {
         return this;
     }
     MDefinition *foldIfEqual() {
@@ -3276,18 +3306,18 @@ class MShiftInstruction
 class MLsh : public MShiftInstruction
 {
     MLsh(MDefinition *left, MDefinition *right)
       : MShiftInstruction(left, right)
     { }
 
   public:
     INSTRUCTION_HEADER(Lsh)
-    static MLsh *New(MDefinition *left, MDefinition *right);
-    static MLsh *NewAsmJS(MDefinition *left, MDefinition *right);
+    static MLsh *New(TempAllocator &alloc, MDefinition *left, MDefinition *right);
+    static MLsh *NewAsmJS(TempAllocator &alloc, MDefinition *left, MDefinition *right);
 
     MDefinition *foldIfZero(size_t operand) {
         // 0 << x => 0
         // x << 0 => x
         return getOperand(0);
     }
 
     void computeRange();
@@ -3296,18 +3326,18 @@ class MLsh : public MShiftInstruction
 class MRsh : public MShiftInstruction
 {
     MRsh(MDefinition *left, MDefinition *right)
       : MShiftInstruction(left, right)
     { }
 
   public:
     INSTRUCTION_HEADER(Rsh)
-    static MRsh *New(MDefinition *left, MDefinition *right);
-    static MRsh *NewAsmJS(MDefinition *left, MDefinition *right);
+    static MRsh *New(TempAllocator &alloc, MDefinition *left, MDefinition *right);
+    static MRsh *NewAsmJS(TempAllocator &alloc, MDefinition *left, MDefinition *right);
 
     MDefinition *foldIfZero(size_t operand) {
         // 0 >> x => 0
         // x >> 0 => x
         return getOperand(0);
     }
     void computeRange();
 };
@@ -3318,18 +3348,18 @@ class MUrsh : public MShiftInstruction
 
     MUrsh(MDefinition *left, MDefinition *right)
       : MShiftInstruction(left, right),
         bailoutsDisabled_(false)
     { }
 
   public:
     INSTRUCTION_HEADER(Ursh)
-    static MUrsh *New(MDefinition *left, MDefinition *right);
-    static MUrsh *NewAsmJS(MDefinition *left, MDefinition *right);
+    static MUrsh *New(TempAllocator &alloc, MDefinition *left, MDefinition *right);
+    static MUrsh *NewAsmJS(TempAllocator &alloc, MDefinition *left, MDefinition *right);
 
     MDefinition *foldIfZero(size_t operand) {
         // 0 >>> x => 0
         if (operand == 0)
             return getOperand(0);
 
         return this;
     }
@@ -3371,28 +3401,28 @@ class MBinaryArithInstruction
 
     TypePolicy *typePolicy() {
         return this;
     }
     MIRType specialization() const {
         return specialization_;
     }
 
-    MDefinition *foldsTo(bool useValueNumbers);
+    MDefinition *foldsTo(TempAllocator &alloc, bool useValueNumbers);
 
     virtual double getIdentity() = 0;
 
-    void infer(BaselineInspector *inspector, jsbytecode *pc);
+    void infer(TempAllocator &alloc, BaselineInspector *inspector, jsbytecode *pc);
 
     void setInt32() {
         specialization_ = MIRType_Int32;
         setResultType(MIRType_Int32);
     }
 
-    virtual void trySpecializeFloat32();
+    virtual void trySpecializeFloat32(TempAllocator &alloc);
 
     bool congruentTo(MDefinition *ins) const {
         return MBinaryInstruction::congruentTo(ins);
     }
     AliasSet getAliasSet() const {
         if (specialization_ >= MIRType_Object)
             return AliasSet::Store(AliasSet::Any);
         return AliasSet::None();
@@ -3419,18 +3449,20 @@ class MMinMax
         JS_ASSERT(type == MIRType_Double || type == MIRType_Int32);
         setResultType(type);
         setMovable();
         specialization_ = type;
     }
 
   public:
     INSTRUCTION_HEADER(MinMax)
-    static MMinMax *New(MDefinition *left, MDefinition *right, MIRType type, bool isMax) {
-        return new MMinMax(left, right, type, isMax);
+    static MMinMax *New(TempAllocator &alloc, MDefinition *left, MDefinition *right, MIRType type,
+                        bool isMax)
+    {
+        return new(alloc) MMinMax(left, right, type, isMax);
     }
 
     bool isMax() const {
         return isMax_;
     }
     MIRType specialization() const {
         return specialization_;
     }
@@ -3465,21 +3497,21 @@ class MAbs
         JS_ASSERT(IsNumberType(type));
         setResultType(type);
         setMovable();
         specialization_ = type;
     }
 
   public:
     INSTRUCTION_HEADER(Abs)
-    static MAbs *New(MDefinition *num, MIRType type) {
-        return new MAbs(num, type);
-    }
-    static MAbs *NewAsmJS(MDefinition *num, MIRType type) {
-        MAbs *ins = new MAbs(num, type);
+    static MAbs *New(TempAllocator &alloc, MDefinition *num, MIRType type) {
+        return new(alloc) MAbs(num, type);
+    }
+    static MAbs *NewAsmJS(TempAllocator &alloc, MDefinition *num, MIRType type) {
+        MAbs *ins = new(alloc) MAbs(num, type);
         if (type == MIRType_Int32)
             ins->implicitTruncate_ = true;
         return ins;
     }
     MDefinition *num() const {
         return getOperand(0);
     }
     TypePolicy *typePolicy() {
@@ -3490,17 +3522,17 @@ class MAbs
     }
     bool fallible() const;
 
     AliasSet getAliasSet() const {
         return AliasSet::None();
     }
     void computeRange();
     bool isFloat32Commutative() const { return true; }
-    void trySpecializeFloat32();
+    void trySpecializeFloat32(TempAllocator &alloc);
 };
 
 // Inline implementation of Math.sqrt().
 class MSqrt
   : public MUnaryInstruction,
     public FloatingPointPolicy<0>
 {
     MSqrt(MDefinition *num, MIRType type)
@@ -3508,22 +3540,22 @@ class MSqrt
     {
         setResultType(type);
         setPolicyType(type);
         setMovable();
     }
 
   public:
     INSTRUCTION_HEADER(Sqrt)
-    static MSqrt *New(MDefinition *num) {
-        return new MSqrt(num, MIRType_Double);
-    }
-    static MSqrt *NewAsmJS(MDefinition *num, MIRType type) {
+    static MSqrt *New(TempAllocator &alloc, MDefinition *num) {
+        return new(alloc) MSqrt(num, MIRType_Double);
+    }
+    static MSqrt *NewAsmJS(TempAllocator &alloc, MDefinition *num, MIRType type) {
         JS_ASSERT(IsFloatingPointType(type));
-        return new MSqrt(num, type);
+        return new(alloc) MSqrt(num, type);
     }
     MDefinition *num() const {
         return getOperand(0);
     }
     TypePolicy *typePolicy() {
         return this;
     }
     bool congruentTo(MDefinition *ins) const {
@@ -3531,35 +3563,35 @@ class MSqrt
     }
 
     AliasSet getAliasSet() const {
         return AliasSet::None();
     }
     void computeRange();
 
     bool isFloat32Commutative() const { return true; }
-    void trySpecializeFloat32();
+    void trySpecializeFloat32(TempAllocator &alloc);
 };
 
 // Inline implementation of atan2 (arctangent of y/x).
 class MAtan2
   : public MBinaryInstruction,
     public MixPolicy<DoublePolicy<0>, DoublePolicy<1> >
 {
     MAtan2(MDefinition *y, MDefinition *x)
       : MBinaryInstruction(y, x)
     {
         setResultType(MIRType_Double);
         setMovable();
     }
 
   public:
     INSTRUCTION_HEADER(Atan2)
-    static MAtan2 *New(MDefinition *y, MDefinition *x) {
-        return new MAtan2(y, x);
+    static MAtan2 *New(TempAllocator &alloc, MDefinition *y, MDefinition *x) {
+        return new(alloc) MAtan2(y, x);
     }
 
     MDefinition *y() const {
         return getOperand(0);
     }
 
     MDefinition *x() const {
         return getOperand(1);
@@ -3591,18 +3623,18 @@ class MHypot
       : MBinaryInstruction(x, y)
     {
         setResultType(MIRType_Double);
         setMovable();
     }
 
   public:
     INSTRUCTION_HEADER(Hypot)
-    static MHypot *New(MDefinition *x, MDefinition *y) {
-        return new MHypot(y, x);
+    static MHypot *New(TempAllocator &alloc, MDefinition *x, MDefinition *y) {
+        return new(alloc) MHypot(y, x);
     }
 
     MDefinition *x() const {
         return getOperand(0);
     }
 
     MDefinition *y() const {
         return getOperand(1);
@@ -3635,18 +3667,20 @@ class MPow
         PowPolicy(powerType)
     {
         setResultType(MIRType_Double);
         setMovable();
     }
 
   public:
     INSTRUCTION_HEADER(Pow)
-    static MPow *New(MDefinition *input, MDefinition *power, MIRType powerType) {
-        return new MPow(input, power, powerType);
+    static MPow *New(TempAllocator &alloc, MDefinition *input, MDefinition *power,
+                     MIRType powerType)
+    {
+        return new(alloc) MPow(input, power, powerType);
     }
 
     MDefinition *input() const {
         return lhs();
     }
     MDefinition *power() const {
         return rhs();
     }
@@ -3680,18 +3714,18 @@ class MPowHalf
         operandIsNeverNaN_(false)
     {
         setResultType(MIRType_Double);
         setMovable();
     }
 
   public:
     INSTRUCTION_HEADER(PowHalf)
-    static MPowHalf *New(MDefinition *input) {
-        return new MPowHalf(input);
+    static MPowHalf *New(TempAllocator &alloc, MDefinition *input) {
+        return new(alloc) MPowHalf(input);
     }
     bool congruentTo(MDefinition *ins) const {
         return congruentIfOperandsEqual(ins);
     }
     bool operandIsNeverNegativeInfinity() const {
         return operandIsNeverNegativeInfinity_;
     }
     bool operandIsNeverNegativeZero() const {
@@ -3714,18 +3748,18 @@ class MRandom : public MNullaryInstructi
 {
     MRandom()
     {
         setResultType(MIRType_Double);
     }
 
   public:
     INSTRUCTION_HEADER(Random)
-    static MRandom *New() {
-        return new MRandom;
+    static MRandom *New(TempAllocator &alloc) {
+        return new(alloc) MRandom;
     }
 
     AliasSet getAliasSet() const {
         return AliasSet::None();
     }
 
     bool possiblyCalls() const {
         return true;
@@ -3776,18 +3810,20 @@ class MMathFunction
         setPolicyType(MIRType_Double);
         setMovable();
     }
 
   public:
     INSTRUCTION_HEADER(MathFunction)
 
     // A nullptr cache means this function will neither access nor update the cache.
-    static MMathFunction *New(MDefinition *input, Function function, MathCache *cache) {
-        return new MMathFunction(input, function, cache);
+    static MMathFunction *New(TempAllocator &alloc, MDefinition *input, Function function,
+                              MathCache *cache)
+    {
+        return new(alloc) MMathFunction(input, function, cache);
     }
     Function function() const {
         return function_;
     }
     MathCache *cache() const {
         return cache_;
     }
     TypePolicy *typePolicy() {
@@ -3813,37 +3849,39 @@ class MMathFunction
 
     static const char *FunctionName(Function function);
 
     bool isFloat32Commutative() const {
         return function_ == Log || function_ == Sin || function_ == Cos
                || function_ == Exp || function_ == Tan || function_ == ATan
                || function_ == ASin || function_ == ACos || function_ == Floor;
     }
-    void trySpecializeFloat32();
+    void trySpecializeFloat32(TempAllocator &alloc);
     void computeRange();
 };
 
 class MAdd : public MBinaryArithInstruction
 {
     // Is this instruction really an int at heart?
     MAdd(MDefinition *left, MDefinition *right)
       : MBinaryArithInstruction(left, right)
     {
         setResultType(MIRType_Value);
     }
 
   public:
     INSTRUCTION_HEADER(Add)
-    static MAdd *New(MDefinition *left, MDefinition *right) {
-        return new MAdd(left, right);
-    }
-
-    static MAdd *NewAsmJS(MDefinition *left, MDefinition *right, MIRType type) {
-        MAdd *add = new MAdd(left, right);
+    static MAdd *New(TempAllocator &alloc, MDefinition *left, MDefinition *right) {
+        return new(alloc) MAdd(left, right);
+    }
+
+    static MAdd *NewAsmJS(TempAllocator &alloc, MDefinition *left, MDefinition *right,
+                          MIRType type)
+    {
+        MAdd *add = new(alloc) MAdd(left, right);
         add->specialization_ = type;
         add->setResultType(type);
         if (type == MIRType_Int32) {
             add->setTruncated(true);
             add->setCommutative();
         }
         return add;
     }
@@ -3865,21 +3903,23 @@ class MSub : public MBinaryArithInstruct
     MSub(MDefinition *left, MDefinition *right)
       : MBinaryArithInstruction(left, right)
     {
         setResultType(MIRType_Value);
     }
 
   public:
     INSTRUCTION_HEADER(Sub)
-    static MSub *New(MDefinition *left, MDefinition *right) {
-        return new MSub(left, right);
-    }
-    static MSub *NewAsmJS(MDefinition *left, MDefinition *right, MIRType type) {
-        MSub *sub = new MSub(left, right);
+    static MSub *New(TempAllocator &alloc, MDefinition *left, MDefinition *right) {
+        return new(alloc) MSub(left, right);
+    }
+    static MSub *NewAsmJS(TempAllocator &alloc, MDefinition *left, MDefinition *right,
+                          MIRType type)
+    {
+        MSub *sub = new(alloc) MSub(left, right);
         sub->specialization_ = type;
         sub->setResultType(type);
         if (type == MIRType_Int32)
             sub->setTruncated(true);
         return sub;
     }
 
     double getIdentity() {
@@ -3925,24 +3965,26 @@ class MMul : public MBinaryArithInstruct
 
         if (type != MIRType_Value)
             specialization_ = type;
         setResultType(type);
     }
 
   public:
     INSTRUCTION_HEADER(Mul)
-    static MMul *New(MDefinition *left, MDefinition *right) {
-        return new MMul(left, right, MIRType_Value, MMul::Normal);
-    }
-    static MMul *New(MDefinition *left, MDefinition *right, MIRType type, Mode mode = Normal) {
-        return new MMul(left, right, type, mode);
-    }
-
-    MDefinition *foldsTo(bool useValueNumbers);
+    static MMul *New(TempAllocator &alloc, MDefinition *left, MDefinition *right) {
+        return new(alloc) MMul(left, right, MIRType_Value, MMul::Normal);
+    }
+    static MMul *New(TempAllocator &alloc, MDefinition *left, MDefinition *right, MIRType type,
+                     Mode mode = Normal)
+    {
+        return new(alloc) MMul(left, right, type, mode);
+    }
+
+    MDefinition *foldsTo(TempAllocator &alloc, bool useValueNumbers);
     void analyzeEdgeCasesForward();
     void analyzeEdgeCasesBackward();
 
     double getIdentity() {
         return 1;
     }
 
     bool canOverflow();
@@ -3985,30 +4027,32 @@ class MDiv : public MBinaryArithInstruct
     {
         if (type != MIRType_Value)
             specialization_ = type;
         setResultType(type);
     }
 
   public:
     INSTRUCTION_HEADER(Div)
-    static MDiv *New(MDefinition *left, MDefinition *right) {
-        return new MDiv(left, right, MIRType_Value);
-    }
-    static MDiv *New(MDefinition *left, MDefinition *right, MIRType type) {
-        return new MDiv(left, right, type);
-    }
-    static MDiv *NewAsmJS(MDefinition *left, MDefinition *right, MIRType type) {
-        MDiv *div = new MDiv(left, right, type);
+    static MDiv *New(TempAllocator &alloc, MDefinition *left, MDefinition *right) {
+        return new(alloc) MDiv(left, right, MIRType_Value);
+    }
+    static MDiv *New(TempAllocator &alloc, MDefinition *left, MDefinition *right, MIRType type) {
+        return new(alloc) MDiv(left, right, type);
+    }
+    static MDiv *NewAsmJS(TempAllocator &alloc, MDefinition *left, MDefinition *right,
+                          MIRType type)
+    {
+        MDiv *div = new(alloc) MDiv(left, right, type);
         if (type == MIRType_Int32)
             div->setTruncated(true);
         return div;
     }
 
-    MDefinition *foldsTo(bool useValueNumbers);
+    MDefinition *foldsTo(TempAllocator &alloc, bool useValueNumbers);
     void analyzeEdgeCasesForward();
     void analyzeEdgeCasesBackward();
 
     double getIdentity() {
         MOZ_ASSUME_UNREACHABLE("not used");
     }
 
     bool canBeNegativeZero() {
@@ -4049,27 +4093,29 @@ class MMod : public MBinaryArithInstruct
     {
         if (type != MIRType_Value)
             specialization_ = type;
         setResultType(type);
     }
 
   public:
     INSTRUCTION_HEADER(Mod)
-    static MMod *New(MDefinition *left, MDefinition *right) {
-        return new MMod(left, right, MIRType_Value);
-    }
-    static MMod *NewAsmJS(MDefinition *left, MDefinition *right, MIRType type) {
-        MMod *mod = new MMod(left, right, type);
+    static MMod *New(TempAllocator &alloc, MDefinition *left, MDefinition *right) {
+        return new(alloc) MMod(left, right, MIRType_Value);
+    }
+    static MMod *NewAsmJS(TempAllocator &alloc, MDefinition *left, MDefinition *right,
+                          MIRType type)
+    {
+        MMod *mod = new(alloc) MMod(left, right, type);
         if (type == MIRType_Int32)
             mod->setTruncated(true);
         return mod;
     }
 
-    MDefinition *foldsTo(bool useValueNumbers);
+    MDefinition *foldsTo(TempAllocator &alloc, bool useValueNumbers);
 
     double getIdentity() {
         MOZ_ASSUME_UNREACHABLE("not used");
     }
 
     bool canBeNegativeDividend() const {
         JS_ASSERT(specialization_ == MIRType_Int32);
         return canBeNegativeDividend_;
@@ -4096,18 +4142,18 @@ class MConcat
       : MBinaryInstruction(left, right)
     {
         setMovable();
         setResultType(MIRType_String);
     }
 
   public:
     INSTRUCTION_HEADER(Concat)
-    static MConcat *New(MDefinition *left, MDefinition *right) {
-        return new MConcat(left, right);
+    static MConcat *New(TempAllocator &alloc, MDefinition *left, MDefinition *right) {
+        return new(alloc) MConcat(left, right);
     }
 
     TypePolicy *typePolicy() {
         return this;
     }
     bool congruentTo(MDefinition *ins) const {
         return congruentIfOperandsEqual(ins);
     }
@@ -4125,18 +4171,18 @@ class MConcatPar
     {
         setMovable();
         setResultType(MIRType_String);
     }
 
   public:
     INSTRUCTION_HEADER(ConcatPar)
 
-    static MConcatPar *New(MDefinition *slice, MConcat *concat) {
-        return new MConcatPar(slice, concat->lhs(), concat->rhs());
+    static MConcatPar *New(TempAllocator &alloc, MDefinition *slice, MConcat *concat) {
+        return new(alloc) MConcatPar(slice, concat->lhs(), concat->rhs());
     }
 
     MDefinition *forkJoinSlice() const {
         return getOperand(0);
     }
     MDefinition *lhs() const {
         return getOperand(1);
     }
@@ -4164,18 +4210,18 @@ class MCharCodeAt
     {
         setMovable();
         setResultType(MIRType_Int32);
     }
 
   public:
     INSTRUCTION_HEADER(CharCodeAt)
 
-    static MCharCodeAt *New(MDefinition *str, MDefinition *index) {
-        return new MCharCodeAt(str, index);
+    static MCharCodeAt *New(TempAllocator &alloc, MDefinition *str, MDefinition *index) {
+        return new(alloc) MCharCodeAt(str, index);
     }
 
     TypePolicy *typePolicy() {
         return this;
     }
 
     virtual AliasSet getAliasSet() const {
         // Strings are immutable, so there is no implicit dependency.
@@ -4194,18 +4240,18 @@ class MFromCharCode
     {
         setMovable();
         setResultType(MIRType_String);
     }
 
   public:
     INSTRUCTION_HEADER(FromCharCode)
 
-    static MFromCharCode *New(MDefinition *code) {
-        return new MFromCharCode(code);
+    static MFromCharCode *New(TempAllocator &alloc, MDefinition *code) {
+        return new(alloc) MFromCharCode(code);
     }
 
     virtual AliasSet getAliasSet() const {
         return AliasSet::None();
     }
 };
 
 class MStringSplit
@@ -4220,18 +4266,20 @@ class MStringSplit
     {
         setResultType(MIRType_Object);
         setResultTypeSet(MakeSingletonTypeSet(templateObject));
     }
 
   public:
     INSTRUCTION_HEADER(StringSplit)
 
-    static MStringSplit *New(MDefinition *string, MDefinition *sep, JSObject *templateObject) {
-        return new MStringSplit(string, sep, templateObject);
+    static MStringSplit *New(TempAllocator &alloc, MDefinition *string, MDefinition *sep,
+                             JSObject *templateObject)
+    {
+        return new(alloc) MStringSplit(string, sep, templateObject);
     }
     types::TypeObject *typeObject() const {
         return typeObject_;
     }
     MDefinition *string() const {
         return getOperand(0);
     }
     MDefinition *separator() const {
@@ -4260,18 +4308,18 @@ class MComputeThis
       : MUnaryInstruction(def)
     {
         setResultType(MIRType_Object);
     }
 
   public:
     INSTRUCTION_HEADER(ComputeThis)
 
-    static MComputeThis *New(MDefinition *def) {
-        return new MComputeThis(def);
+    static MComputeThis *New(TempAllocator &alloc, MDefinition *def) {
+        return new(alloc) MComputeThis(def);
     }
 
     MDefinition *input() const {
         return getOperand(0);
     }
     TypePolicy *typePolicy() {
         return this;
     }
@@ -4316,18 +4364,18 @@ class MPhi MOZ_FINAL : public MDefinitio
 
   protected:
     MUse *getUseFor(size_t index) {
         return &inputs_[index];
     }
 
   public:
     INSTRUCTION_HEADER(Phi)
-    static MPhi *New(uint32_t slot, MIRType resultType = MIRType_Value) {
-        return new MPhi(slot, resultType);
+    static MPhi *New(TempAllocator &alloc, uint32_t slot, MIRType resultType = MIRType_Value) {
+        return new(alloc) MPhi(slot, resultType);
     }
 
     void setOperand(size_t index, MDefinition *operand) {
         // Note: after the initial IonBuilder pass, it is OK to change phi
         // operands such that they do not include the type sets of their
         // operands. This can arise during e.g. value numbering, where
         // definitions producing the same value may have different type sets.
         JS_ASSERT(index < numOperands());
@@ -4371,17 +4419,17 @@ class MPhi MOZ_FINAL : public MDefinitio
 
     // Use only if capacity has been reserved by reserveLength
     void addInput(MDefinition *ins);
 
     // Appends a new input to the input vector. May call realloc_().
     // Prefer reserveLength() and addInput() instead, where possible.
     bool addInputSlow(MDefinition *ins, bool *ptypeChange = nullptr);
 
-    MDefinition *foldsTo(bool useValueNumbers);
+    MDefinition *foldsTo(TempAllocator &alloc, bool useValueNumbers);
 
     bool congruentTo(MDefinition *ins) const;
 
     bool isIterator() const {
         return isIterator_;
     }
     void setIterator() {
         isIterator_ = true;
@@ -4438,19 +4486,19 @@ class MBeta : public MUnaryInstruction
     {
         setResultType(val->type());
         setResultTypeSet(val->resultTypeSet());
     }
 
   public:
     INSTRUCTION_HEADER(Beta)
     void printOpcode(FILE *fp) const;
-    static MBeta *New(MDefinition *val, const Range *comp)
-    {
-        return new MBeta(val, comp);
+    static MBeta *New(TempAllocator &alloc, MDefinition *val, const Range *comp)
+    {
+        return new(alloc) MBeta(val, comp);
     }
 
     AliasSet getAliasSet() const {
         return AliasSet::None();
     }
 
     void computeRange();
 };
@@ -4466,18 +4514,18 @@ class MOsrValue : public MUnaryInstructi
       : MUnaryInstruction(entry),
         frameOffset_(frameOffset)
     {
         setResultType(MIRType_Value);
     }
 
   public:
     INSTRUCTION_HEADER(OsrValue)
-    static MOsrValue *New(MOsrEntry *entry, ptrdiff_t frameOffset) {
-        return new MOsrValue(entry, frameOffset);
+    static MOsrValue *New(TempAllocator &alloc, MOsrEntry *entry, ptrdiff_t frameOffset) {
+        return new(alloc) MOsrValue(entry, frameOffset);
     }
 
     ptrdiff_t frameOffset() const {
         return frameOffset_;
     }
 
     MOsrEntry *entry() {
         return getOperand(0)->toOsrEntry();
@@ -4496,18 +4544,18 @@ class MOsrScopeChain : public MUnaryInst
     MOsrScopeChain(MOsrEntry *entry)
       : MUnaryInstruction(entry)
     {
         setResultType(MIRType_Object);
     }
 
   public:
     INSTRUCTION_HEADER(OsrScopeChain)
-    static MOsrScopeChain *New(MOsrEntry *entry) {
-        return new MOsrScopeChain(entry);
+    static MOsrScopeChain *New(TempAllocator &alloc, MOsrEntry *entry) {
+        return new(alloc) MOsrScopeChain(entry);
     }
 
     MOsrEntry *entry() {
         return getOperand(0)->toOsrEntry();
     }
 };
 
 // MIR representation of a JSObject ArgumentsObject pointer on the OSR StackFrame.
@@ -4518,18 +4566,18 @@ class MOsrArgumentsObject : public MUnar
     MOsrArgumentsObject(MOsrEntry *entry)
       : MUnaryInstruction(entry)
     {
         setResultType(MIRType_Object);
     }
 
   public:
     INSTRUCTION_HEADER(OsrArgumentsObject)
-    static MOsrArgumentsObject *New(MOsrEntry *entry) {
-        return new MOsrArgumentsObject(entry);
+    static MOsrArgumentsObject *New(TempAllocator &alloc, MOsrEntry *entry) {
+        return new(alloc) MOsrArgumentsObject(entry);
     }
 
     MOsrEntry *entry() {
         return getOperand(0)->toOsrEntry();
     }
 };
 
 // MIR representation of the return value on the OSR StackFrame.
@@ -4540,18 +4588,18 @@ class MOsrReturnValue : public MUnaryIns
     MOsrReturnValue(MOsrEntry *entry)
       : MUnaryInstruction(entry)
     {
         setResultType(MIRType_Value);
     }
 
   public:
     INSTRUCTION_HEADER(OsrReturnValue)
-    static MOsrReturnValue *New(MOsrEntry *entry) {
-        return new MOsrReturnValue(entry);
+    static MOsrReturnValue *New(TempAllocator &alloc, MOsrEntry *entry) {
+        return new(alloc) MOsrReturnValue(entry);
     }
 
     MOsrEntry *entry() {
         return getOperand(0)->toOsrEntry();
     }
 };
 
 // Check the current frame for over-recursion past the global stack limit.
@@ -4605,18 +4653,18 @@ class MInterruptCheck : public MNullaryI
 {
     MInterruptCheck() {
         setGuard();
     }
 
   public:
     INSTRUCTION_HEADER(InterruptCheck)
 
-    static MInterruptCheck *New() {
-        return new MInterruptCheck();
+    static MInterruptCheck *New(TempAllocator &alloc) {
+        return new(alloc) MInterruptCheck();
     }
     AliasSet getAliasSet() const {
         return AliasSet::None();
     }
 };
 
 // If not defined, set a global variable to |undefined|.
 class MDefVar : public MUnaryInstruction
@@ -4630,18 +4678,20 @@ class MDefVar : public MUnaryInstruction
         name_(name),
         attrs_(attrs)
     {
     }
 
   public:
     INSTRUCTION_HEADER(DefVar)
 
-    static MDefVar *New(PropertyName *name, unsigned attrs, MDefinition *scopeChain) {
-        return new MDefVar(name, attrs, scopeChain);
+    static MDefVar *New(TempAllocator &alloc, PropertyName *name, unsigned attrs,
+                        MDefinition *scopeChain)
+    {
+        return new(alloc) MDefVar(name, attrs, scopeChain);
     }
 
     PropertyName *name() const {
         return name_;
     }
     unsigned attrs() const {
         return attrs_;
     }
@@ -4661,18 +4711,18 @@ class MDefFun : public MUnaryInstruction
     MDefFun(JSFunction *fun, MDefinition *scopeChain)
       : MUnaryInstruction(scopeChain),
         fun_(fun)
     {}
 
   public:
     INSTRUCTION_HEADER(DefFun)
 
-    static MDefFun *New(JSFunction *fun, MDefinition *scopeChain) {
-        return new MDefFun(fun, scopeChain);
+    static MDefFun *New(TempAllocator &alloc, JSFunction *fun, MDefinition *scopeChain) {
+        return new(alloc) MDefFun(fun, scopeChain);
     }
 
     JSFunction *fun() const {
         return fun_;
     }
     MDefinition *scopeChain() const {
         return getOperand(0);
     }
@@ -4696,18 +4746,20 @@ class MRegExp : public MNullaryInstructi
 
         JS_ASSERT(source->getProto() == prototype);
         setResultTypeSet(MakeSingletonTypeSet(source));
     }
 
   public:
     INSTRUCTION_HEADER(RegExp)
 
-    static MRegExp *New(RegExpObject *source, JSObject *prototype, bool mustClone) {
-        return new MRegExp(source, prototype, mustClone);
+    static MRegExp *New(TempAllocator &alloc, RegExpObject *source, JSObject *prototype,
+                        bool mustClone)
+    {
+        return new(alloc) MRegExp(source, prototype, mustClone);
     }
 
     bool mustClone() const {
         return mustClone_;
     }
     RegExpObject *source() const {
         return source_;
     }
@@ -4732,18 +4784,18 @@ class MRegExpTest
       : MBinaryInstruction(string, regexp)
     {
         setResultType(MIRType_Boolean);
     }
 
   public:
     INSTRUCTION_HEADER(RegExpTest)
 
-    static MRegExpTest *New(MDefinition *regexp, MDefinition *string) {
-        return new MRegExpTest(regexp, string);
+    static MRegExpTest *New(TempAllocator &alloc, MDefinition *regexp, MDefinition *string) {
+        return new(alloc) MRegExpTest(regexp, string);
     }
 
     MDefinition *string() const {
         return getOperand(0);
     }
     MDefinition *regexp() const {
         return getOperand(1);
     }
@@ -4797,18 +4849,18 @@ class MLambda
         setResultType(MIRType_Object);
         if (!fun->hasSingletonType() && !types::UseNewTypeForClone(fun))
             setResultTypeSet(MakeSingletonTypeSet(fun));
     }
 
   public:
     INSTRUCTION_HEADER(Lambda)
 
-    static MLambda *New(MDefinition *scopeChain, JSFunction *fun) {
-        return new MLambda(scopeChain, fun);
+    static MLambda *New(TempAllocator &alloc, MDefinition *scopeChain, JSFunction *fun) {
+        return new(alloc) MLambda(scopeChain, fun);
     }
     MDefinition *scopeChain() const {
         return getOperand(0);
     }
     const LambdaFunctionInfo &info() const {
         return info_;
     }
     TypePolicy *typePolicy() {
@@ -4830,19 +4882,19 @@ class MLambdaPar
         JS_ASSERT(!info_.useNewTypeForClone);
         setResultType(MIRType_Object);
         setResultTypeSet(resultTypes);
     }
 
   public:
     INSTRUCTION_HEADER(LambdaPar);
 
-    static MLambdaPar *New(MDefinition *slice, MLambda *lambda) {
-        return new MLambdaPar(slice, lambda->scopeChain(), lambda->info().fun,
-                              lambda->resultTypeSet(), lambda->info());
+    static MLambdaPar *New(TempAllocator &alloc, MDefinition *slice, MLambda *lambda) {
+        return new(alloc) MLambdaPar(slice, lambda->scopeChain(), lambda->info().fun,
+                                     lambda->resultTypeSet(), lambda->info());
     }
 
     MDefinition *forkJoinSlice() const {
         return getOperand(0);
     }
 
     MDefinition *scopeChain() const {
         return getOperand(1);
@@ -4863,18 +4915,18 @@ class MImplicitThis
     {
         setResultType(MIRType_Value);
         setMovable();
     }
 
   public:
     INSTRUCTION_HEADER(ImplicitThis)
 
-    static MImplicitThis *New(MDefinition *callee) {
-        return new MImplicitThis(callee);
+    static MImplicitThis *New(TempAllocator &alloc, MDefinition *callee) {
+        return new(alloc) MImplicitThis(callee);
     }
 
     TypePolicy *typePolicy() {
         return this;
     }
     MDefinition *callee() const {
         return getOperand(0);
     }
@@ -4893,18 +4945,18 @@ class MSlots
     {
         setResultType(MIRType_Slots);
         setMovable();
     }
 
   public:
     INSTRUCTION_HEADER(Slots)
 
-    static MSlots *New(MDefinition *object) {
-        return new MSlots(object);
+    static MSlots *New(TempAllocator &alloc, MDefinition *object) {
+        return new(alloc) MSlots(object);
     }
 
     TypePolicy *typePolicy() {
         return this;
     }
     MDefinition *object() const {
         return getOperand(0);
     }
@@ -4926,18 +4978,18 @@ class MElements
     {
         setResultType(MIRType_Elements);
         setMovable();
     }
 
   public:
     INSTRUCTION_HEADER(Elements)
 
-    static MElements *New(MDefinition *object) {
-        return new MElements(object);
+    static MElements *New(TempAllocator &alloc, MDefinition *object) {
+        return new(alloc) MElements(object);
     }
 
     TypePolicy *typePolicy() {
         return this;
     }
     MDefinition *object() const {
         return getOperand(0);
     }
@@ -4959,18 +5011,18 @@ class MConstantElements : public MNullar
       : value_(v)
     {
         setResultType(MIRType_Elements);
         setMovable();
     }
 
   public:
     INSTRUCTION_HEADER(ConstantElements)
-    static MConstantElements *New(void *v) {
-        return new MConstantElements(v);
+    static MConstantElements *New(TempAllocator &alloc, void *v) {
+        return new(alloc) MConstantElements(v);
     }
 
     void *value() const {
         return value_;
     }
 
     void printOpcode(FILE *fp) const;
 
@@ -4997,18 +5049,18 @@ class MConvertElementsToDoubles
         setGuard();
         setMovable();
         setResultType(MIRType_Elements);
     }
 
   public:
     INSTRUCTION_HEADER(ConvertElementsToDoubles)
 
-    static MConvertElementsToDoubles *New(MDefinition *elements) {
-        return new MConvertElementsToDoubles(elements);
+    static MConvertElementsToDoubles *New(TempAllocator &alloc, MDefinition *elements) {
+        return new(alloc) MConvertElementsToDoubles(elements);
     }
 
     MDefinition *elements() const {
         return getOperand(0);
     }
     bool congruentTo(MDefinition *ins) const {
         return congruentIfOperandsEqual(ins);
     }
@@ -5036,18 +5088,20 @@ class MMaybeToDoubleElement
         JS_ASSERT(elements->type() == MIRType_Elements);
         setMovable();
         setResultType(MIRType_Value);
     }
 
   public:
     INSTRUCTION_HEADER(MaybeToDoubleElement)
 
-    static MMaybeToDoubleElement *New(MDefinition *elements, MDefinition *value) {
-        return new MMaybeToDoubleElement(elements, value);
+    static MMaybeToDoubleElement *New(TempAllocator &alloc, MDefinition *elements,
+                                      MDefinition *value)
+    {
+        return new(alloc) MMaybeToDoubleElement(elements, value);
     }
 
     TypePolicy *typePolicy() {
         return this;
     }
 
     MDefinition *elements() const {
         return getOperand(0);
@@ -5072,18 +5126,18 @@ class MInitializedLength
     {
         setResultType(MIRType_Int32);
         setMovable();
     }
 
   public:
     INSTRUCTION_HEADER(InitializedLength)
 
-    static MInitializedLength *New(MDefinition *elements) {
-        return new MInitializedLength(elements);
+    static MInitializedLength *New(TempAllocator &alloc, MDefinition *elements) {
+        return new(alloc) MInitializedLength(elements);
     }
 
     MDefinition *elements() const {
         return getOperand(0);
     }
     bool congruentTo(MDefinition *ins) const {
         return congruentIfOperandsEqual(ins);
     }
@@ -5102,18 +5156,18 @@ class MSetInitializedLength
     {
         setOperand(0, elements);
         setOperand(1, index);
     }
 
   public:
     INSTRUCTION_HEADER(SetInitializedLength)
 
-    static MSetInitializedLength *New(MDefinition *elements, MDefinition *index) {
-        return new MSetInitializedLength(elements, index);
+    static MSetInitializedLength *New(TempAllocator &alloc, MDefinition *elements, MDefinition *index) {
+        return new(alloc) MSetInitializedLength(elements, index);
     }
 
     MDefinition *elements() const {
         return getOperand(0);
     }
     MDefinition *index() const {
         return getOperand(1);
     }
@@ -5159,18 +5213,18 @@ class MTypedArrayLength
     {
         setResultType(MIRType_Int32);
         setMovable();
     }
 
   public:
     INSTRUCTION_HEADER(TypedArrayLength)
 
-    static MTypedArrayLength *New(MDefinition *obj) {
-        return new MTypedArrayLength(obj);
+    static MTypedArrayLength *New(TempAllocator &alloc, MDefinition *obj) {
+        return new(alloc) MTypedArrayLength(obj);
     }
 
     TypePolicy *typePolicy() {
         return this;
     }
     MDefinition *object() const {
         return getOperand(0);
     }
@@ -5196,18 +5250,18 @@ class MTypedArrayElements
     {
         setResultType(MIRType_Elements);
         setMovable();
     }
 
   public:
     INSTRUCTION_HEADER(TypedArrayElements)
 
-    static MTypedArrayElements *New(MDefinition *object) {
-        return new MTypedArrayElements(object);
+    static MTypedArrayElements *New(TempAllocator &alloc, MDefinition *object) {
+        return new(alloc) MTypedArrayElements(object);
     }
 
     TypePolicy *typePolicy() {
         return this;
     }
     MDefinition *object() const {
         return getOperand(0);
     }
@@ -5232,18 +5286,18 @@ class MTypedObjectElements
     {
         setResultType(MIRType_Elements);
         setMovable();
     }
 
   public:
     INSTRUCTION_HEADER(TypedObjectElements)
 
-    static MTypedObjectElements *New(MDefinition *object) {
-        return new MTypedObjectElements(object);
+    static MTypedObjectElements *New(TempAllocator &alloc, MDefinition *object) {
+        return new(alloc) MTypedObjectElements(object);
     }
 
     TypePolicy *typePolicy() {
         return this;
     }
     MDefinition *object() const {
         return getOperand(0);
     }
@@ -5268,29 +5322,29 @@ class MNot
       : MUnaryInstruction(input),
         operandMightEmulateUndefined_(true),
         operandIsNeverNaN_(false)
     {
         setResultType(MIRType_Boolean);
         setMovable();
     }
 
-    static MNot *New(MDefinition *elements) {
-        return new MNot(elements);
-    }
-    static MNot *NewAsmJS(MDefinition *elements) {
-        MNot *ins = new MNot(elements);
+    static MNot *New(TempAllocator &alloc, MDefinition *elements) {
+        return new(alloc) MNot(elements);
+    }
+    static MNot *NewAsmJS(TempAllocator &alloc, MDefinition *elements) {
+        MNot *ins = new(alloc) MNot(elements);
         ins->setResultType(MIRType_Int32);
         return ins;
     }
 
     INSTRUCTION_HEADER(Not);
 
     void infer();
-    MDefinition *foldsTo(bool useValueNumbers);
+    MDefinition *foldsTo(TempAllocator &alloc, bool useValueNumbers);
 
     void markOperandCantEmulateUndefined() {
         operandMightEmulateUndefined_ = false;
     }
     bool operandMightEmulateUndefined() const {
         return operandMightEmulateUndefined_;
     }
     bool operandIsNeverNaN() const {
@@ -5304,17 +5358,17 @@ class MNot
     virtual AliasSet getAliasSet() const {
         return AliasSet::None();
     }
     TypePolicy *typePolicy() {
         return this;
     }
     void collectRangeInfo();
 
-    void trySpecializeFloat32();
+    void trySpecializeFloat32(TempAllocator &alloc);
     bool isFloat32Commutative() const { return true; }
 #ifdef DEBUG
     bool isConsistentFloat32Use() const {
         return true;
     }
 #endif
 };
 
@@ -5338,18 +5392,18 @@ class MBoundsCheck
 
         // Returns the checked index.
         setResultType(MIRType_Int32);
     }
 
   public:
     INSTRUCTION_HEADER(BoundsCheck)
 
-    static MBoundsCheck *New(MDefinition *index, MDefinition *length) {
-        return new MBoundsCheck(index, length);
+    static MBoundsCheck *New(TempAllocator &alloc, MDefinition *index, MDefinition *length) {
+        return new(alloc) MBoundsCheck(index, length);
     }
     MDefinition *index() const {
         return getOperand(0);
     }
     MDefinition *length() const {
         return getOperand(1);
     }
     int32_t minimum() const {
@@ -5391,18 +5445,18 @@ class MBoundsCheckLower
         setGuard();
         setMovable();
         JS_ASSERT(index->type() == MIRType_Int32);
     }
 
   public:
     INSTRUCTION_HEADER(BoundsCheckLower)
 
-    static MBoundsCheckLower *New(MDefinition *index) {
-        return new MBoundsCheckLower(index);
+    static MBoundsCheckLower *New(TempAllocator &alloc, MDefinition *index) {
+        return new(alloc) MBoundsCheckLower(index);
     }
 
     MDefinition *index() const {
         return getOperand(0);
     }
     int32_t minimum() const {
         return minimum_;
     }
@@ -5436,19 +5490,19 @@ class MLoadElement
         setMovable();
         JS_ASSERT(elements->type() == MIRType_Elements);
         JS_ASSERT(index->type() == MIRType_Int32);
     }
 
   public:
     INSTRUCTION_HEADER(LoadElement)
 
-    static MLoadElement *New(MDefinition *elements, MDefinition *index,
+    static MLoadElement *New(TempAllocator &alloc, MDefinition *elements, MDefinition *index,
                              bool needsHoleCheck, bool loadDoubles) {
-        return new MLoadElement(elements, index, needsHoleCheck, loadDoubles);
+        return new(alloc) MLoadElement(elements, index, needsHoleCheck, loadDoubles);
     }
 
     TypePolicy *typePolicy() {
         return this;
     }
     MDefinition *elements() const {
         return getOperand(0);
     }
@@ -5489,19 +5543,19 @@ class MLoadElementHole
         JS_ASSERT(elements->type() == MIRType_Elements);
         JS_ASSERT(index->type() == MIRType_Int32);
         JS_ASSERT(initLength->type() == MIRType_Int32);
     }
 
   public:
     INSTRUCTION_HEADER(LoadElementHole)
 
-    static MLoadElementHole *New(MDefinition *elements, MDefinition *index,
+    static MLoadElementHole *New(TempAllocator &alloc, MDefinition *elements, MDefinition *index,
                                  MDefinition *initLength, bool needsHoleCheck) {
-        return new MLoadElementHole(elements, index, initLength, needsHoleCheck);
+        return new(alloc) MLoadElementHole(elements, index, initLength, needsHoleCheck);
     }
 
     TypePolicy *typePolicy() {
         return this;
     }
     MDefinition *elements() const {
         return getOperand(0);
     }
@@ -5573,19 +5627,19 @@ class MStoreElement
         needsHoleCheck_ = needsHoleCheck;
         JS_ASSERT(elements->type() == MIRType_Elements);
         JS_ASSERT(index->type() == MIRType_Int32);
     }
 
   public:
     INSTRUCTION_HEADER(StoreElement)
 
-    static MStoreElement *New(MDefinition *elements, MDefinition *index, MDefinition *value,
-                              bool needsHoleCheck) {
-        return new MStoreElement(elements, index, value, needsHoleCheck);
+    static MStoreElement *New(TempAllocator &alloc, MDefinition *elements, MDefinition *index,
+                              MDefinition *value, bool needsHoleCheck) {
+        return new(alloc) MStoreElement(elements, index, value, needsHoleCheck);
     }
     MDefinition *elements() const {
         return getOperand(0);
     }
     MDefinition *index() const {
         return getOperand(1);
     }
     MDefinition *value() const {
@@ -5622,19 +5676,19 @@ class MStoreElementHole
         setOperand(3, value);
         JS_ASSERT(elements->type() == MIRType_Elements);
         JS_ASSERT(index->type() == MIRType_Int32);
     }
 
   public:
     INSTRUCTION_HEADER(StoreElementHole)
 
-    static MStoreElementHole *New(MDefinition *object, MDefinition *elements,
+    static MStoreElementHole *New(TempAllocator &alloc, MDefinition *object, MDefinition *elements,
                                   MDefinition *index, MDefinition *value) {
-        return new MStoreElementHole(object, elements, index, value);
+        return new(alloc) MStoreElementHole(object, elements, index, value);
     }
 
     MDefinition *object() const {
         return getOperand(0);
     }
     MDefinition *elements() const {
         return getOperand(1);
     }
@@ -5673,19 +5727,20 @@ class MArrayPopShift
     MArrayPopShift(MDefinition *object, Mode mode, bool needsHoleCheck, bool maybeUndefined)
       : MUnaryInstruction(object), mode_(mode), needsHoleCheck_(needsHoleCheck),
         maybeUndefined_(maybeUndefined)
     { }
 
   public:
     INSTRUCTION_HEADER(ArrayPopShift)
 
-    static MArrayPopShift *New(MDefinition *object, Mode mode, bool needsHoleCheck,
-                               bool maybeUndefined) {
-        return new MArrayPopShift(object, mode, needsHoleCheck, maybeUndefined);
+    static MArrayPopShift *New(TempAllocator &alloc, MDefinition *object, Mode mode,
+                               bool needsHoleCheck, bool maybeUndefined)
+    {
+        return new(alloc) MArrayPopShift(object, mode, needsHoleCheck, maybeUndefined);
     }
 
     MDefinition *object() const {
         return getOperand(0);
     }
     bool needsHoleCheck() const {
         return needsHoleCheck_;
     }
@@ -5712,18 +5767,18 @@ class MArrayPush
       : MBinaryInstruction(object, value)
     {
         setResultType(MIRType_Int32);
     }
 
   public:
     INSTRUCTION_HEADER(ArrayPush)
 
-    static MArrayPush *New(MDefinition *object, MDefinition *value) {
-        return new MArrayPush(object, value);
+    static MArrayPush *New(TempAllocator &alloc, MDefinition *object, MDefinition *value) {
+        return new(alloc) MArrayPush(object, value);
     }
 
     MDefinition *object() const {
         return getOperand(0);
     }
     MDefinition *value() const {
         return getOperand(1);
     }
@@ -5749,18 +5804,20 @@ class MArrayConcat
     {
         setResultType(MIRType_Object);
         setResultTypeSet(MakeSingletonTypeSet(templateObj));
     }
 
   public:
     INSTRUCTION_HEADER(ArrayConcat)
 
-    static MArrayConcat *New(MDefinition *lhs, MDefinition *rhs, JSObject *templateObj) {
-        return new MArrayConcat(lhs, rhs, templateObj);
+    static MArrayConcat *New(TempAllocator &alloc, MDefinition *lhs, MDefinition *rhs,
+                             JSObject *templateObj)
+    {
+        return new(alloc) MArrayConcat(lhs, rhs, templateObj);
     }
 
     JSObject *templateObj() const {
         return templateObj_;
     }
     TypePolicy *typePolicy() {
         return this;
     }
@@ -5786,18 +5843,20 @@ class MLoadTypedArrayElement
         JS_ASSERT(elements->type() == MIRType_Elements);
         JS_ASSERT(index->type() == MIRType_Int32);
         JS_ASSERT(arrayType >= 0 && arrayType < ScalarTypeRepresentation::TYPE_MAX);
     }
 
   public:
     INSTRUCTION_HEADER(LoadTypedArrayElement)
 
-    static MLoadTypedArrayElement *New(MDefinition *elements, MDefinition *index, ScalarTypeRepresentation::Type arrayType) {
-        return new MLoadTypedArrayElement(elements, index, arrayType);
+    static MLoadTypedArrayElement *New(TempAllocator &alloc, MDefinition *elements, MDefinition *index,
+                                       ScalarTypeRepresentation::Type arrayType)
+    {
+        return new(alloc) MLoadTypedArrayElement(elements, index, arrayType);
     }
 
     ScalarTypeRepresentation::Type arrayType() const {
         return arrayType_;
     }
     bool fallible() const {
         // Bailout if the result does not fit in an int32.
         return arrayType_ == ScalarTypeRepresentation::TYPE_UINT32 && type() == MIRType_Int32;
@@ -5835,18 +5894,20 @@ class MLoadTypedArrayElementHole
         setMovable();
         JS_ASSERT(index->type() == MIRType_Int32);
         JS_ASSERT(arrayType >= 0 && arrayType < ScalarTypeRepresentation::TYPE_MAX);
     }
 
   public:
     INSTRUCTION_HEADER(LoadTypedArrayElementHole)
 
-    static MLoadTypedArrayElementHole *New(MDefinition *object, MDefinition *index, int arrayType, bool allowDouble) {
-        return new MLoadTypedArrayElementHole(object, index, arrayType, allowDouble);
+    static MLoadTypedArrayElementHole *New(TempAllocator &alloc, MDefinition *object, MDefinition *index,
+                                           int arrayType, bool allowDouble)
+    {
+        return new(alloc) MLoadTypedArrayElementHole(object, index, arrayType, allowDouble);
     }
 
     int arrayType() const {
         return arrayType_;
     }
     bool allowDouble() const {
         return allowDouble_;
     }
@@ -5886,18 +5947,20 @@ class MLoadTypedArrayElementStatic
     }
 
     CompilerRoot<TypedArrayObject*> typedArray_;
     bool fallible_;
 
   public:
     INSTRUCTION_HEADER(LoadTypedArrayElementStatic);
 
-    static MLoadTypedArrayElementStatic *New(TypedArrayObject *typedArray, MDefinition *ptr) {
-        return new MLoadTypedArrayElementStatic(typedArray, ptr);
+    static MLoadTypedArrayElementStatic *New(TempAllocator &alloc, TypedArrayObject *typedArray,
+                                             MDefinition *ptr)
+    {
+        return new(alloc) MLoadTypedArrayElementStatic(typedArray, ptr);
     }
 
     ArrayBufferView::ViewType viewType() const { return JS_GetArrayBufferViewType(typedArray_); }
     void *base() const;
     size_t length() const;
 
     MDefinition *ptr() const { return getOperand(0); }
     AliasSet getAliasSet() const {
@@ -5938,19 +6001,20 @@ class MStoreTypedArrayElement
         JS_ASSERT(elements->type() == MIRType_Elements);
         JS_ASSERT(index->type() == MIRType_Int32);
         JS_ASSERT(arrayType >= 0 && arrayType < ScalarTypeRepresentation::TYPE_MAX);
     }
 
   public:
     INSTRUCTION_HEADER(StoreTypedArrayElement)
 
-    static MStoreTypedArrayElement *New(MDefinition *elements, MDefinition *index, MDefinition *value,
-                                        int arrayType) {
-        return new MStoreTypedArrayElement(elements, index, value, arrayType);
+    static MStoreTypedArrayElement *New(TempAllocator &alloc, MDefinition *elements, MDefinition *index,
+                                        MDefinition *value, int arrayType)
+    {
+        return new(alloc) MStoreTypedArrayElement(elements, index, value, arrayType);
     }
 
     int arrayType() const {
         return arrayType_;
     }
     bool isByteArray() const {
         return (arrayType_ == ScalarTypeRepresentation::TYPE_INT8 ||
                 arrayType_ == ScalarTypeRepresentation::TYPE_UINT8 ||
@@ -6005,20 +6069,21 @@ class MStoreTypedArrayElementHole
         JS_ASSERT(length->type() == MIRType_Int32);
         JS_ASSERT(index->type() == MIRType_Int32);
         JS_ASSERT(arrayType >= 0 && arrayType < ScalarTypeRepresentation::TYPE_MAX);
     }
 
   public:
     INSTRUCTION_HEADER(StoreTypedArrayElementHole)
 
-    static MStoreTypedArrayElementHole *New(MDefinition *elements, MDefinition *length,
-                                            MDefinition *index, MDefinition *value, int arrayType)
-    {
-        return new MStoreTypedArrayElementHole(elements, length, index, value, arrayType);
+    static MStoreTypedArrayElementHole *New(TempAllocator &alloc, MDefinition *elements,
+                                            MDefinition *length, MDefinition *index,
+                                            MDefinition *value, int arrayType)
+    {
+        return new(alloc) MStoreTypedArrayElementHole(elements, length, index, value, arrayType);
     }
 
     int arrayType() const {
         return arrayType_;
     }
     bool isByteArray() const {
         return (arrayType_ == ScalarTypeRepresentation::TYPE_INT8 ||
                 arrayType_ == ScalarTypeRepresentation::TYPE_UINT8 ||
@@ -6060,20 +6125,20 @@ class MStoreTypedArrayElementStatic :
       : MBinaryInstruction(ptr, v), typedArray_(typedArray)
     {}
 
     CompilerRoot<TypedArrayObject*> typedArray_;
 
   public:
     INSTRUCTION_HEADER(StoreTypedArrayElementStatic);
 
-    static MStoreTypedArrayElementStatic *New(TypedArrayObject *typedArray, MDefinition *ptr,
-                                              MDefinition *v)
-    {
-        return new MStoreTypedArrayElementStatic(typedArray, ptr, v);
+    static MStoreTypedArrayElementStatic *New(TempAllocator &alloc, TypedArrayObject *typedArray,
+                                              MDefinition *ptr, MDefinition *v)
+    {
+        return new(alloc) MStoreTypedArrayElementStatic(typedArray, ptr, v);
     }
 
     TypePolicy *typePolicy() {
         return this;
     }
 
     ArrayBufferView::ViewType viewType() const { return JS_GetArrayBufferViewType(typedArray_); }
     bool isFloatArray() const {
@@ -6108,18 +6173,20 @@ class MEffectiveAddress : public MBinary
     }
 
     Scale scale_;
     int32_t displacement_;
 
   public:
     INSTRUCTION_HEADER(EffectiveAddress);
 
-    static MEffectiveAddress *New(MDefinition *base, MDefinition *index, Scale s, int32_t d) {
-        return new MEffectiveAddress(base, index, s, d);
+    static MEffectiveAddress *New(TempAllocator &alloc, MDefinition *base, MDefinition *index,
+                                  Scale s, int32_t d)
+    {
+        return new(alloc) MEffectiveAddress(base, index, s, d);
     }
     MDefinition *base() const {
         return lhs();
     }
     MDefinition *index() const {
         return rhs();
     }
     Scale scale() const {
@@ -6140,21 +6207,21 @@ class MClampToUint8
     {
         setResultType(MIRType_Int32);
         setMovable();
     }
 
   public:
     INSTRUCTION_HEADER(ClampToUint8)
 
-    static MClampToUint8 *New(MDefinition *input) {
-        return new MClampToUint8(input);
-    }
-
-    MDefinition *foldsTo(bool useValueNumbers);
+    static MClampToUint8 *New(TempAllocator &alloc, MDefinition *input) {
+        return new(alloc) MClampToUint8(input);
+    }
+
+    MDefinition *foldsTo(TempAllocator &alloc, bool useValueNumbers);
 
     TypePolicy *typePolicy() {
         return this;
     }
     bool congruentTo(MDefinition *ins) const {
         return congruentIfOperandsEqual(ins);
     }
     AliasSet getAliasSet() const {
@@ -6175,18 +6242,18 @@ class MLoadFixedSlot
     {
         setResultType(MIRType_Value);
         setMovable();
     }
 
   public:
     INSTRUCTION_HEADER(LoadFixedSlot)
 
-    static MLoadFixedSlot *New(MDefinition *obj, size_t slot) {
-        return new MLoadFixedSlot(obj, slot);
+    static MLoadFixedSlot *New(TempAllocator &alloc, MDefinition *obj, size_t slot) {
+        return new(alloc) MLoadFixedSlot(obj, slot);
     }
 
     TypePolicy *typePolicy() {
         return this;
     }
 
     MDefinition *object() const {
         return getOperand(0);
@@ -6220,21 +6287,25 @@ class MStoreFixedSlot
       : MBinaryInstruction(obj, rval),
         needsBarrier_(barrier),
         slot_(slot)
     { }
 
   public:
     INSTRUCTION_HEADER(StoreFixedSlot)
 
-    static MStoreFixedSlot *New(MDefinition *obj, size_t slot, MDefinition *rval) {
-        return new MStoreFixedSlot(obj, rval, slot, false);
-    }
-    static MStoreFixedSlot *NewBarriered(MDefinition *obj, size_t slot, MDefinition *rval) {
-        return new MStoreFixedSlot(obj, rval, slot, true);
+    static MStoreFixedSlot *New(TempAllocator &alloc, MDefinition *obj, size_t slot,
+                                MDefinition *rval)
+    {
+        return new(alloc) MStoreFixedSlot(obj, rval, slot, false);
+    }
+    static MStoreFixedSlot *NewBarriered(TempAllocator &alloc, MDefinition *obj, size_t slot,
+                                         MDefinition *rval)
+    {
+        return new(alloc) MStoreFixedSlot(obj, rval, slot, true);
     }
 
     TypePolicy *typePolicy() {
         return this;
     }
 
     MDefinition *object() const {
         return getOperand(0);
@@ -6288,18 +6359,18 @@ class InlinePropertyTable : public TempO
     MResumePoint *priorResumePoint() const {
         return priorResumePoint_;
     }
 
     jsbytecode *pc() const {
         return pc_;
     }
 
-    bool addEntry(types::TypeObject *typeObj, JSFunction *func) {
-        return entries_.append(new Entry(typeObj, func));
+    bool addEntry(TempAllocator &alloc, types::TypeObject *typeObj, JSFunction *func) {
+        return entries_.append(new(alloc) Entry(typeObj, func));
     }
 
     size_t numEntries() const {
         return entries_.length();
     }
 
     types::TypeObject *getTypeObject(size_t i) const {
         JS_ASSERT(i < numEntries());
@@ -6359,23 +6430,23 @@ class MGetPropertyCache
         // resolve hooks on the proto chain. setGuard ensures this check is not
         // eliminated.
         setGuard();
     }
 
   public:
     INSTRUCTION_HEADER(GetPropertyCache)
 
-    static MGetPropertyCache *New(MDefinition *obj, PropertyName *name) {
-        return new MGetPropertyCache(obj, name);
-    }
-
-    InlinePropertyTable *initInlinePropertyTable(jsbytecode *pc) {
+    static MGetPropertyCache *New(TempAllocator &alloc, MDefinition *obj, PropertyName *name) {
+        return new(alloc) MGetPropertyCache(obj, name);
+    }
+
+    InlinePropertyTable *initInlinePropertyTable(TempAllocator &alloc, jsbytecode *pc) {
         JS_ASSERT(inlinePropertyTable_ == nullptr);
-        inlinePropertyTable_ = new InlinePropertyTable(pc);
+        inlinePropertyTable_ = new(alloc) InlinePropertyTable(pc);
         return inlinePropertyTable_;
     }
 
     void clearInlinePropertyTable() {
         inlinePropertyTable_ = nullptr;
     }
 
     InlinePropertyTable *propTable() const {
@@ -6456,18 +6527,18 @@ class MGetPropertyPolymorphic
 
     PropertyName *name() const {
         return name_;
     }
 
   public:
     INSTRUCTION_HEADER(GetPropertyPolymorphic)
 
-    static MGetPropertyPolymorphic *New(MDefinition *obj, PropertyName *name) {
-        return new MGetPropertyPolymorphic(obj, name);
+    static MGetPropertyPolymorphic *New(TempAllocator &alloc, MDefinition *obj, PropertyName *name) {
+        return new(alloc) MGetPropertyPolymorphic(obj, name);
     }
 
     bool congruentTo(MDefinition *ins) const {
         if (!ins->isGetPropertyPolymorphic())
             return false;
         if (name() != ins->toGetPropertyPolymorphic()->name())
             return false;
         return congruentIfOperandsEqual(ins);
@@ -6522,18 +6593,18 @@ class MSetPropertyPolymorphic
       : MBinaryInstruction(obj, value),
         needsBarrier_(false)
     {
     }
 
   public:
     INSTRUCTION_HEADER(SetPropertyPolymorphic)
 
-    static MSetPropertyPolymorphic *New(MDefinition *obj, MDefinition *value) {
-        return new MSetPropertyPolymorphic(obj, value);
+    static MSetPropertyPolymorphic *New(TempAllocator &alloc, MDefinition *obj, MDefinition *value) {
+        return new(alloc) MSetPropertyPolymorphic(obj, value);
     }
 
     TypePolicy *typePolicy() {
         return this;
     }
     bool addShape(Shape *objShape, Shape *shape) {
         Entry entry;
         entry.objShape = objShape;
@@ -6675,18 +6746,20 @@ class MTypeObjectDispatch : public MDisp
     MTypeObjectDispatch(MDefinition *input, InlinePropertyTable *table)
       : MDispatchInstruction(input),
         inlinePropertyTable_(table)
     { }
 
   public:
     INSTRUCTION_HEADER(TypeObjectDispatch)
 
-    static MTypeObjectDispatch *New(MDefinition *ins, InlinePropertyTable *table) {
-        return new MTypeObjectDispatch(ins, table);
+    static MTypeObjectDispatch *New(TempAllocator &alloc, MDefinition *ins,
+                                    InlinePropertyTable *table)
+    {
+        return new(alloc) MTypeObjectDispatch(ins, table);
     }
 
     InlinePropertyTable *propTable() const {
         return inlinePropertyTable_;
     }
 };
 
 // Polymorphic dispatch for inlining, keyed off incoming JSFunction*.
@@ -6694,18 +6767,18 @@ class MFunctionDispatch : public MDispat
 {
     MFunctionDispatch(MDefinition *input)
       : MDispatchInstruction(input)
     { }
 
   public:
     INSTRUCTION_HEADER(FunctionDispatch)
 
-    static MFunctionDispatch *New(MDefinition *ins) {
-        return new MFunctionDispatch(ins);
+    static MFunctionDispatch *New(TempAllocator &alloc, MDefinition *ins) {
+        return new(alloc) MFunctionDispatch(ins);
     }
 };
 
 class MGetElementCache
   : public MBinaryInstruction
 {
     MixPolicy<ObjectPolicy<0>, BoxPolicy<1> > PolicyV;
     MixPolicy<ObjectPolicy<0>, IntPolicy<1> > PolicyT;
@@ -6717,18 +6790,20 @@ class MGetElementCache
       : MBinaryInstruction(obj, value), monitoredResult_(monitoredResult)
     {
         setResultType(MIRType_Value);
     }
 
   public:
     INSTRUCTION_HEADER(GetElementCache)
 
-    static MGetElementCache *New(MDefinition *obj, MDefinition *value, bool monitoredResult) {
-        return new MGetElementCache(obj, value, monitoredResult);
+    static MGetElementCache *New(TempAllocator &alloc, MDefinition *obj, MDefinition *value,
+                                 bool monitoredResult)
+    {
+        return new(alloc) MGetElementCache(obj, value, monitoredResult);
     }
 
     MDefinition *object() const {
         return getOperand(0);
     }
     MDefinition *index() const {
         return getOperand(1);
     }
@@ -6754,19 +6829,20 @@ class MBindNameCache
       : MUnaryInstruction(scopeChain), name_(name), script_(script), pc_(pc)
     {
         setResultType(MIRType_Object);
     }
 
   public:
     INSTRUCTION_HEADER(BindNameCache)
 
-    static MBindNameCache *New(MDefinition *scopeChain, PropertyName *name, JSScript *script,
-                               jsbytecode *pc) {
-        return new MBindNameCache(scopeChain, name, script, pc);
+    static MBindNameCache *New(TempAllocator &alloc, MDefinition *scopeChain, PropertyName *name,
+                               JSScript *script, jsbytecode *pc)
+    {
+        return new(alloc) MBindNameCache(scopeChain, name, script, pc);
     }
 
     TypePolicy *typePolicy() {
         return this;
     }
     MDefinition *scopeChain() const {
         return getOperand(0);
     }
@@ -6797,18 +6873,20 @@ class MGuardShape
         setGuard();
         setMovable();
         setResultType(MIRType_Object);
     }
 
   public:
     INSTRUCTION_HEADER(GuardShape)
 
-    static MGuardShape *New(MDefinition *obj, Shape *shape, BailoutKind bailoutKind) {
-        return new MGuardShape(obj, shape, bailoutKind);
+    static MGuardShape *New(TempAllocator &alloc, MDefinition *obj, Shape *shape,
+                            BailoutKind bailoutKind)
+    {
+        return new(alloc) MGuardShape(obj, shape, bailoutKind);
     }
 
     TypePolicy *typePolicy() {
         return this;
     }
     MDefinition *obj() const {
         return getOperand(0);
     }
@@ -6848,19 +6926,19 @@ class MGuardObjectType
         setGuard();
         setMovable();
         setResultType(MIRType_Object);
     }
 
   public:
     INSTRUCTION_HEADER(GuardObjectType)
 
-    static MGuardObjectType *New(MDefinition *obj, types::TypeObject *typeObject,
+    static MGuardObjectType *New(TempAllocator &alloc, MDefinition *obj, types::TypeObject *typeObject,
                                  bool bailOnEquality) {
-        return new MGuardObjectType(obj, typeObject, bailOnEquality);
+        return new(alloc) MGuardObjectType(obj, typeObject, bailOnEquality);
     }
 
     TypePolicy *typePolicy() {
         return this;
     }
     MDefinition *obj() const {
         return getOperand(0);
     }
@@ -6900,19 +6978,19 @@ class MGuardObjectIdentity
         setGuard();
         setMovable();
         setResultType(MIRType_Object);
     }
 
   public:
     INSTRUCTION_HEADER(GuardObjectIdentity)
 
-    static MGuardObjectIdentity *New(MDefinition *obj, JSObject *singleObject,
-                                 bool bailOnEquality) {
-        return new MGuardObjectIdentity(obj, singleObject, bailOnEquality);
+    static MGuardObjectIdentity *New(TempAllocator &alloc, MDefinition *obj, JSObject *singleObject,
+                                     bool bailOnEquality) {
+        return new(alloc) MGuardObjectIdentity(obj, singleObject, bailOnEquality);
     }
 
     TypePolicy *typePolicy() {
         return this;
     }
     MDefinition *obj() const {
         return getOperand(0);
     }
@@ -6949,18 +7027,18 @@ class MGuardClass
     {
         setGuard();
         setMovable();
     }
 
   public:
     INSTRUCTION_HEADER(GuardClass)
 
-    static MGuardClass *New(MDefinition *obj, const Class *clasp) {
-        return new MGuardClass(obj, clasp);
+    static MGuardClass *New(TempAllocator &alloc, MDefinition *obj, const Class *clasp) {
+        return new(alloc) MGuardClass(obj, clasp);
     }
 
     TypePolicy *typePolicy() {
         return this;
     }
     MDefinition *obj() const {
         return getOperand(0);
     }
@@ -6993,18 +7071,18 @@ class MLoadSlot
         setResultType(MIRType_Value);
         setMovable();
         JS_ASSERT(slots->type() == MIRType_Slots);
     }
 
   public:
     INSTRUCTION_HEADER(LoadSlot)
 
-    static MLoadSlot *New(MDefinition *slots, uint32_t slot) {
-        return new MLoadSlot(slots, slot);
+    static MLoadSlot *New(TempAllocator &alloc, MDefinition *slots, uint32_t slot) {
+        return new(alloc) MLoadSlot(slots, slot);
     }
 
     TypePolicy *typePolicy() {
         return this;
     }
     MDefinition *slots() const {
         return getOperand(0);
     }
@@ -7036,18 +7114,18 @@ class MFunctionEnvironment
         : MUnaryInstruction(function)
     {
         setResultType(MIRType_Object);
         setMovable();
     }
 
     INSTRUCTION_HEADER(FunctionEnvironment)
 
-    static MFunctionEnvironment *New(MDefinition *function) {
-        return new MFunctionEnvironment(function);
+    static MFunctionEnvironment *New(TempAllocator &alloc, MDefinition *function) {
+        return new(alloc) MFunctionEnvironment(function);
     }
 
     MDefinition *function() const {
         return getOperand(0);
     }
 
     TypePolicy *typePolicy() {
         return this;
@@ -7059,25 +7137,29 @@ class MFunctionEnvironment
     }
 };
 
 // Loads the current js::ForkJoinSlice*.
 // Only applicable in ParallelExecution.
 class MForkJoinSlice
   : public MNullaryInstruction
 {
-  public:
     MForkJoinSlice()
         : MNullaryInstruction()
     {
         setResultType(MIRType_ForkJoinSlice);
     }
 
+  public:
     INSTRUCTION_HEADER(ForkJoinSlice);
 
+    static MForkJoinSlice *New(TempAllocator &alloc) {
+        return new(alloc) MForkJoinSlice();
+    }
+
     AliasSet getAliasSet() const {
         // Indicate that this instruction reads nothing, stores nothing.
         // (For all intents and purposes)
         return AliasSet::None();
     }
 
     bool possiblyCalls() const {
         return true;
@@ -7100,21 +7182,25 @@ class MStoreSlot
           needsBarrier_(barrier)
     {
         JS_ASSERT(slots->type() == MIRType_Slots);
     }
 
   public:
     INSTRUCTION_HEADER(StoreSlot)
 
-    static MStoreSlot *New(MDefinition *slots, uint32_t slot, MDefinition *value) {
-        return new MStoreSlot(slots, slot, value, false);
-    }
-    static MStoreSlot *NewBarriered(MDefinition *slots, uint32_t slot, MDefinition *value) {
-        return new MStoreSlot(slots, slot, value, true);
+    static MStoreSlot *New(TempAllocator &alloc, MDefinition *slots, uint32_t slot,
+                           MDefinition *value)
+    {
+        return new(alloc) MStoreSlot(slots, slot, value, false);
+    }
+    static MStoreSlot *NewBarriered(TempAllocator &alloc, MDefinition *slots, uint32_t slot,
+                                    MDefinition *value)
+    {
+        return new(alloc) MStoreSlot(slots, slot, value, true);
     }
 
     TypePolicy *typePolicy() {
         return this;
     }
     MDefinition *slots() const {
         return getOperand(0);
     }
@@ -7162,18 +7248,20 @@ class MGetNameCache
         kind_(kind)
     {
         setResultType(MIRType_Value);
     }
 
   public:
     INSTRUCTION_HEADER(GetNameCache)
 
-    static MGetNameCache *New(MDefinition *obj, PropertyName *name, AccessKind kind) {
-        return new MGetNameCache(obj, name, kind);
+    static MGetNameCache *New(TempAllocator &alloc, MDefinition *obj, PropertyName *name,
+                              AccessKind kind)
+    {
+        return new(alloc) MGetNameCache(obj, name, kind);
     }
     TypePolicy *typePolicy() {
         return this;
     }
     MDefinition *scopeObj() const {
         return getOperand(0);
     }
     PropertyName *name() const {
@@ -7192,18 +7280,18 @@ class MCallGetIntrinsicValue : public MN
       : name_(name)
     {
         setResultType(MIRType_Value);
     }
 
   public:
     INSTRUCTION_HEADER(CallGetIntrinsicValue)
 
-    static MCallGetIntrinsicValue *New(PropertyName *name) {
-        return new MCallGetIntrinsicValue(name);
+    static MCallGetIntrinsicValue *New(TempAllocator &alloc, PropertyName *name) {
+        return new(alloc) MCallGetIntrinsicValue(name);
     }
     PropertyName *name() const {
         return name_;
     }
     AliasSet getAliasSet() const {
         return AliasSet::None();
     }
     bool possiblyCalls() const {
@@ -7222,18 +7310,18 @@ class MCallsiteCloneCache
         callPc_(callPc)
     {
         setResultType(MIRType_Object);
     }
 
   public:
     INSTRUCTION_HEADER(CallsiteCloneCache);
 
-    static MCallsiteCloneCache *New(MDefinition *callee, jsbytecode *callPc) {
-        return new MCallsiteCloneCache(callee, callPc);