Bug 1412653 - Distinguish between call stack used for outer resume points from call stacks used for resuming at one instruction. r=jandem

This commit is contained in:
Nicolas B. Pierron 2017-12-08 16:44:44 +00:00
Родитель 52aacbca78
Коммит 81d226d76e
3 изменённых файлов: 49 добавлений и 11 удалений

Просмотреть файл

@ -3750,7 +3750,7 @@ IonBuilder::inlineScriptedCall(CallInfo& callInfo, JSFunction* target)
}
// Capture formals in the outer resume point.
MOZ_TRY(callInfo.pushFormals(this, current));
MOZ_TRY(callInfo.pushCallStack(this, current));
MResumePoint* outerResumePoint =
MResumePoint::New(alloc(), current, pc, MResumePoint::Outer);
@ -3759,7 +3759,7 @@ IonBuilder::inlineScriptedCall(CallInfo& callInfo, JSFunction* target)
current->setOuterResumePoint(outerResumePoint);
// Pop formals again, except leave |fun| on stack for duration of call.
callInfo.popFormals(current);
callInfo.popCallStack(current);
current->push(callInfo.fun());
JSScript* calleeScript = target->nonLazyScript();
@ -4416,7 +4416,7 @@ IonBuilder::inlineGenericFallback(JSFunction* target, CallInfo& callInfo, MBasic
CallInfo fallbackInfo(alloc(), pc, callInfo.constructing(), callInfo.ignoresReturnValue());
if (!fallbackInfo.init(callInfo))
return abort(AbortReason::Alloc);
fallbackInfo.popFormals(fallbackBlock);
fallbackInfo.popCallStack(fallbackBlock);
// Generate an MCall, which uses stateful |current|.
MOZ_TRY(setCurrentAndSpecializePhis(fallbackBlock));
@ -4473,7 +4473,7 @@ IonBuilder::inlineObjectGroupFallback(CallInfo& callInfo, MBasicBlock* dispatchB
MBasicBlock* prepBlock;
MOZ_TRY_VAR(prepBlock, newBlock(dispatchBlock, pc));
graph().addBlock(prepBlock);
fallbackInfo.popFormals(prepBlock);
fallbackInfo.popCallStack(prepBlock);
// Construct a block into which the MGetPropertyCache can be moved.
// This is subtle: the pc and resume point are those of the MGetPropertyCache!
@ -4536,7 +4536,7 @@ IonBuilder::inlineCalls(CallInfo& callInfo, const InliningTargets& targets, Bool
MBasicBlock* dispatchBlock = current;
callInfo.setImplicitlyUsedUnchecked();
MOZ_TRY(callInfo.pushFormals(this, dispatchBlock));
MOZ_TRY(callInfo.pushCallStack(this, dispatchBlock));
// Patch any InlinePropertyTable to only contain functions that are
// inlineable. The InlinePropertyTable will also be patched at the end to
@ -4569,7 +4569,7 @@ IonBuilder::inlineCalls(CallInfo& callInfo, const InliningTargets& targets, Bool
// Set up stack, used to manually create a post-call resume point.
returnBlock->inheritSlots(dispatchBlock);
callInfo.popFormals(returnBlock);
callInfo.popCallStack(returnBlock);
MPhi* retPhi = MPhi::New(alloc());
returnBlock->addPhi(retPhi);
@ -4632,7 +4632,7 @@ IonBuilder::inlineCalls(CallInfo& callInfo, const InliningTargets& targets, Bool
CallInfo inlineInfo(alloc(), pc, callInfo.constructing(), callInfo.ignoresReturnValue());
if (!inlineInfo.init(callInfo))
return abort(AbortReason::Alloc);
inlineInfo.popFormals(inlineBlock);
inlineInfo.popCallStack(inlineBlock);
inlineInfo.setFun(funcDef);
if (maybeCache) {
@ -5264,6 +5264,20 @@ IonBuilder::jsop_funapplyarray(uint32_t argc)
return pushTypeBarrier(apply, types, BarrierKind::TypeSet);
}
AbortReasonOr<Ok>
CallInfo::savePriorCallStack(MIRGenerator* mir, MBasicBlock* current, size_t peekDepth)
{
MOZ_ASSERT(priorArgs_.empty());
if (!priorArgs_.reserve(peekDepth))
return mir->abort(AbortReason::Alloc);
while (peekDepth) {
priorArgs_.infallibleAppend(current->peek(0 - int32_t(peekDepth)));
peekDepth--;
}
return Ok();
}
AbortReasonOr<Ok>
IonBuilder::jsop_funapplyarguments(uint32_t argc)
{
@ -5319,6 +5333,7 @@ IonBuilder::jsop_funapplyarguments(uint32_t argc)
CallInfo callInfo(alloc(), pc, /* constructing = */ false,
/* ignoresReturnValue = */ BytecodeIsPopped(pc));
callInfo.savePriorCallStack(this, current, 4);
// Vp
MDefinition* vp = current->pop();

Просмотреть файл

@ -1192,6 +1192,9 @@ class CallInfo
MDefinition* thisArg_;
MDefinition* newTargetArg_;
MDefinitionVector args_;
// If non-empty, this corresponds to the stack prior any implicit inlining
// such as before JSOP_FUNAPPLY.
MDefinitionVector priorArgs_;
bool constructing_:1;
@ -1207,6 +1210,7 @@ class CallInfo
thisArg_(nullptr),
newTargetArg_(nullptr),
args_(alloc),
priorArgs_(alloc),
constructing_(constructing),
ignoresReturnValue_(ignoresReturnValue),
setter_(false),
@ -1250,11 +1254,30 @@ class CallInfo
return true;
}
void popFormals(MBasicBlock* current) {
// Before doing any pop to the stack, capture whatever flows into the
// instruction, such that we can restore it later.
AbortReasonOr<Ok> savePriorCallStack(MIRGenerator* mir, MBasicBlock* current, size_t peekDepth);
void popPriorCallStack(MBasicBlock* current) {
if (priorArgs_.empty())
popCallStack(current);
else
current->popn(priorArgs_.length());
}
AbortReasonOr<Ok> pushPriorCallStack(MIRGenerator* mir, MBasicBlock* current) {
if (priorArgs_.empty())
return pushCallStack(mir, current);
for (MDefinition* def : priorArgs_)
current->push(def);
return Ok();
}
void popCallStack(MBasicBlock* current) {
current->popn(numFormals());
}
AbortReasonOr<Ok> pushFormals(MIRGenerator* mir, MBasicBlock* current) {
AbortReasonOr<Ok> pushCallStack(MIRGenerator* mir, MBasicBlock* current) {
// Ensure sufficient space in the slots: needed for inlining from FUNAPPLY.
if (apply_) {
uint32_t depth = current->stackDepth() + numFormals();

Просмотреть файл

@ -846,7 +846,7 @@ IonBuilder::inlineArrayPush(CallInfo& callInfo)
// Restore the stack, such that resume points are created with the stack
// as it was before the call.
MOZ_TRY(callInfo.pushFormals(this, current));
callInfo.pushPriorCallStack(this, current);
}
MInstruction* ins = nullptr;
@ -879,7 +879,7 @@ IonBuilder::inlineArrayPush(CallInfo& callInfo)
if (callInfo.argc() > 1) {
// Fix the stack to represent the state after the call execution.
callInfo.popFormals(current);
callInfo.popPriorCallStack(current);
}
current->push(ins);