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); 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. // Get the start and end pc of this loop.
jsbytecode* start = loopEntryBlock->stopPc(); jsbytecode* start = loopEntryBlock->stopPc();
start += GetBytecodeLength(start); start += GetBytecodeLength(start);

View File

@ -941,6 +941,9 @@ ControlFlowGenerator::processWhileOrForInLoop(jssrcnote* sn)
if (LoopEntryCanIonOsr(loopEntry)) if (LoopEntryCanIonOsr(loopEntry))
ins->setCanOsr(); ins->setCanOsr();
if (SN_TYPE(sn) == SRC_FOR_IN)
ins->setIsForIn();
current->setStopIns(ins); current->setStopIns(ins);
current->setStopPc(pc); current->setStopPc(pc);

View File

@ -552,19 +552,23 @@ class CFGBackEdge : public CFGUnaryControlInstruction
class CFGLoopEntry : public CFGUnaryControlInstruction class CFGLoopEntry : public CFGUnaryControlInstruction
{ {
bool canOsr_; bool canOsr_;
bool isForIn_;
size_t stackPhiCount_; size_t stackPhiCount_;
jsbytecode* loopStopPc_; jsbytecode* loopStopPc_;
CFGLoopEntry(CFGBlock* block, size_t stackPhiCount) CFGLoopEntry(CFGBlock* block, size_t stackPhiCount)
: CFGUnaryControlInstruction(block), : CFGUnaryControlInstruction(block),
canOsr_(false), canOsr_(false),
isForIn_(false),
stackPhiCount_(stackPhiCount), stackPhiCount_(stackPhiCount),
loopStopPc_(nullptr) 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), : CFGUnaryControlInstruction(block),
canOsr_(canOsr), canOsr_(canOsr),
isForIn_(isForIn),
stackPhiCount_(stackPhiCount), stackPhiCount_(stackPhiCount),
loopStopPc_(loopStopPc) loopStopPc_(loopStopPc)
{} {}
@ -576,8 +580,8 @@ class CFGLoopEntry : public CFGUnaryControlInstruction
static CFGLoopEntry* CopyWithNewTargets(TempAllocator& alloc, CFGLoopEntry* old, static CFGLoopEntry* CopyWithNewTargets(TempAllocator& alloc, CFGLoopEntry* old,
CFGBlock* loopEntry) CFGBlock* loopEntry)
{ {
return new(alloc) CFGLoopEntry(loopEntry, old->canOsr(), old->stackPhiCount(), return new(alloc) CFGLoopEntry(loopEntry, old->canOsr(), old->isForIn(),
old->loopStopPc()); old->stackPhiCount(), old->loopStopPc());
} }
void setCanOsr() { void setCanOsr() {
@ -588,6 +592,13 @@ class CFGLoopEntry : public CFGUnaryControlInstruction
return canOsr_; return canOsr_;
} }
void setIsForIn() {
isForIn_ = true;
}
bool isForIn() const {
return isForIn_;
}
size_t stackPhiCount() const { size_t stackPhiCount() const {
return stackPhiCount_; return stackPhiCount_;
} }