diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index dfce3601ebd6..da8e4a7c0702 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -734,7 +734,7 @@ IonBuilder::build() script()->baselineScript()->resetMaxInliningDepth(); MBasicBlock* entry; - MOZ_TRY_VAR(entry, newBlock(pc)); + MOZ_TRY_VAR(entry, newBlock(info().firstStackSlot(), pc)); MOZ_TRY(setCurrentAndSpecializePhis(entry)); #ifdef JS_JITSPEW @@ -930,7 +930,7 @@ IonBuilder::buildInline(IonBuilder* callerBuilder, MResumePoint* callerResumePoi // Generate single entrance block. MBasicBlock* entry; - MOZ_TRY_VAR(entry, newBlock(pc)); + MOZ_TRY_VAR(entry, newBlock(info().firstStackSlot(), pc)); MOZ_TRY(setCurrentAndSpecializePhis(entry)); current->setCallerResumePoint(callerResumePoint); @@ -3845,7 +3845,7 @@ IonBuilder::inlineScriptedCall(CallInfo& callInfo, JSFunction* target) // Create return block. jsbytecode* postCall = GetNextPc(pc); MBasicBlock* returnBlock; - MOZ_TRY_VAR(returnBlock, newBlock(nullptr, postCall)); + MOZ_TRY_VAR(returnBlock, newBlock(current->stackDepth(), postCall)); graph().addBlock(returnBlock); returnBlock->setCallerResumePoint(callerResumePoint_); @@ -4541,10 +4541,13 @@ IonBuilder::inlineCalls(CallInfo& callInfo, const InliningTargets& targets, Bool dispatch = MFunctionDispatch::New(alloc(), callInfo.fun()); } + MOZ_ASSERT(dispatchBlock->stackDepth() >= callInfo.numFormals()); + uint32_t stackDepth = dispatchBlock->stackDepth() - callInfo.numFormals() + 1; + // Generate a return block to host the rval-collecting MPhi. jsbytecode* postCall = GetNextPc(pc); MBasicBlock* returnBlock; - MOZ_TRY_VAR(returnBlock, newBlock(nullptr, postCall)); + MOZ_TRY_VAR(returnBlock, newBlock(stackDepth, postCall)); graph().addBlock(returnBlock); returnBlock->setCallerResumePoint(callerResumePoint_); @@ -6510,9 +6513,11 @@ IonBuilder::jsop_initelem_getter_setter() } AbortReasonOr -IonBuilder::newBlock(MBasicBlock* predecessor, jsbytecode* pc) +IonBuilder::newBlock(size_t stackDepth, jsbytecode* pc, MBasicBlock* maybePredecessor) { - MBasicBlock* block = MBasicBlock::New(graph(), &analysis(), info(), predecessor, + MOZ_ASSERT_IF(maybePredecessor, maybePredecessor->stackDepth() == stackDepth); + + MBasicBlock* block = MBasicBlock::New(graph(), stackDepth, info(), maybePredecessor, bytecodeSite(pc), MBasicBlock::NORMAL); if (!block) return abort(AbortReason::Alloc); @@ -6546,9 +6551,12 @@ IonBuilder::newBlockPopN(MBasicBlock* predecessor, jsbytecode* pc, uint32_t popp } AbortReasonOr -IonBuilder::newBlockAfter(MBasicBlock* at, MBasicBlock* predecessor, jsbytecode* pc) +IonBuilder::newBlockAfter(MBasicBlock* at, size_t stackDepth, jsbytecode* pc, + MBasicBlock* maybePredecessor) { - MBasicBlock* block = MBasicBlock::New(graph(), &analysis(), info(), predecessor, + MOZ_ASSERT_IF(maybePredecessor, maybePredecessor->stackDepth() == stackDepth); + + MBasicBlock* block = MBasicBlock::New(graph(), stackDepth, info(), maybePredecessor, bytecodeSite(pc), MBasicBlock::NORMAL); if (!block) return abort(AbortReason::Alloc); @@ -6569,7 +6577,7 @@ IonBuilder::newOsrPreheader(MBasicBlock* predecessor, jsbytecode* loopEntry, // the preheader, which has the OSR entry block as a predecessor. The // OSR block is always the second block (with id 1). MBasicBlock* osrBlock; - MOZ_TRY_VAR(osrBlock, newBlockAfter(*graph().begin(), loopEntry)); + MOZ_TRY_VAR(osrBlock, newBlockAfter(*graph().begin(), predecessor->stackDepth(), loopEntry)); MBasicBlock* preheader; MOZ_TRY_VAR(preheader, newBlock(predecessor, loopEntry)); diff --git a/js/src/jit/IonBuilder.h b/js/src/jit/IonBuilder.h index 2122c7341a6e..df66beeaafc9 100644 --- a/js/src/jit/IonBuilder.h +++ b/js/src/jit/IonBuilder.h @@ -76,22 +76,21 @@ class IonBuilder AbortReasonOr analyzeNewLoopTypes(const CFGBlock* loopEntryBlock); - AbortReasonOr newBlock(MBasicBlock* predecessor, jsbytecode* pc); + AbortReasonOr newBlock(size_t stackDepth, jsbytecode* pc, + MBasicBlock* maybePredecessor = nullptr); AbortReasonOr newBlock(MBasicBlock* predecessor, jsbytecode* pc, MResumePoint* priorResumePoint); AbortReasonOr newBlockPopN(MBasicBlock* predecessor, jsbytecode* pc, uint32_t popped); - AbortReasonOr newBlockAfter(MBasicBlock* at, MBasicBlock* predecessor, - jsbytecode* pc); + AbortReasonOr newBlockAfter(MBasicBlock* at, size_t stackDepth, + jsbytecode* pc, MBasicBlock* maybePredecessor = nullptr); AbortReasonOr newOsrPreheader(MBasicBlock* header, jsbytecode* loopEntry, jsbytecode* beforeLoopEntry); AbortReasonOr newPendingLoopHeader(MBasicBlock* predecessor, jsbytecode* pc, bool osr, bool canOsr, unsigned stackPhiCount); - AbortReasonOr newBlock(jsbytecode* pc) { - return newBlock(nullptr, pc); - } - AbortReasonOr newBlockAfter(MBasicBlock* at, jsbytecode* pc) { - return newBlockAfter(at, nullptr, pc); + + AbortReasonOr newBlock(MBasicBlock* predecessor, jsbytecode* pc) { + return newBlock(predecessor->stackDepth(), pc, predecessor); } AbortReasonOr visitBlock(const CFGBlock* hblock, MBasicBlock* mblock); diff --git a/js/src/jit/LoopUnroller.cpp b/js/src/jit/LoopUnroller.cpp index bed7b1ccff40..f394293e9a43 100644 --- a/js/src/jit/LoopUnroller.cpp +++ b/js/src/jit/LoopUnroller.cpp @@ -212,17 +212,17 @@ LoopUnroller::go(LoopIterationBound* bound) const CompileInfo& info = oldPreheader->info(); if (header->trackedPc()) { unrolledHeader = - MBasicBlock::New(graph, nullptr, info, + MBasicBlock::New(graph, oldPreheader->stackDepth(), info, oldPreheader, header->trackedSite(), MBasicBlock::LOOP_HEADER); if (!unrolledHeader) return false; unrolledBackedge = - MBasicBlock::New(graph, nullptr, info, + MBasicBlock::New(graph, unrolledHeader->stackDepth(), info, unrolledHeader, backedge->trackedSite(), MBasicBlock::NORMAL); if (!unrolledBackedge) return false; newPreheader = - MBasicBlock::New(graph, nullptr, info, + MBasicBlock::New(graph, unrolledHeader->stackDepth(), info, unrolledHeader, oldPreheader->trackedSite(), MBasicBlock::NORMAL); if (!newPreheader) return false; diff --git a/js/src/jit/MIRGraph.cpp b/js/src/jit/MIRGraph.cpp index 200d7ce67999..45fe975d7155 100644 --- a/js/src/jit/MIRGraph.cpp +++ b/js/src/jit/MIRGraph.cpp @@ -286,8 +286,8 @@ MIRGraph::unmarkBlocks() } MBasicBlock* -MBasicBlock::New(MIRGraph& graph, BytecodeAnalysis* analysis, const CompileInfo& info, - MBasicBlock* pred, BytecodeSite* site, Kind kind) +MBasicBlock::New(MIRGraph& graph, size_t stackDepth, const CompileInfo& info, + MBasicBlock* maybePred, BytecodeSite* site, Kind kind) { MOZ_ASSERT(site->pc() != nullptr); @@ -295,7 +295,7 @@ MBasicBlock::New(MIRGraph& graph, BytecodeAnalysis* analysis, const CompileInfo& if (!block->init()) return nullptr; - if (!block->inherit(graph.alloc(), analysis, pred, 0)) + if (!block->inherit(graph.alloc(), stackDepth, maybePred, 0)) return nullptr; return block; @@ -309,7 +309,7 @@ MBasicBlock::NewPopN(MIRGraph& graph, const CompileInfo& info, if (!block->init()) return nullptr; - if (!block->inherit(graph.alloc(), nullptr, pred, popped)) + if (!block->inherit(graph.alloc(), pred->stackDepth(), pred, popped)) return nullptr; return block; @@ -348,7 +348,7 @@ MBasicBlock::NewPendingLoopHeader(MIRGraph& graph, const CompileInfo& info, if (!block->init()) return nullptr; - if (!block->inherit(graph.alloc(), nullptr, pred, 0, stackPhiCount)) + if (!block->inherit(graph.alloc(), pred->stackDepth(), pred, 0, stackPhiCount)) return nullptr; return block; @@ -546,35 +546,31 @@ MBasicBlock::copySlots(MBasicBlock* from) } bool -MBasicBlock::inherit(TempAllocator& alloc, BytecodeAnalysis* analysis, MBasicBlock* pred, +MBasicBlock::inherit(TempAllocator& alloc, size_t stackDepth, MBasicBlock* maybePred, uint32_t popped, unsigned stackPhiCount) { - if (pred) { - stackPosition_ = pred->stackPosition_; - MOZ_ASSERT(stackPosition_ >= popped); - stackPosition_ -= popped; - if (kind_ != PENDING_LOOP_HEADER) - copySlots(pred); - } else { - uint32_t stackDepth = analysis->info(pc()).stackDepth; - stackPosition_ = info().firstStackSlot() + stackDepth; - MOZ_ASSERT(stackPosition_ >= popped); - stackPosition_ -= popped; - } + MOZ_ASSERT_IF(maybePred, maybePred->stackDepth() == stackDepth); + + MOZ_ASSERT(stackDepth >= popped); + stackDepth -= popped; + stackPosition_ = stackDepth; + + if (maybePred && kind_ != PENDING_LOOP_HEADER) + copySlots(maybePred); MOZ_ASSERT(info_.nslots() >= stackPosition_); MOZ_ASSERT(!entryResumePoint_); // Propagate the caller resume point from the inherited block. - callerResumePoint_ = pred ? pred->callerResumePoint() : nullptr; + callerResumePoint_ = maybePred ? maybePred->callerResumePoint() : nullptr; // Create a resume point using our initial stack state. entryResumePoint_ = new(alloc) MResumePoint(this, pc(), MResumePoint::ResumeAt); if (!entryResumePoint_->init(alloc)) return false; - if (pred) { - if (!predecessors_.append(pred)) + if (maybePred) { + if (!predecessors_.append(maybePred)) return false; if (kind_ == PENDING_LOOP_HEADER) { @@ -583,35 +579,35 @@ MBasicBlock::inherit(TempAllocator& alloc, BytecodeAnalysis* analysis, MBasicBlo MPhi* phi = MPhi::New(alloc.fallible()); if (!phi) return false; - phi->addInlineInput(pred->getSlot(i)); + phi->addInlineInput(maybePred->getSlot(i)); addPhi(phi); setSlot(i, phi); entryResumePoint()->initOperand(i, phi); } - MOZ_ASSERT(stackPhiCount <= stackDepth()); - MOZ_ASSERT(info().firstStackSlot() <= stackDepth() - stackPhiCount); + MOZ_ASSERT(stackPhiCount <= stackDepth); + MOZ_ASSERT(info().firstStackSlot() <= stackDepth - stackPhiCount); // Avoid creating new phis for stack values that aren't part of the // loop. Note that for loop headers that can OSR, all values on the // stack are part of the loop. - for (; i < stackDepth() - stackPhiCount; i++) { - MDefinition* val = pred->getSlot(i); + for (; i < stackDepth - stackPhiCount; i++) { + MDefinition* val = maybePred->getSlot(i); setSlot(i, val); entryResumePoint()->initOperand(i, val); } - for (; i < stackDepth(); i++) { + for (; i < stackDepth; i++) { MPhi* phi = MPhi::New(alloc.fallible()); if (!phi) return false; - phi->addInlineInput(pred->getSlot(i)); + phi->addInlineInput(maybePred->getSlot(i)); addPhi(phi); setSlot(i, phi); entryResumePoint()->initOperand(i, phi); } } else { - for (size_t i = 0; i < stackDepth(); i++) + for (size_t i = 0; i < stackDepth; i++) entryResumePoint()->initOperand(i, getSlot(i)); } } else { @@ -619,7 +615,7 @@ MBasicBlock::inherit(TempAllocator& alloc, BytecodeAnalysis* analysis, MBasicBlo * Don't leave the operands uninitialized for the caller, as it may not * initialize them later on. */ - for (size_t i = 0; i < stackDepth(); i++) + for (size_t i = 0; i < stackDepth; i++) entryResumePoint()->clearOperand(i); } diff --git a/js/src/jit/MIRGraph.h b/js/src/jit/MIRGraph.h index 9c0b89ec4b7d..1eed4bfb2f0b 100644 --- a/js/src/jit/MIRGraph.h +++ b/js/src/jit/MIRGraph.h @@ -49,8 +49,8 @@ class MBasicBlock : public TempObject, public InlineListNode MBasicBlock(MIRGraph& graph, const CompileInfo& info, BytecodeSite* site, Kind kind); MOZ_MUST_USE bool init(); void copySlots(MBasicBlock* from); - MOZ_MUST_USE bool inherit(TempAllocator& alloc, BytecodeAnalysis* analysis, MBasicBlock* pred, - uint32_t popped, unsigned stackPhiCount = 0); + MOZ_MUST_USE bool inherit(TempAllocator& alloc, size_t stackDepth, MBasicBlock* maybePred, + uint32_t popped, unsigned stackPhiCount = 0); MOZ_MUST_USE bool inheritResumePoint(MBasicBlock* pred); void assertUsesAreNotWithin(MUseIterator use, MUseIterator end); @@ -109,8 +109,8 @@ class MBasicBlock : public TempObject, public InlineListNode // Creates a new basic block for a MIR generator. If |pred| is not nullptr, // its slots and stack depth are initialized from |pred|. - static MBasicBlock* New(MIRGraph& graph, BytecodeAnalysis* analysis, const CompileInfo& info, - MBasicBlock* pred, BytecodeSite* site, Kind kind); + static MBasicBlock* New(MIRGraph& graph, size_t stackDepth, const CompileInfo& info, + MBasicBlock* maybePred, BytecodeSite* site, Kind kind); static MBasicBlock* New(MIRGraph& graph, const CompileInfo& info, MBasicBlock* pred, Kind kind); static MBasicBlock* NewPopN(MIRGraph& graph, const CompileInfo& info, MBasicBlock* pred, BytecodeSite* site, Kind kind, uint32_t popn);