Bug 1395900 part 2 - Teach analyzeNewLoopTypes about for-in iterator value slot. r=tcampbell

--HG--
extra : rebase_source : 4249cb67860227705d50d85600e8704a4c6405b7
This commit is contained in:
Jan de Mooij 2017-09-06 10:01:46 +02:00
parent 406236a491
commit e0a93920a4
3 changed files with 29 additions and 3 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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_;
}