зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1395900 part 2 - Teach analyzeNewLoopTypes about for-in iterator value slot. r=tcampbell
--HG-- extra : rebase_source : 4249cb67860227705d50d85600e8704a4c6405b7
This commit is contained in:
Родитель
406236a491
Коммит
e0a93920a4
|
@ -570,6 +570,18 @@ IonBuilder::analyzeNewLoopTypes(const CFGBlock* loopEntryBlock)
|
|||
return abort(AbortReason::Alloc);
|
||||
}
|
||||
|
||||
if (loopEntry->isForIn()) {
|
||||
// The backedge will have MIteratorMore with MIRType::Value. This slot
|
||||
// is initialized to MIRType::Undefined before the loop. Add
|
||||
// MIRType::Value to avoid unnecessary loop restarts.
|
||||
|
||||
MPhi* phi = entry->getSlot(entry->stackDepth() - 1)->toPhi();
|
||||
MOZ_ASSERT(phi->getOperand(0)->type() == MIRType::Undefined);
|
||||
|
||||
if (!phi->addBackedgeType(alloc(), MIRType::Value, nullptr))
|
||||
return abort(AbortReason::Alloc);
|
||||
}
|
||||
|
||||
// Get the start and end pc of this loop.
|
||||
jsbytecode* start = loopEntryBlock->stopPc();
|
||||
start += GetBytecodeLength(start);
|
||||
|
|
|
@ -941,6 +941,9 @@ ControlFlowGenerator::processWhileOrForInLoop(jssrcnote* sn)
|
|||
if (LoopEntryCanIonOsr(loopEntry))
|
||||
ins->setCanOsr();
|
||||
|
||||
if (SN_TYPE(sn) == SRC_FOR_IN)
|
||||
ins->setIsForIn();
|
||||
|
||||
current->setStopIns(ins);
|
||||
current->setStopPc(pc);
|
||||
|
||||
|
|
|
@ -552,19 +552,23 @@ class CFGBackEdge : public CFGUnaryControlInstruction
|
|||
class CFGLoopEntry : public CFGUnaryControlInstruction
|
||||
{
|
||||
bool canOsr_;
|
||||
bool isForIn_;
|
||||
size_t stackPhiCount_;
|
||||
jsbytecode* loopStopPc_;
|
||||
|
||||
CFGLoopEntry(CFGBlock* block, size_t stackPhiCount)
|
||||
: CFGUnaryControlInstruction(block),
|
||||
canOsr_(false),
|
||||
isForIn_(false),
|
||||
stackPhiCount_(stackPhiCount),
|
||||
loopStopPc_(nullptr)
|
||||
{}
|
||||
|
||||
CFGLoopEntry(CFGBlock* block, bool canOsr, size_t stackPhiCount, jsbytecode* loopStopPc)
|
||||
CFGLoopEntry(CFGBlock* block, bool canOsr, bool isForIn, size_t stackPhiCount,
|
||||
jsbytecode* loopStopPc)
|
||||
: CFGUnaryControlInstruction(block),
|
||||
canOsr_(canOsr),
|
||||
isForIn_(isForIn),
|
||||
stackPhiCount_(stackPhiCount),
|
||||
loopStopPc_(loopStopPc)
|
||||
{}
|
||||
|
@ -576,8 +580,8 @@ class CFGLoopEntry : public CFGUnaryControlInstruction
|
|||
static CFGLoopEntry* CopyWithNewTargets(TempAllocator& alloc, CFGLoopEntry* old,
|
||||
CFGBlock* loopEntry)
|
||||
{
|
||||
return new(alloc) CFGLoopEntry(loopEntry, old->canOsr(), old->stackPhiCount(),
|
||||
old->loopStopPc());
|
||||
return new(alloc) CFGLoopEntry(loopEntry, old->canOsr(), old->isForIn(),
|
||||
old->stackPhiCount(), old->loopStopPc());
|
||||
}
|
||||
|
||||
void setCanOsr() {
|
||||
|
@ -588,6 +592,13 @@ class CFGLoopEntry : public CFGUnaryControlInstruction
|
|||
return canOsr_;
|
||||
}
|
||||
|
||||
void setIsForIn() {
|
||||
isForIn_ = true;
|
||||
}
|
||||
bool isForIn() const {
|
||||
return isForIn_;
|
||||
}
|
||||
|
||||
size_t stackPhiCount() const {
|
||||
return stackPhiCount_;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче