Skip to content

Commit a384d2e

Browse files
committed
Redefer function bodies that are not currently being executed and are
eligible for deferred parsing (e.g., not arrow functions, not functions-in-block). Define a force mode in which all eligible functions are redeferred on GC, as well as a 'stress' mode in which all candidates are redeferred on each stack probe.
1 parent 5b0fd25 commit a384d2e

File tree

72 files changed

+2155
-1282
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+2155
-1282
lines changed

lib/Backend/BailOut.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1773,7 +1773,7 @@ void BailOutRecord::ScheduleFunctionCodeGen(Js::ScriptFunction * function, Js::S
17731773
bailOutRecordNotConst->bailOutCount++;
17741774

17751775
Js::FunctionEntryPointInfo *entryPointInfo = function->GetFunctionEntryPointInfo();
1776-
uint8 callsCount = entryPointInfo->callsCount;
1776+
uint8 callsCount = entryPointInfo->callsCount > 255 ? 255 : static_cast<uint8>(entryPointInfo->callsCount);
17771777
RejitReason rejitReason = RejitReason::None;
17781778
bool reThunk = false;
17791779

@@ -2330,11 +2330,7 @@ void BailOutRecord::ScheduleLoopBodyCodeGen(Js::ScriptFunction * function, Js::S
23302330

23312331
entryPointInfo->totalJittedLoopIterations += entryPointInfo->jittedLoopIterationsSinceLastBailout;
23322332
entryPointInfo->jittedLoopIterationsSinceLastBailout = 0;
2333-
if (entryPointInfo->totalJittedLoopIterations > UINT8_MAX)
2334-
{
2335-
entryPointInfo->totalJittedLoopIterations = UINT8_MAX;
2336-
}
2337-
uint8 totalJittedLoopIterations = (uint8)entryPointInfo->totalJittedLoopIterations;
2333+
uint8 totalJittedLoopIterations = entryPointInfo->totalJittedLoopIterations > 255 ? 255 : static_cast<uint8>(entryPointInfo->totalJittedLoopIterations);
23382334
totalJittedLoopIterations = totalJittedLoopIterations <= Js::LoopEntryPointInfo::GetDecrLoopCountPerBailout() ? 0 : totalJittedLoopIterations - Js::LoopEntryPointInfo::GetDecrLoopCountPerBailout();
23392335

23402336
CheckPreemptiveRejit(executeFunction, bailOutKind, bailOutRecordNotConst, totalJittedLoopIterations, interpreterFrame->GetCurrentLoopNum());

lib/Backend/FunctionJITTimeInfo.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ FunctionJITTimeInfo::BuildJITTimeData(
3737

3838
jitData->inlineesBv = (BVFixedIDL*)codeGenData->inlineesBv;
3939

40-
if (codeGenData->GetFunctionInfo()->HasBody())
40+
if (codeGenData->GetFunctionInfo()->HasBody() && codeGenData->GetFunctionInfo()->GetFunctionProxy()->IsFunctionBody())
4141
{
4242
Assert(isInlinee == !!runtimeData);
4343
const Js::FunctionCodeGenRuntimeData * targetRuntimeData = nullptr;

lib/Backend/Inline.cpp

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,9 @@ uint Inline::FillInlineesDataArray(
526526
}
527527

528528
intptr_t inlineeFunctionInfoAddr = inlineeJitTimeData->GetFunctionInfoAddr();
529-
if (!PHASE_OFF(Js::PolymorphicInlinePhase, inlineeJitTimeData))
529+
#ifdef DBG
530+
if (inlineeJitTimeData->HasBody() && !PHASE_OFF(Js::PolymorphicInlinePhase, inlineeJitTimeData))
531+
#endif
530532
{
531533
const FunctionJITTimeInfo* rightInlineeJitTimeData = inlineeJitTimeData->GetJitTimeDataFromFunctionInfoAddr(inlineeFunctionInfoAddr);
532534

@@ -573,28 +575,31 @@ void Inline::FillInlineesDataArrayUsingFixedMethods(
573575
JITTimeFunctionBody* inlineeFuncBody = nullptr;
574576
while (inlineeJitTimeData)
575577
{
576-
inlineeFuncBody = inlineeJitTimeData->GetBody();
577-
if (!PHASE_OFF(Js::PolymorphicInlinePhase, inlineeJitTimeData) && !PHASE_OFF(Js::PolymorphicInlineFixedMethodsPhase, inlineeJitTimeData))
578+
if (inlineeJitTimeData->HasBody())
578579
{
579-
const FunctionJITTimeInfo * jitTimeData = inlineeJitTimeData->GetJitTimeDataFromFunctionInfoAddr(inlineeJitTimeData->GetFunctionInfoAddr());
580-
if (jitTimeData)
580+
inlineeFuncBody = inlineeJitTimeData->GetBody();
581+
if (!PHASE_OFF(Js::PolymorphicInlinePhase, inlineeJitTimeData) && !PHASE_OFF(Js::PolymorphicInlineFixedMethodsPhase, inlineeJitTimeData))
581582
{
582-
for (uint16 i = 0; i < cachedFixedInlineeCount; i++)
583+
const FunctionJITTimeInfo * jitTimeData = inlineeJitTimeData->GetJitTimeDataFromFunctionInfoAddr(inlineeJitTimeData->GetFunctionInfoAddr());
584+
if (jitTimeData)
583585
{
584-
if (inlineeJitTimeData->GetFunctionInfoAddr() == fixedFieldInfoArray[i].GetFuncInfoAddr())
586+
for (uint16 i = 0; i < cachedFixedInlineeCount; i++)
585587
{
586-
inlineesDataArray[i] = inlineeJitTimeData->GetJitTimeDataFromFunctionInfoAddr(inlineeJitTimeData->GetFunctionInfoAddr());
587-
break;
588+
if (inlineeJitTimeData->GetFunctionInfoAddr() == fixedFieldInfoArray[i].GetFuncInfoAddr())
589+
{
590+
inlineesDataArray[i] = inlineeJitTimeData->GetJitTimeDataFromFunctionInfoAddr(inlineeJitTimeData->GetFunctionInfoAddr());
591+
break;
592+
}
588593
}
589594
}
590-
}
591-
else
592-
{
595+
else
596+
{
593597
#if defined(DBG_DUMP) || defined(ENABLE_DEBUG_CONFIG_OPTIONS)
594-
char16 debugStringBuffer[MAX_FUNCTION_BODY_DEBUG_STRING_SIZE];
598+
char16 debugStringBuffer[MAX_FUNCTION_BODY_DEBUG_STRING_SIZE];
595599
#endif
596-
POLYMORPHIC_INLINE_TESTTRACE(_u("INLINING (Polymorphic): Missing jit time data skipped inlinee\tInlinee: %s (%s)\n"),
597-
inlineeFuncBody->GetDisplayName(), inlineeJitTimeData->GetDebugNumberSet(debugStringBuffer));
600+
POLYMORPHIC_INLINE_TESTTRACE(_u("INLINING (Polymorphic): Missing jit time data skipped inlinee\tInlinee: %s (%s)\n"),
601+
inlineeFuncBody->GetDisplayName(), inlineeJitTimeData->GetDebugNumberSet(debugStringBuffer));
602+
}
598603
}
599604
}
600605
inlineeJitTimeData = inlineeJitTimeData->GetNext();
@@ -1028,7 +1033,7 @@ Inline::InlinePolymorphicFunction(IR::Instr *callInstr, const FunctionJITTimeInf
10281033
IR::RegOpnd* functionObject = callInstr->GetSrc1()->AsRegOpnd();
10291034
dispatchStartLabel->InsertBefore(IR::BranchInstr::New(Js::OpCode::BrAddr_A, inlineeStartLabel,
10301035
IR::IndirOpnd::New(functionObject, Js::JavascriptFunction::GetOffsetOfFunctionInfo(), TyMachPtr, dispatchStartLabel->m_func),
1031-
IR::AddrOpnd::New(inlineesDataArray[i]->GetBody()->GetAddr(), IR::AddrOpndKindDynamicFunctionBody, dispatchStartLabel->m_func), dispatchStartLabel->m_func));
1036+
IR::AddrOpnd::New(inlineesDataArray[i]->GetFunctionInfoAddr(), IR::AddrOpndKindDynamicFunctionBody, dispatchStartLabel->m_func), dispatchStartLabel->m_func));
10321037
}
10331038

10341039
CompletePolymorphicInlining(callInstr, returnValueOpnd, doneLabel, dispatchStartLabel, /*ldMethodFldInstr*/nullptr, IR::BailOutOnPolymorphicInlineFunction);
@@ -4143,14 +4148,14 @@ Inline::InsertJsFunctionCheck(IR::Instr *callInstr, IR::Instr *insertBeforeInstr
41434148
}
41444149

41454150
void
4146-
Inline::InsertFunctionBodyCheck(IR::Instr *callInstr, IR::Instr *insertBeforeInstr, IR::Instr* bailoutInstr, const FunctionJITTimeInfo *funcInfo)
4151+
Inline::InsertFunctionInfoCheck(IR::Instr *callInstr, IR::Instr *insertBeforeInstr, IR::Instr* bailoutInstr, const FunctionJITTimeInfo *funcInfo)
41474152
{
41484153
// if (JavascriptFunction::FromVar(r1)->functionInfo != funcInfo) goto noInlineLabel
41494154
// BrNeq_I4 noInlineLabel, r1->functionInfo, funcInfo
4150-
IR::IndirOpnd* funcBody = IR::IndirOpnd::New(callInstr->GetSrc1()->AsRegOpnd(), Js::JavascriptFunction::GetOffsetOfFunctionInfo(), TyMachPtr, callInstr->m_func);
4151-
IR::AddrOpnd* inlinedFuncBody = IR::AddrOpnd::New(funcInfo->GetFunctionInfoAddr(), IR::AddrOpndKindDynamicFunctionBody, callInstr->m_func);
4152-
bailoutInstr->SetSrc1(funcBody);
4153-
bailoutInstr->SetSrc2(inlinedFuncBody);
4155+
IR::IndirOpnd* opndFuncInfo = IR::IndirOpnd::New(callInstr->GetSrc1()->AsRegOpnd(), Js::JavascriptFunction::GetOffsetOfFunctionInfo(), TyMachPtr, callInstr->m_func);
4156+
IR::AddrOpnd* inlinedFuncInfo = IR::AddrOpnd::New(funcInfo->GetFunctionInfoAddr(), IR::AddrOpndKindDynamicFunctionInfo, callInstr->m_func);
4157+
bailoutInstr->SetSrc1(opndFuncInfo);
4158+
bailoutInstr->SetSrc2(inlinedFuncInfo);
41544159

41554160
insertBeforeInstr->InsertBefore(bailoutInstr);
41564161
}
@@ -4188,7 +4193,7 @@ Inline::PrepareInsertionPoint(IR::Instr *callInstr, const FunctionJITTimeInfo *f
41884193
InsertFunctionTypeIdCheck(callInstr, insertBeforeInstr, bailOutIfNotJsFunction);
41894194

41904195
// 3. Bailout if function body doesn't match funcInfo
4191-
InsertFunctionBodyCheck(callInstr, insertBeforeInstr, primaryBailOutInstr, funcInfo);
4196+
InsertFunctionInfoCheck(callInstr, insertBeforeInstr, primaryBailOutInstr, funcInfo);
41924197

41934198
return primaryBailOutInstr;
41944199
}

lib/Backend/Inline.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ class Inline
129129
void InsertObjectCheck(IR::Instr *callInstr, IR::Instr* insertBeforeInstr, IR::Instr*bailOutInstr);
130130
void InsertFunctionTypeIdCheck(IR::Instr *callInstr, IR::Instr* insertBeforeInstr, IR::Instr*bailOutInstr);
131131
void InsertJsFunctionCheck(IR::Instr *callInstr, IR::Instr *insertBeforeInstr, IR::BailOutKind bailOutKind);
132-
void InsertFunctionBodyCheck(IR::Instr *callInstr, IR::Instr *insertBeforeInstr, IR::Instr* bailoutInstr, const FunctionJITTimeInfo *funcInfo);
132+
void InsertFunctionInfoCheck(IR::Instr *callInstr, IR::Instr *insertBeforeInstr, IR::Instr* bailoutInstr, const FunctionJITTimeInfo *funcInfo);
133133
void InsertFunctionObjectCheck(IR::Instr *callInstr, IR::Instr *insertBeforeInstr, IR::Instr* bailoutInstr, const FunctionJITTimeInfo *funcInfo);
134134

135135
void TryResetObjTypeSpecFldInfoOn(IR::PropertySymOpnd* propertySymOpnd);

lib/Backend/InliningDecider.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ uint InliningDecider::InlinePolymorphicCallSite(Js::FunctionBody *const inliner,
151151
AssertMsg(inlineeCount >= 2, "There are at least two polymorphic call site");
152152
break;
153153
}
154-
if (Inline(inliner, functionBodyArray[inlineeCount], isConstructorCall, true /*isPolymorphicCall*/, 0, profiledCallSiteId, recursiveInlineDepth, false))
154+
if (Inline(inliner, functionBodyArray[inlineeCount]->GetFunctionInfo(), isConstructorCall, true /*isPolymorphicCall*/, 0, profiledCallSiteId, recursiveInlineDepth, false))
155155
{
156156
canInlineArray[inlineeCount] = true;
157157
actualInlineeCount++;
@@ -272,7 +272,7 @@ Js::FunctionInfo *InliningDecider::Inline(Js::FunctionBody *const inliner, Js::F
272272
#endif
273273

274274
this->bytecodeInlinedCount += inlinee->GetByteCodeCount();
275-
return inlinee;
275+
return inlinee->GetFunctionInfo();
276276
}
277277

278278
Js::OpCode builtInInlineCandidateOpCode;

0 commit comments

Comments
 (0)