Skip to content

Commit 85818fb

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). This is experimental behavior, off by default. Define an 'on' 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. This change is built on a previous PR that refactors the FunctionBody hierarchy to make it easier to toggle between deferred and fully-compiled states.
1 parent 3373b34 commit 85818fb

Some content is hidden

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

68 files changed

+1813
-1141
lines changed

lib/Backend/BailOut.cpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1763,7 +1763,7 @@ void BailOutRecord::ScheduleFunctionCodeGen(Js::ScriptFunction * function, Js::S
17631763
bailOutRecordNotConst->bailOutCount++;
17641764

17651765
Js::FunctionEntryPointInfo *entryPointInfo = function->GetFunctionEntryPointInfo();
1766-
uint8 callsCount = entryPointInfo->callsCount;
1766+
uint32 callsCount = entryPointInfo->callsCount;
17671767
RejitReason rejitReason = RejitReason::None;
17681768
bool reThunk = false;
17691769

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

23212321
entryPointInfo->totalJittedLoopIterations += entryPointInfo->jittedLoopIterationsSinceLastBailout;
23222322
entryPointInfo->jittedLoopIterationsSinceLastBailout = 0;
2323-
if (entryPointInfo->totalJittedLoopIterations > UINT8_MAX)
2324-
{
2325-
entryPointInfo->totalJittedLoopIterations = UINT8_MAX;
2326-
}
2327-
uint8 totalJittedLoopIterations = (uint8)entryPointInfo->totalJittedLoopIterations;
2323+
uint32 totalJittedLoopIterations = (uint8)entryPointInfo->totalJittedLoopIterations;
23282324
totalJittedLoopIterations = totalJittedLoopIterations <= Js::LoopEntryPointInfo::GetDecrLoopCountPerBailout() ? 0 : totalJittedLoopIterations - Js::LoopEntryPointInfo::GetDecrLoopCountPerBailout();
23292325

23302326
CheckPreemptiveRejit(executeFunction, bailOutKind, bailOutRecordNotConst, totalJittedLoopIterations, interpreterFrame->GetCurrentLoopNum());
@@ -2608,7 +2604,7 @@ void BailOutRecord::ScheduleLoopBodyCodeGen(Js::ScriptFunction * function, Js::S
26082604
}
26092605
}
26102606

2611-
void BailOutRecord::CheckPreemptiveRejit(Js::FunctionBody* executeFunction, IR::BailOutKind bailOutKind, BailOutRecord* bailoutRecord, uint8& callsOrIterationsCount, int loopNumber)
2607+
void BailOutRecord::CheckPreemptiveRejit(Js::FunctionBody* executeFunction, IR::BailOutKind bailOutKind, BailOutRecord* bailoutRecord, uint32& callsOrIterationsCount, int loopNumber)
26122608
{
26132609
if (bailOutKind == IR::BailOutOnNoProfile && executeFunction->IncrementBailOnMisingProfileCount() > CONFIG_FLAG(BailOnNoProfileLimit))
26142610
{

lib/Backend/BailOut.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ class BailOutRecord
255255

256256
static void ScheduleFunctionCodeGen(Js::ScriptFunction * function, Js::ScriptFunction * innerMostInlinee, BailOutRecord const * bailOutRecord, IR::BailOutKind bailOutKind, Js::ImplicitCallFlags savedImplicitCallFlags, void * returnAddress);
257257
static void ScheduleLoopBodyCodeGen(Js::ScriptFunction * function, Js::ScriptFunction * innerMostInlinee, BailOutRecord const * bailOutRecord, IR::BailOutKind bailOutKind);
258-
static void CheckPreemptiveRejit(Js::FunctionBody* executeFunction, IR::BailOutKind bailOutKind, BailOutRecord* bailoutRecord, uint8& callsOrIterationsCount, int loopNumber);
258+
static void CheckPreemptiveRejit(Js::FunctionBody* executeFunction, IR::BailOutKind bailOutKind, BailOutRecord* bailoutRecord, uint32& callsOrIterationsCount, int loopNumber);
259259
void RestoreValues(IR::BailOutKind bailOutKind, Js::JavascriptCallStackLayout * layout, Js::InterpreterStackFrame * newInstance, Js::ScriptContext * scriptContext,
260260
bool fromLoopBody, Js::Var * registerSaves, BailOutReturnValue * returnValue, Js::Var* pArgumentsObject, Js::Var branchValue = nullptr, void* returnAddress = nullptr, bool useStartCall = true, void * argoutRestoreAddress = nullptr) const;
261261
void RestoreValues(IR::BailOutKind bailOutKind, Js::JavascriptCallStackLayout * layout, uint count, __in_ecount_opt(count) int * offsets, int argOutSlotId,

lib/Backend/Inline.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1026,7 +1026,7 @@ Inline::InlinePolymorphicFunction(IR::Instr *callInstr, const FunctionJITTimeInf
10261026
IR::RegOpnd* functionObject = callInstr->GetSrc1()->AsRegOpnd();
10271027
dispatchStartLabel->InsertBefore(IR::BranchInstr::New(Js::OpCode::BrAddr_A, inlineeStartLabel,
10281028
IR::IndirOpnd::New(functionObject, Js::JavascriptFunction::GetOffsetOfFunctionInfo(), TyMachPtr, dispatchStartLabel->m_func),
1029-
IR::AddrOpnd::New(inlineesDataArray[i]->GetBody()->GetAddr(), IR::AddrOpndKindDynamicFunctionBody, dispatchStartLabel->m_func), dispatchStartLabel->m_func));
1029+
IR::AddrOpnd::New((void*)inlineesDataArray[i], IR::AddrOpndKindDynamicFunctionBody, dispatchStartLabel->m_func), dispatchStartLabel->m_func));
10301030
}
10311031

10321032
CompletePolymorphicInlining(callInstr, returnValueOpnd, doneLabel, dispatchStartLabel, /*ldMethodFldInstr*/nullptr, IR::BailOutOnPolymorphicInlineFunction);
@@ -4063,14 +4063,14 @@ Inline::InsertJsFunctionCheck(IR::Instr *callInstr, IR::Instr *insertBeforeInstr
40634063
}
40644064

40654065
void
4066-
Inline::InsertFunctionBodyCheck(IR::Instr *callInstr, IR::Instr *insertBeforeInstr, IR::Instr* bailoutInstr, const FunctionJITTimeInfo *funcInfo)
4066+
Inline::InsertFunctionInfoCheck(IR::Instr *callInstr, IR::Instr *insertBeforeInstr, IR::Instr* bailoutInstr, const FunctionJITTimeInfo *funcInfo)
40674067
{
40684068
// if (JavascriptFunction::FromVar(r1)->functionInfo != funcInfo) goto noInlineLabel
40694069
// BrNeq_I4 noInlineLabel, r1->functionInfo, funcInfo
4070-
IR::IndirOpnd* funcBody = IR::IndirOpnd::New(callInstr->GetSrc1()->AsRegOpnd(), Js::JavascriptFunction::GetOffsetOfFunctionInfo(), TyMachPtr, callInstr->m_func);
4071-
IR::AddrOpnd* inlinedFuncBody = IR::AddrOpnd::New(funcInfo->GetFunctionInfoAddr(), IR::AddrOpndKindDynamicFunctionBody, callInstr->m_func);
4072-
bailoutInstr->SetSrc1(funcBody);
4073-
bailoutInstr->SetSrc2(inlinedFuncBody);
4070+
IR::IndirOpnd* opndFuncInfo = IR::IndirOpnd::New(callInstr->GetSrc1()->AsRegOpnd(), Js::JavascriptFunction::GetOffsetOfFunctionInfo(), TyMachPtr, callInstr->m_func);
4071+
IR::AddrOpnd* inlinedFuncInfo = IR::AddrOpnd::New(funcInfo->GetFunctionInfoAddr(), IR::AddrOpndKindDynamicFunctionInfo, callInstr->m_func);
4072+
bailoutInstr->SetSrc1(opndFuncInfo);
4073+
bailoutInstr->SetSrc2(inlinedFuncInfo);
40744074

40754075
insertBeforeInstr->InsertBefore(bailoutInstr);
40764076
}
@@ -4108,7 +4108,7 @@ Inline::PrepareInsertionPoint(IR::Instr *callInstr, const FunctionJITTimeInfo *f
41084108
InsertFunctionTypeIdCheck(callInstr, insertBeforeInstr, bailOutIfNotJsFunction);
41094109

41104110
// 3. Bailout if function body doesn't match funcInfo
4111-
InsertFunctionBodyCheck(callInstr, insertBeforeInstr, primaryBailOutInstr, funcInfo);
4111+
InsertFunctionInfoCheck(callInstr, insertBeforeInstr, primaryBailOutInstr, funcInfo);
41124112

41134113
return primaryBailOutInstr;
41144114
}

lib/Backend/Inline.h

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

132132
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)