mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-15 06:15:43 +00:00
Bug 1042729 part 3 - Ensure priorResumePoints are re-attached to the new BasicBlock or discarded. r=efaust
This commit is contained in:
parent
7edba63c04
commit
8ef397647f
@ -4321,6 +4321,26 @@ IonBuilder::inlineSingleCall(CallInfo &callInfo, JSFunction *target)
|
||||
return InliningStatus_Inlined;
|
||||
}
|
||||
|
||||
class DiscardPropCacheResumePoint
|
||||
{
|
||||
MGetPropertyCache *propCache_;
|
||||
|
||||
public:
|
||||
DiscardPropCacheResumePoint(MGetPropertyCache *propCache)
|
||||
: propCache_(propCache)
|
||||
{
|
||||
}
|
||||
|
||||
~DiscardPropCacheResumePoint() {
|
||||
if (!propCache_)
|
||||
return;
|
||||
|
||||
InlinePropertyTable *propTable = propCache_->propTable();
|
||||
if (MResumePoint *rp = propTable->takePriorResumePoint())
|
||||
propCache_->block()->discardPreAllocatedResumePoint(rp);
|
||||
}
|
||||
};
|
||||
|
||||
IonBuilder::InliningStatus
|
||||
IonBuilder::inlineCallsite(ObjectVector &targets, ObjectVector &originals,
|
||||
bool lambda, CallInfo &callInfo)
|
||||
@ -4364,6 +4384,8 @@ IonBuilder::inlineCallsite(ObjectVector &targets, ObjectVector &originals,
|
||||
return inlineSingleCall(callInfo, target);
|
||||
}
|
||||
|
||||
DiscardPropCacheResumePoint discardRp(propCache);
|
||||
|
||||
// Choose a subset of the targets for polymorphic inlining.
|
||||
BoolVector choiceSet(alloc());
|
||||
uint32_t numInlined;
|
||||
@ -4455,9 +4477,10 @@ IonBuilder::inlineTypeObjectFallback(CallInfo &callInfo, MBasicBlock *dispatchBl
|
||||
// Construct a block into which the MGetPropertyCache can be moved.
|
||||
// This is subtle: the pc and resume point are those of the MGetPropertyCache!
|
||||
InlinePropertyTable *propTable = cache->propTable();
|
||||
MResumePoint *priorResumePoint = propTable->takePriorResumePoint();
|
||||
JS_ASSERT(propTable->pc() != nullptr);
|
||||
JS_ASSERT(propTable->priorResumePoint() != nullptr);
|
||||
MBasicBlock *getPropBlock = newBlock(prepBlock, propTable->pc(), propTable->priorResumePoint());
|
||||
JS_ASSERT(priorResumePoint != nullptr);
|
||||
MBasicBlock *getPropBlock = newBlock(prepBlock, propTable->pc(), priorResumePoint);
|
||||
if (!getPropBlock)
|
||||
return false;
|
||||
|
||||
|
@ -7503,9 +7503,10 @@ class InlinePropertyTable : public TempObject
|
||||
JS_ASSERT(priorResumePoint_ == nullptr);
|
||||
priorResumePoint_ = resumePoint;
|
||||
}
|
||||
|
||||
MResumePoint *priorResumePoint() const {
|
||||
return priorResumePoint_;
|
||||
MResumePoint *takePriorResumePoint() {
|
||||
MResumePoint *rp = priorResumePoint_;
|
||||
priorResumePoint_ = nullptr;
|
||||
return rp;
|
||||
}
|
||||
|
||||
jsbytecode *pc() const {
|
||||
|
@ -203,7 +203,10 @@ MBasicBlock::NewWithResumePoint(MIRGraph &graph, CompileInfo &info,
|
||||
{
|
||||
MBasicBlock *block = new(graph.alloc()) MBasicBlock(graph, info, site, NORMAL);
|
||||
|
||||
MOZ_ASSERT(!resumePoint->instruction());
|
||||
resumePoint->block()->discardResumePoint(resumePoint, RefType_None);
|
||||
resumePoint->block_ = block;
|
||||
block->addResumePoint(resumePoint);
|
||||
block->entryResumePoint_ = resumePoint;
|
||||
|
||||
if (!block->init())
|
||||
@ -720,9 +723,10 @@ AssertSafelyDiscardable(MDefinition *def)
|
||||
}
|
||||
|
||||
void
|
||||
MBasicBlock::discardResumePoint(MResumePoint *rp)
|
||||
MBasicBlock::discardResumePoint(MResumePoint *rp, ReferencesType refType /* = RefType_Default */)
|
||||
{
|
||||
rp->discardUses();
|
||||
if (refType & RefType_DiscardOperands)
|
||||
rp->discardUses();
|
||||
MResumePointIterator iter = resumePointsBegin();
|
||||
while (*iter != rp) {
|
||||
// We should reach it before reaching the end.
|
||||
@ -740,8 +744,8 @@ MBasicBlock::prepareForDiscard(MInstruction *ins, ReferencesType refType /* = Re
|
||||
MOZ_ASSERT(ins->block() == this);
|
||||
|
||||
MResumePoint *rp = ins->resumePoint();
|
||||
if (refType & RefType_DiscardResumePoint && rp)
|
||||
discardResumePoint(rp);
|
||||
if ((refType & RefType_DiscardResumePoint) && rp)
|
||||
discardResumePoint(rp, refType);
|
||||
|
||||
// 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,15 +61,17 @@ class MBasicBlock : public TempObject, public InlineListNode<MBasicBlock>
|
||||
// as needed.
|
||||
void setVariable(uint32_t slot);
|
||||
|
||||
void discardResumePoint(MResumePoint *rp);
|
||||
|
||||
enum ReferencesType {
|
||||
RefType_None = 0,
|
||||
RefType_AssertNoUses = 1 << 0,
|
||||
RefType_DiscardOperands = 1 << 1,
|
||||
RefType_DiscardResumePoint = 1 << 2,
|
||||
RefType_DefaultNoAssert = RefType_DiscardOperands | RefType_DiscardResumePoint,
|
||||
RefType_Default = RefType_AssertNoUses | RefType_DiscardOperands | RefType_DiscardResumePoint
|
||||
};
|
||||
|
||||
void discardResumePoint(MResumePoint *rp, ReferencesType refType = RefType_Default);
|
||||
|
||||
// Remove all references to an instruction such that it can be removed from
|
||||
// the list of instruction, without keeping any dangling pointer to it. This
|
||||
// includes the operands of the instruction, and the resume point if
|
||||
@ -185,6 +187,12 @@ class MBasicBlock : public TempObject, public InlineListNode<MBasicBlock>
|
||||
resumePoints_.pushFront(resume);
|
||||
}
|
||||
|
||||
// Discard pre-allocated resume point.
|
||||
void discardPreAllocatedResumePoint(MResumePoint *resume) {
|
||||
MOZ_ASSERT(!resume->instruction());
|
||||
discardResumePoint(resume);
|
||||
}
|
||||
|
||||
// Adds a predecessor. Every predecessor must have the same exit stack
|
||||
// depth as the entry state to this block. Adding a predecessor
|
||||
// automatically creates phi nodes and rewrites uses as needed.
|
||||
|
Loading…
Reference in New Issue
Block a user