mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-15 06:15:43 +00:00
Bug 1042729 part 2 - Ensure that a resume point belongs to one instruction. r=h4writer
This commit is contained in:
parent
4ded2e7b05
commit
7edba63c04
@ -1744,10 +1744,15 @@ jit::AssertBasicGraphCoherency(MIRGraph &graph)
|
||||
for (size_t i = 0; i < block->numPredecessors(); i++)
|
||||
JS_ASSERT(CheckPredecessorImpliesSuccessor(*block, block->getPredecessor(i)));
|
||||
|
||||
MOZ_ASSERT_IF(block->entryResumePoint(), !block->entryResumePoint()->instruction());
|
||||
for (MResumePointIterator iter(block->resumePointsBegin()); iter != block->resumePointsEnd(); iter++) {
|
||||
// We cannot yet assert that is there is no instruction then this is
|
||||
// the entry resume point because we are still storing resume points
|
||||
// in the InlinePropertyTable.
|
||||
MOZ_ASSERT_IF(iter->instruction(), iter->instruction()->block() == *block);
|
||||
for (uint32_t i = 0, e = iter->numOperands(); i < e; i++) {
|
||||
if (iter->getUseFor(i)->hasProducer())
|
||||
JS_ASSERT(CheckOperandImpliesUse(*iter, iter->getOperand(i)));
|
||||
MOZ_ASSERT(iter->getUseFor(i)->hasProducer());
|
||||
MOZ_ASSERT(CheckOperandImpliesUse(*iter, iter->getOperand(i)));
|
||||
}
|
||||
}
|
||||
for (MPhiIterator phi(block->phisBegin()); phi != block->phisEnd(); phi++) {
|
||||
@ -1765,11 +1770,8 @@ jit::AssertBasicGraphCoherency(MIRGraph &graph)
|
||||
|
||||
if (iter->isInstruction()) {
|
||||
if (MResumePoint *resume = iter->toInstruction()->resumePoint()) {
|
||||
if (MInstruction *ins = resume->instruction())
|
||||
JS_ASSERT(ins->block() == iter->block());
|
||||
|
||||
for (uint32_t i = 0, e = resume->numOperands(); i < e; i++)
|
||||
MOZ_ASSERT(resume->getUseFor(i)->hasProducer());
|
||||
MOZ_ASSERT(resume->instruction() == *iter);
|
||||
MOZ_ASSERT(resume->block() == *block);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6051,7 +6051,6 @@ IonBuilder::resume(MInstruction *ins, jsbytecode *pc, MResumePoint::Mode mode)
|
||||
if (!resumePoint)
|
||||
return false;
|
||||
ins->setResumePoint(resumePoint);
|
||||
resumePoint->setInstruction(ins);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -231,6 +231,23 @@ MDefinition::analyzeEdgeCasesBackward()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
MInstruction::setResumePoint(MResumePoint *resumePoint)
|
||||
{
|
||||
JS_ASSERT(!resumePoint_);
|
||||
resumePoint_ = resumePoint;
|
||||
resumePoint_->setInstruction(this);
|
||||
}
|
||||
|
||||
void
|
||||
MInstruction::stealResumePoint(MInstruction *ins)
|
||||
{
|
||||
MOZ_ASSERT(ins->resumePoint_->instruction() == ins);
|
||||
resumePoint_ = ins->resumePoint_;
|
||||
ins->resumePoint_ = nullptr;
|
||||
resumePoint_->replaceInstruction(this);
|
||||
}
|
||||
|
||||
static bool
|
||||
MaybeEmulatesUndefined(MDefinition *op)
|
||||
{
|
||||
|
@ -779,15 +779,9 @@ class MInstruction
|
||||
: resumePoint_(nullptr)
|
||||
{ }
|
||||
|
||||
void setResumePoint(MResumePoint *resumePoint) {
|
||||
JS_ASSERT(!resumePoint_);
|
||||
resumePoint_ = resumePoint;
|
||||
}
|
||||
void setResumePoint(MResumePoint *resumePoint);
|
||||
// Used to transfer the resume point to the rewritten instruction.
|
||||
void stealResumePoint(MInstruction *ins) {
|
||||
resumePoint_ = ins->resumePoint_;
|
||||
ins->resumePoint_ = nullptr;
|
||||
}
|
||||
void stealResumePoint(MInstruction *ins);
|
||||
MResumePoint *resumePoint() const {
|
||||
return resumePoint_;
|
||||
}
|
||||
@ -10302,6 +10296,12 @@ class MResumePoint MOZ_FINAL : public MNode, public InlineForwardListNode<MResum
|
||||
return instruction_;
|
||||
}
|
||||
void setInstruction(MInstruction *ins) {
|
||||
MOZ_ASSERT(!instruction_);
|
||||
instruction_ = ins;
|
||||
}
|
||||
// Only to be used by stealResumePoint.
|
||||
void replaceInstruction(MInstruction *ins) {
|
||||
MOZ_ASSERT(instruction_);
|
||||
instruction_ = ins;
|
||||
}
|
||||
Mode mode() const {
|
||||
|
@ -448,6 +448,9 @@ MBasicBlock::inheritSlots(MBasicBlock *parent)
|
||||
bool
|
||||
MBasicBlock::initEntrySlots(TempAllocator &alloc)
|
||||
{
|
||||
// Remove the previous resume point.
|
||||
discardResumePoint(entryResumePoint_);
|
||||
|
||||
// Create a resume point using our initial stack state.
|
||||
entryResumePoint_ = MResumePoint::New(alloc, this, pc(), callerResumePoint(),
|
||||
MResumePoint::ResumeAt);
|
||||
@ -716,6 +719,19 @@ AssertSafelyDiscardable(MDefinition *def)
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
MBasicBlock::discardResumePoint(MResumePoint *rp)
|
||||
{
|
||||
rp->discardUses();
|
||||
MResumePointIterator iter = resumePointsBegin();
|
||||
while (*iter != rp) {
|
||||
// We should reach it before reaching the end.
|
||||
MOZ_ASSERT(iter != resumePointsEnd());
|
||||
iter++;
|
||||
}
|
||||
resumePoints_.removeAt(iter);
|
||||
}
|
||||
|
||||
void
|
||||
MBasicBlock::prepareForDiscard(MInstruction *ins, ReferencesType refType /* = RefType_Default */)
|
||||
{
|
||||
@ -724,19 +740,8 @@ MBasicBlock::prepareForDiscard(MInstruction *ins, ReferencesType refType /* = Re
|
||||
MOZ_ASSERT(ins->block() == this);
|
||||
|
||||
MResumePoint *rp = ins->resumePoint();
|
||||
if (refType & RefType_DiscardResumePoint && rp) {
|
||||
rp->discardUses();
|
||||
// Resume point are using a forward list only, so we need to iterate
|
||||
// to the location of the resume point in order to remove it.
|
||||
MResumePointIterator iter = resumePointsBegin();
|
||||
while (*iter != rp) {
|
||||
// If the instruction has a resume point, then it should be part
|
||||
// of the basic block list of resume points.
|
||||
MOZ_ASSERT(iter != resumePointsEnd());
|
||||
iter++;
|
||||
}
|
||||
resumePoints_.removeAt(iter);
|
||||
}
|
||||
if (refType & RefType_DiscardResumePoint && rp)
|
||||
discardResumePoint(rp);
|
||||
|
||||
// We need to assert that instructions have no uses after removing the their
|
||||
// resume points operands as they could be captured by their own resume
|
||||
|
@ -61,6 +61,8 @@ class MBasicBlock : public TempObject, public InlineListNode<MBasicBlock>
|
||||
// as needed.
|
||||
void setVariable(uint32_t slot);
|
||||
|
||||
void discardResumePoint(MResumePoint *rp);
|
||||
|
||||
enum ReferencesType {
|
||||
RefType_AssertNoUses = 1 << 0,
|
||||
RefType_DiscardOperands = 1 << 1,
|
||||
|
@ -337,11 +337,8 @@ static void
|
||||
TransplantResumePoint(MInstruction *oldInstruction, MInstruction *replacementInstruction)
|
||||
{
|
||||
MOZ_ASSERT(!oldInstruction->isDiscarded());
|
||||
if (MResumePoint *rp = oldInstruction->resumePoint()) {
|
||||
if (oldInstruction->resumePoint())
|
||||
replacementInstruction->stealResumePoint(oldInstruction);
|
||||
if (rp->instruction() == oldInstruction)
|
||||
rp->setInstruction(replacementInstruction);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
|
Loading…
Reference in New Issue
Block a user