Skip to content

Commit 8f39283

Browse files
committed
Restructure the FunctionBody hierarchy so that FunctionInfo is a standalone proxy from which FunctionProxy does not inherit, and FunctionProxy is the basis for all the representations of user functions (FunctionBody, etc.). FunctionInfo still points to the FunctionProxy that implements the function, and FunctionProxy points to FunctionInfo. Do this to facilitate re-deferral and to maximize the memory benefit.
1 parent eaf47df commit 8f39283

30 files changed

+532
-272
lines changed

lib/Backend/Inline.cpp

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -499,8 +499,8 @@ uint Inline::FillInlineesDataArray(
499499
Js::FunctionBody *inlineeFunctionBody = inlineeJitTimeData->GetFunctionBody();
500500
if (!PHASE_OFF(Js::PolymorphicInlinePhase, inlineeFunctionBody))
501501
{
502-
const Js::FunctionCodeGenJitTimeData* rightInlineeJitTimeData = inlineeJitTimeData->GetJitTimeDataFromFunctionInfo(inlineeFunctionBody);
503-
const Js::FunctionCodeGenRuntimeData* rightInlineeRuntimeData = inlineeRuntimeData->GetRuntimeDataFromFunctionInfo(inlineeFunctionBody);
502+
const Js::FunctionCodeGenJitTimeData* rightInlineeJitTimeData = inlineeJitTimeData->GetJitTimeDataFromFunctionInfo(inlineeFunctionBody->GetFunctionInfo());
503+
const Js::FunctionCodeGenRuntimeData* rightInlineeRuntimeData = inlineeRuntimeData->GetRuntimeDataFromFunctionInfo(inlineeFunctionBody->GetFunctionInfo());
504504

505505
if (rightInlineeJitTimeData)
506506
{
@@ -551,15 +551,15 @@ void Inline::FillInlineesDataArrayUsingFixedMethods(
551551
inlineeFuncBody = inlineeJitTimeData->GetFunctionBody();
552552
if (!PHASE_OFF(Js::PolymorphicInlinePhase, inlineeFuncBody) && !PHASE_OFF(Js::PolymorphicInlineFixedMethodsPhase, inlineeFuncBody))
553553
{
554-
const Js::FunctionCodeGenJitTimeData* jitTimeData = inlineeJitTimeData->GetJitTimeDataFromFunctionInfo(inlineeFuncBody);
554+
const Js::FunctionCodeGenJitTimeData* jitTimeData = inlineeJitTimeData->GetJitTimeDataFromFunctionInfo(inlineeFuncBody->GetFunctionInfo());
555555
if (jitTimeData)
556556
{
557557
for (uint16 i = 0; i < cachedFixedInlineeCount; i++)
558558
{
559559
if (inlineeFuncBody == ((Js::JavascriptFunction*)(fixedFieldInfoArray[i].fieldValue))->GetFunctionBody())
560560
{
561-
inlineesDataArray[i].inlineeJitTimeData = inlineeJitTimeData->GetJitTimeDataFromFunctionInfo(inlineeFuncBody);
562-
inlineesDataArray[i].inlineeRuntimeData = inlineeRuntimeData->GetRuntimeDataFromFunctionInfo(inlineeFuncBody);
561+
inlineesDataArray[i].inlineeJitTimeData = inlineeJitTimeData->GetJitTimeDataFromFunctionInfo(inlineeFuncBody->GetFunctionInfo());
562+
inlineesDataArray[i].inlineeRuntimeData = inlineeRuntimeData->GetRuntimeDataFromFunctionInfo(inlineeFuncBody->GetFunctionInfo());
563563
inlineesDataArray[i].functionBody = inlineeFuncBody;
564564
break;
565565
}
@@ -759,7 +759,7 @@ Inline::InlinePolymorphicFunctionUsingFixedMethods(IR::Instr *callInstr, const J
759759
if (i == 0)
760760
{
761761
// Do all the general, non-function-object-specific checks just once.
762-
if (!TryOptimizeCallInstrWithFixedMethod(callInstr, (Js::FunctionInfo*)(inlineesDataArray[i].functionBody), true, false, false, true /*isInlined*/, safeThis, true /*dontOptimizeJustCheck*/, i))
762+
if (!TryOptimizeCallInstrWithFixedMethod(callInstr, inlineesDataArray[i].functionBody->GetFunctionInfo(), true, false, false, true /*isInlined*/, safeThis, true /*dontOptimizeJustCheck*/, i))
763763
{
764764
POLYMORPHIC_INLINE_TESTTRACE(_u("INLINING (Polymorphic; Using Fixed Methods): Skip Inline: can't optimize using Fixed Methods %d (Max: %d)\tInlinee: %s (%s):\tCaller: %s (%s)\n"),
765765
inlineeCount, Js::DynamicProfileInfo::maxPolymorphicInliningSize,
@@ -771,7 +771,7 @@ Inline::InlinePolymorphicFunctionUsingFixedMethods(IR::Instr *callInstr, const J
771771
else
772772
{
773773
if (methodPropertyOpnd->GetFieldValueAsFixedFunction(i) &&
774-
methodPropertyOpnd->GetFieldValueAsFixedFunction(i)->GetFunctionInfo() != (Js::FunctionInfo*)(inlineesDataArray[i].functionBody))
774+
methodPropertyOpnd->GetFieldValueAsFixedFunction(i)->GetFunctionInfo() != inlineesDataArray[i].functionBody->GetFunctionInfo())
775775
{
776776
POLYMORPHIC_INLINE_TESTTRACE(_u("INLINING (Polymorphic; Using Fixed Methods): Skip Inline: can't optimize using Fixed Methods %d (Max: %d)\tInlinee: %s (%s):\tCaller: %s (%s)\n"),
777777
inlineeCount, Js::DynamicProfileInfo::maxPolymorphicInliningSize,
@@ -1012,7 +1012,7 @@ Inline::InlinePolymorphicFunction(IR::Instr *callInstr, const Js::FunctionCodeGe
10121012
IR::RegOpnd* functionObject = callInstr->GetSrc1()->AsRegOpnd();
10131013
dispatchStartLabel->InsertBefore(IR::BranchInstr::New(Js::OpCode::BrAddr_A, inlineeStartLabel,
10141014
IR::IndirOpnd::New(functionObject, Js::JavascriptFunction::GetOffsetOfFunctionInfo(), TyMachPtr, dispatchStartLabel->m_func),
1015-
IR::AddrOpnd::New(inlineesDataArray[i].functionBody, IR::AddrOpndKindDynamicFunctionBody, dispatchStartLabel->m_func), dispatchStartLabel->m_func));
1015+
IR::AddrOpnd::New(inlineesDataArray[i].functionBody->GetFunctionInfo(), IR::AddrOpndKindDynamicFunctionInfo, dispatchStartLabel->m_func), dispatchStartLabel->m_func));
10161016
}
10171017

10181018
CompletePolymorphicInlining(callInstr, returnValueOpnd, doneLabel, dispatchStartLabel, /*ldMethodFldInstr*/nullptr, IR::BailOutOnPolymorphicInlineFunction);
@@ -3440,11 +3440,11 @@ Inline::InlineFunctionCommon(IR::Instr *callInstr, StackSym* originalCallTargetS
34403440
#endif
34413441
if (callInstr->m_opcode == Js::OpCode::CallIFixed)
34423442
{
3443-
Assert(callInstr->GetFixedFunction()->GetFunctionInfo() == funcBody);
3443+
Assert(callInstr->GetFixedFunction()->GetFunctionInfo() == funcBody->GetFunctionInfo());
34443444
}
34453445
else
34463446
{
3447-
PrepareInsertionPoint(callInstr, funcBody, inlineBailoutChecksBeforeInstr);
3447+
PrepareInsertionPoint(callInstr, funcBody->GetFunctionInfo(), inlineBailoutChecksBeforeInstr);
34483448
}
34493449

34503450
Assert(formalCount <= Js::InlineeCallInfo::MaxInlineeArgoutCount);
@@ -3961,14 +3961,14 @@ Inline::InsertJsFunctionCheck(IR::Instr *callInstr, IR::Instr *insertBeforeInstr
39613961
}
39623962

39633963
void
3964-
Inline::InsertFunctionBodyCheck(IR::Instr *callInstr, IR::Instr *insertBeforeInstr, IR::Instr* bailoutInstr, Js::FunctionInfo *funcInfo)
3964+
Inline::InsertFunctionInfoCheck(IR::Instr *callInstr, IR::Instr *insertBeforeInstr, IR::Instr* bailoutInstr, Js::FunctionInfo *funcInfo)
39653965
{
39663966
// if (JavascriptFunction::FromVar(r1)->functionInfo != funcInfo) goto noInlineLabel
39673967
// BrNeq_I4 noInlineLabel, r1->functionInfo, funcInfo
3968-
IR::IndirOpnd* funcBody = IR::IndirOpnd::New(callInstr->GetSrc1()->AsRegOpnd(), Js::JavascriptFunction::GetOffsetOfFunctionInfo(), TyMachPtr, callInstr->m_func);
3969-
IR::AddrOpnd* inlinedFuncBody = IR::AddrOpnd::New(funcInfo, IR::AddrOpndKindDynamicFunctionBody, callInstr->m_func);
3970-
bailoutInstr->SetSrc1(funcBody);
3971-
bailoutInstr->SetSrc2(inlinedFuncBody);
3968+
IR::IndirOpnd* opndFuncInfo = IR::IndirOpnd::New(callInstr->GetSrc1()->AsRegOpnd(), Js::JavascriptFunction::GetOffsetOfFunctionInfo(), TyMachPtr, callInstr->m_func);
3969+
IR::AddrOpnd* inlinedFuncInfo = IR::AddrOpnd::New(funcInfo, IR::AddrOpndKindDynamicFunctionInfo, callInstr->m_func);
3970+
bailoutInstr->SetSrc1(opndFuncInfo);
3971+
bailoutInstr->SetSrc2(inlinedFuncInfo);
39723972

39733973
insertBeforeInstr->InsertBefore(bailoutInstr);
39743974
}
@@ -3987,6 +3987,10 @@ Inline::InsertFunctionObjectCheck(IR::Instr *callInstr, IR::Instr *insertBeforeI
39873987
IR::Instr *
39883988
Inline::PrepareInsertionPoint(IR::Instr *callInstr, Js::FunctionInfo *funcInfo, IR::Instr *insertBeforeInstr, IR::BailOutKind bailOutKind)
39893989
{
3990+
if (callInstr->m_func == this->topFunc && this->topFunc->GetLocalFunctionId()==160 && callInstr->GetByteCodeOffset()==0x1f)
3991+
{
3992+
*(volatile int*)this;
3993+
}
39903994
Assert(insertBeforeInstr);
39913995
Assert(insertBeforeInstr->m_func == callInstr->m_func);
39923996
Assert(bailOutKind == IR::BailOutOnInlineFunction);
@@ -4006,7 +4010,7 @@ Inline::PrepareInsertionPoint(IR::Instr *callInstr, Js::FunctionInfo *funcInfo,
40064010
InsertFunctionTypeIdCheck(callInstr, insertBeforeInstr, bailOutIfNotJsFunction);
40074011

40084012
// 3. Bailout if function body doesn't match funcInfo
4009-
InsertFunctionBodyCheck(callInstr, insertBeforeInstr, primaryBailOutInstr, funcInfo);
4013+
InsertFunctionInfoCheck(callInstr, insertBeforeInstr, primaryBailOutInstr, funcInfo);
40104014

40114015
return primaryBailOutInstr;
40124016
}
@@ -5369,4 +5373,4 @@ Inline::Simd128FixLoadStoreInstr(Js::BuiltinFunction builtInId, IR::Instr * call
53695373

53705374
}
53715375
}
5372-
#endif
5376+
#endif

lib/Backend/Inline.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ class Inline
134134
void InsertObjectCheck(IR::Instr *callInstr, IR::Instr* insertBeforeInstr, IR::Instr*bailOutInstr);
135135
void InsertFunctionTypeIdCheck(IR::Instr *callInstr, IR::Instr* insertBeforeInstr, IR::Instr*bailOutInstr);
136136
void InsertJsFunctionCheck(IR::Instr *callInstr, IR::Instr *insertBeforeInstr, IR::BailOutKind bailOutKind);
137-
void InsertFunctionBodyCheck(IR::Instr *callInstr, IR::Instr *insertBeforeInstr, IR::Instr* bailoutInstr, Js::FunctionInfo *funcInfo);
137+
void InsertFunctionInfoCheck(IR::Instr *callInstr, IR::Instr *insertBeforeInstr, IR::Instr* bailoutInstr, Js::FunctionInfo *funcInfo);
138138
void InsertFunctionObjectCheck(IR::Instr *callInstr, IR::Instr *insertBeforeInstr, IR::Instr* bailoutInstr, Js::FunctionInfo *funcInfo);
139139

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