зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
52aacbca78
Коммит
81d226d76e
|
@ -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);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче