Skip to content

Commit

Permalink
Redefer function bodies that are not currently being executed and are
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
pleath committed Nov 8, 2016
1 parent c2405ae commit 0826835
Show file tree
Hide file tree
Showing 72 changed files with 2,143 additions and 1,273 deletions.
8 changes: 2 additions & 6 deletions lib/Backend/BailOut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1773,7 +1773,7 @@ void BailOutRecord::ScheduleFunctionCodeGen(Js::ScriptFunction * function, Js::S
bailOutRecordNotConst->bailOutCount++;

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

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

entryPointInfo->totalJittedLoopIterations += entryPointInfo->jittedLoopIterationsSinceLastBailout;
entryPointInfo->jittedLoopIterationsSinceLastBailout = 0;
if (entryPointInfo->totalJittedLoopIterations > UINT8_MAX)
{
entryPointInfo->totalJittedLoopIterations = UINT8_MAX;
}
uint8 totalJittedLoopIterations = (uint8)entryPointInfo->totalJittedLoopIterations;
uint8 totalJittedLoopIterations = entryPointInfo->totalJittedLoopIterations > 255 ? 255 : static_cast<uint8>(entryPointInfo->totalJittedLoopIterations);
totalJittedLoopIterations = totalJittedLoopIterations <= Js::LoopEntryPointInfo::GetDecrLoopCountPerBailout() ? 0 : totalJittedLoopIterations - Js::LoopEntryPointInfo::GetDecrLoopCountPerBailout();

CheckPreemptiveRejit(executeFunction, bailOutKind, bailOutRecordNotConst, totalJittedLoopIterations, interpreterFrame->GetCurrentLoopNum());
Expand Down
2 changes: 1 addition & 1 deletion lib/Backend/FunctionJITTimeInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ FunctionJITTimeInfo::BuildJITTimeData(

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

if (codeGenData->GetFunctionInfo()->HasBody())
if (codeGenData->GetFunctionInfo()->HasBody() && codeGenData->GetFunctionInfo()->GetFunctionProxy()->IsFunctionBody())
{
Assert(isInlinee == !!runtimeData);
const Js::FunctionCodeGenRuntimeData * targetRuntimeData = nullptr;
Expand Down
49 changes: 27 additions & 22 deletions lib/Backend/Inline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,9 @@ uint Inline::FillInlineesDataArray(
}

intptr_t inlineeFunctionInfoAddr = inlineeJitTimeData->GetFunctionInfoAddr();
if (!PHASE_OFF(Js::PolymorphicInlinePhase, inlineeJitTimeData))
#ifdef DBG
if (inlineeJitTimeData->HasBody() && !PHASE_OFF(Js::PolymorphicInlinePhase, inlineeJitTimeData))
#endif
{
const FunctionJITTimeInfo* rightInlineeJitTimeData = inlineeJitTimeData->GetJitTimeDataFromFunctionInfoAddr(inlineeFunctionInfoAddr);

Expand Down Expand Up @@ -571,28 +573,31 @@ void Inline::FillInlineesDataArrayUsingFixedMethods(
JITTimeFunctionBody* inlineeFuncBody = nullptr;
while (inlineeJitTimeData)
{
inlineeFuncBody = inlineeJitTimeData->GetBody();
if (!PHASE_OFF(Js::PolymorphicInlinePhase, inlineeJitTimeData) && !PHASE_OFF(Js::PolymorphicInlineFixedMethodsPhase, inlineeJitTimeData))
if (inlineeJitTimeData->HasBody())
{
const FunctionJITTimeInfo * jitTimeData = inlineeJitTimeData->GetJitTimeDataFromFunctionInfoAddr(inlineeJitTimeData->GetFunctionInfoAddr());
if (jitTimeData)
inlineeFuncBody = inlineeJitTimeData->GetBody();
if (!PHASE_OFF(Js::PolymorphicInlinePhase, inlineeJitTimeData) && !PHASE_OFF(Js::PolymorphicInlineFixedMethodsPhase, inlineeJitTimeData))
{
for (uint16 i = 0; i < cachedFixedInlineeCount; i++)
const FunctionJITTimeInfo * jitTimeData = inlineeJitTimeData->GetJitTimeDataFromFunctionInfoAddr(inlineeJitTimeData->GetFunctionInfoAddr());
if (jitTimeData)
{
if (inlineeJitTimeData->GetFunctionInfoAddr() == fixedFieldInfoArray[i].GetFuncInfoAddr())
for (uint16 i = 0; i < cachedFixedInlineeCount; i++)
{
inlineesDataArray[i] = inlineeJitTimeData->GetJitTimeDataFromFunctionInfoAddr(inlineeJitTimeData->GetFunctionInfoAddr());
break;
if (inlineeJitTimeData->GetFunctionInfoAddr() == fixedFieldInfoArray[i].GetFuncInfoAddr())
{
inlineesDataArray[i] = inlineeJitTimeData->GetJitTimeDataFromFunctionInfoAddr(inlineeJitTimeData->GetFunctionInfoAddr());
break;
}
}
}
}
else
{
else
{
#if defined(DBG_DUMP) || defined(ENABLE_DEBUG_CONFIG_OPTIONS)
char16 debugStringBuffer[MAX_FUNCTION_BODY_DEBUG_STRING_SIZE];
char16 debugStringBuffer[MAX_FUNCTION_BODY_DEBUG_STRING_SIZE];
#endif
POLYMORPHIC_INLINE_TESTTRACE(_u("INLINING (Polymorphic): Missing jit time data skipped inlinee\tInlinee: %s (%s)\n"),
inlineeFuncBody->GetDisplayName(), inlineeJitTimeData->GetDebugNumberSet(debugStringBuffer));
POLYMORPHIC_INLINE_TESTTRACE(_u("INLINING (Polymorphic): Missing jit time data skipped inlinee\tInlinee: %s (%s)\n"),
inlineeFuncBody->GetDisplayName(), inlineeJitTimeData->GetDebugNumberSet(debugStringBuffer));
}
}
}
inlineeJitTimeData = inlineeJitTimeData->GetNext();
Expand Down Expand Up @@ -1026,7 +1031,7 @@ Inline::InlinePolymorphicFunction(IR::Instr *callInstr, const FunctionJITTimeInf
IR::RegOpnd* functionObject = callInstr->GetSrc1()->AsRegOpnd();
dispatchStartLabel->InsertBefore(IR::BranchInstr::New(Js::OpCode::BrAddr_A, inlineeStartLabel,
IR::IndirOpnd::New(functionObject, Js::JavascriptFunction::GetOffsetOfFunctionInfo(), TyMachPtr, dispatchStartLabel->m_func),
IR::AddrOpnd::New(inlineesDataArray[i]->GetBody()->GetAddr(), IR::AddrOpndKindDynamicFunctionBody, dispatchStartLabel->m_func), dispatchStartLabel->m_func));
IR::AddrOpnd::New(inlineesDataArray[i]->GetFunctionInfoAddr(), IR::AddrOpndKindDynamicFunctionBody, dispatchStartLabel->m_func), dispatchStartLabel->m_func));
}

CompletePolymorphicInlining(callInstr, returnValueOpnd, doneLabel, dispatchStartLabel, /*ldMethodFldInstr*/nullptr, IR::BailOutOnPolymorphicInlineFunction);
Expand Down Expand Up @@ -4124,14 +4129,14 @@ Inline::InsertJsFunctionCheck(IR::Instr *callInstr, IR::Instr *insertBeforeInstr
}

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

insertBeforeInstr->InsertBefore(bailoutInstr);
}
Expand Down Expand Up @@ -4169,7 +4174,7 @@ Inline::PrepareInsertionPoint(IR::Instr *callInstr, const FunctionJITTimeInfo *f
InsertFunctionTypeIdCheck(callInstr, insertBeforeInstr, bailOutIfNotJsFunction);

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

return primaryBailOutInstr;
}
Expand Down
2 changes: 1 addition & 1 deletion lib/Backend/Inline.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ class Inline
void InsertObjectCheck(IR::Instr *callInstr, IR::Instr* insertBeforeInstr, IR::Instr*bailOutInstr);
void InsertFunctionTypeIdCheck(IR::Instr *callInstr, IR::Instr* insertBeforeInstr, IR::Instr*bailOutInstr);
void InsertJsFunctionCheck(IR::Instr *callInstr, IR::Instr *insertBeforeInstr, IR::BailOutKind bailOutKind);
void InsertFunctionBodyCheck(IR::Instr *callInstr, IR::Instr *insertBeforeInstr, IR::Instr* bailoutInstr, const FunctionJITTimeInfo *funcInfo);
void InsertFunctionInfoCheck(IR::Instr *callInstr, IR::Instr *insertBeforeInstr, IR::Instr* bailoutInstr, const FunctionJITTimeInfo *funcInfo);
void InsertFunctionObjectCheck(IR::Instr *callInstr, IR::Instr *insertBeforeInstr, IR::Instr* bailoutInstr, const FunctionJITTimeInfo *funcInfo);

void TryResetObjTypeSpecFldInfoOn(IR::PropertySymOpnd* propertySymOpnd);
Expand Down
4 changes: 2 additions & 2 deletions lib/Backend/InliningDecider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ uint InliningDecider::InlinePolymorphicCallSite(Js::FunctionBody *const inliner,
AssertMsg(inlineeCount >= 2, "There are at least two polymorphic call site");
break;
}
if (Inline(inliner, functionBodyArray[inlineeCount], isConstructorCall, true /*isPolymorphicCall*/, 0, profiledCallSiteId, recursiveInlineDepth, false))
if (Inline(inliner, functionBodyArray[inlineeCount]->GetFunctionInfo(), isConstructorCall, true /*isPolymorphicCall*/, 0, profiledCallSiteId, recursiveInlineDepth, false))
{
canInlineArray[inlineeCount] = true;
actualInlineeCount++;
Expand Down Expand Up @@ -272,7 +272,7 @@ Js::FunctionInfo *InliningDecider::Inline(Js::FunctionBody *const inliner, Js::F
#endif

this->bytecodeInlinedCount += inlinee->GetByteCodeCount();
return inlinee;
return inlinee->GetFunctionInfo();
}

Js::OpCode builtInInlineCandidateOpCode;
Expand Down
Loading

0 comments on commit 0826835

Please sign in to comment.