Bug 1042729 part 3 - Ensure priorResumePoints are re-attached to the new BasicBlock or discarded. r=efaust

This commit is contained in:
Nicolas B. Pierron 2014-08-05 04:29:13 -07:00
parent 7edba63c04
commit 8ef397647f
4 changed files with 47 additions and 11 deletions

View File

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

View File

@ -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 {

View File

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

View File

@ -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.