Skip to content

Commit 41db1fe

Browse files
committed
[MERGE #5854 @rajatd] Inline more .call/.apply targets
Merge pull request #5854 from rajatd:callApplyTarget Gather profile data about the target of a .call or .apply at the call site instead of the load site of the target. Today, we can only inline .call/.apply targets loaded via LdFld. This PR attempts to catch many more cases by also collecting profile data at the call site.
2 parents e8019b5 + 474e417 commit 41db1fe

Some content is hidden

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

42 files changed

+10917
-10195
lines changed

lib/Backend/FunctionCodeGenJitTimeData.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ namespace Js
1616
#endif
1717
next(nullptr),
1818
ldFldInlinees(nullptr),
19+
callbackInlinees(nullptr),
20+
callApplyTargetInlinees(nullptr),
1921
globalThisObject(globalThis),
2022
profiledIterations(profiledIterations),
2123
sharedPropertyGuards(nullptr),
@@ -110,6 +112,14 @@ namespace Js
110112
return callbackInlinees ? callbackInlinees[profiledCallSiteId] : nullptr;
111113
}
112114

115+
const FunctionCodeGenJitTimeData * FunctionCodeGenJitTimeData::GetCallApplyTargetInlinee(const ProfileId callApplyCallSiteId) const
116+
{
117+
Assert(GetFunctionBody());
118+
Assert(callApplyCallSiteId < GetFunctionBody()->GetProfiledCallApplyCallSiteCount());
119+
120+
return callApplyTargetInlinees ? callApplyTargetInlinees[callApplyCallSiteId] : nullptr;
121+
}
122+
113123
FunctionCodeGenJitTimeData *FunctionCodeGenJitTimeData::AddInlinee(
114124
Recycler *const recycler,
115125
const ProfileId profiledCallSiteId,
@@ -197,6 +207,32 @@ namespace Js
197207
return inlineeData;
198208
}
199209

210+
FunctionCodeGenJitTimeData * FunctionCodeGenJitTimeData::AddCallApplyTargetInlinee(
211+
Recycler *const recycler,
212+
const ProfileId profiledCallSiteId,
213+
const ProfileId callApplyCallSiteId,
214+
FunctionInfo *const inlinee)
215+
{
216+
Assert(recycler != nullptr);
217+
FunctionBody * functionBody = GetFunctionBody();
218+
Assert(functionBody != nullptr);
219+
Assert(profiledCallSiteId < functionBody->GetProfiledCallSiteCount());
220+
Assert(callApplyCallSiteId < functionBody->GetProfiledCallApplyCallSiteCount());
221+
Assert(inlinee != nullptr);
222+
223+
if (!callApplyTargetInlinees)
224+
{
225+
callApplyTargetInlinees = RecyclerNewArrayZ(recycler, Field(FunctionCodeGenJitTimeData *), functionBody->GetProfiledCallApplyCallSiteCount());
226+
}
227+
228+
// Polymorphic call/apply targets are not inlined.
229+
Assert(callApplyTargetInlinees[callApplyCallSiteId] == nullptr);
230+
231+
FunctionCodeGenJitTimeData * inlineeData = FunctionCodeGenJitTimeData::New(recycler, inlinee, nullptr /* entryPoint */, true /*isInlined*/);
232+
callApplyTargetInlinees[callApplyCallSiteId] = inlineeData;
233+
return inlineeData;
234+
}
235+
200236
uint FunctionCodeGenJitTimeData::InlineeCount() const
201237
{
202238
return inlineeCount;

lib/Backend/FunctionCodeGenJitTimeData.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ namespace Js
3232
Field(Field(FunctionCodeGenJitTimeData*)*) inlinees;
3333
Field(Field(FunctionCodeGenJitTimeData*)*) ldFldInlinees;
3434
Field(Field(FunctionCodeGenJitTimeData*)*) callbackInlinees;
35+
Field(Field(FunctionCodeGenJitTimeData*)*) callApplyTargetInlinees;
36+
3537
Field(RecyclerWeakReference<FunctionBody>*) weakFuncRef;
3638

3739
Field(PolymorphicInlineCacheInfoIDL*) inlineeInfo;
@@ -92,6 +94,7 @@ namespace Js
9294
const FunctionCodeGenJitTimeData *GetInlinee(const ProfileId profiledCallSiteId) const;
9395
const FunctionCodeGenJitTimeData *GetLdFldInlinee(const InlineCacheIndex inlineCacheIndex) const;
9496
const FunctionCodeGenJitTimeData * GetCallbackInlinee(const ProfileId profiledCallSiteId) const;
97+
const FunctionCodeGenJitTimeData * GetCallApplyTargetInlinee(const ProfileId callApplyCallSiteId) const;
9598
FunctionCodeGenJitTimeData *AddInlinee(
9699
Recycler *const recycler,
97100
const ProfileId profiledCallSiteId,
@@ -125,6 +128,12 @@ namespace Js
125128
const ProfileId profiledCallSiteId,
126129
FunctionInfo *const inlinee);
127130

131+
FunctionCodeGenJitTimeData * AddCallApplyTargetInlinee(
132+
Recycler *const recycler,
133+
const ProfileId profiledCallSiteId,
134+
const ProfileId callApplyCallSiteId,
135+
FunctionInfo *const inlinee);
136+
128137
bool IsPolymorphicCallSite(const ProfileId profiledCallSiteId) const;
129138
// This function walks all the chained jittimedata and returns the one which match the functionInfo.
130139
// This can return null, if the functionInfo doesn't match.

lib/Backend/FunctionJITTimeInfo.cpp

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@ FunctionJITTimeInfo::BuildJITTimeData(
9494
}
9595
}
9696

97-
jitData->callbackInlineeCount = jitData->bodyData->profiledCallSiteCount;
9897
jitData->callbackInlinees = AnewArrayZ(alloc, FunctionJITTimeDataIDL*, jitData->bodyData->profiledCallSiteCount);
9998

10099
for (Js::ProfileId i = 0; i < jitData->bodyData->profiledCallSiteCount; ++i)
@@ -111,6 +110,26 @@ FunctionJITTimeInfo::BuildJITTimeData(
111110
BuildJITTimeData(alloc, inlineeJITData, inlineeRuntimeData, jitData->callbackInlinees[i], true, isForegroundJIT);
112111
}
113112
}
113+
114+
jitData->callApplyTargetInlineeCount = jitData->bodyData->profiledCallApplyCallSiteCount;
115+
if (jitData->bodyData->profiledCallApplyCallSiteCount > 0)
116+
{
117+
jitData->callApplyTargetInlinees = AnewArrayZ(alloc, FunctionJITTimeDataIDL*, jitData->bodyData->profiledCallApplyCallSiteCount);
118+
}
119+
for (Js::ProfileId i = 0; i < jitData->bodyData->profiledCallApplyCallSiteCount; ++i)
120+
{
121+
const Js::FunctionCodeGenJitTimeData * inlineeJITData = codeGenData->GetCallApplyTargetInlinee(i);
122+
if (inlineeJITData != nullptr)
123+
{
124+
const Js::FunctionCodeGenRuntimeData * inlineeRuntimeData = nullptr;
125+
if (inlineeJITData->GetFunctionInfo()->HasBody())
126+
{
127+
inlineeRuntimeData = isInlinee ? targetRuntimeData->GetCallApplyTargetInlinee(i) : functionBody->GetCallApplyTargetInlineeCodeGenRuntimeData(i);
128+
}
129+
jitData->callApplyTargetInlinees[i] = AnewStructZ(alloc, FunctionJITTimeDataIDL);
130+
BuildJITTimeData(alloc, inlineeJITData, inlineeRuntimeData, jitData->callApplyTargetInlinees[i], true, isForegroundJIT);
131+
}
132+
}
114133
}
115134
jitData->profiledRuntimeData = AnewStructZ(alloc, FunctionJITRuntimeIDL);
116135
if (isInlinee && targetRuntimeData->ClonedInlineCaches()->HasInlineCaches())
@@ -293,6 +312,12 @@ FunctionJITTimeInfo::GetInlineeForCallbackInlineeRuntimeData(const Js::ProfileId
293312
return inlineeData->GetRuntimeInfo();
294313
}
295314

315+
const FunctionJITRuntimeInfo *
316+
FunctionJITTimeInfo::GetCallApplyTargetInlineeRuntimeData(const Js::ProfileId callApplyCallSiteId) const
317+
{
318+
return GetCallApplyTargetInlinee(callApplyCallSiteId) ? GetCallApplyTargetInlinee(callApplyCallSiteId)->GetRuntimeInfo() : nullptr;
319+
}
320+
296321
const FunctionJITRuntimeInfo *
297322
FunctionJITTimeInfo::GetRuntimeInfo() const
298323
{
@@ -341,11 +366,23 @@ FunctionJITTimeInfo::GetCallbackInlinee(Js::ProfileId profileId) const
341366
{
342367
return nullptr;
343368
}
344-
AssertOrFailFast(profileId < m_data.callbackInlineeCount);
369+
AssertOrFailFast(profileId < m_data.inlineeCount);
345370

346371
return reinterpret_cast<const FunctionJITTimeInfo *>(m_data.callbackInlinees[profileId]);
347372
}
348373

374+
const FunctionJITTimeInfo *
375+
FunctionJITTimeInfo::GetCallApplyTargetInlinee(Js::ProfileId callApplyCallSiteId) const
376+
{
377+
if (!m_data.callApplyTargetInlinees)
378+
{
379+
return nullptr;
380+
}
381+
AssertOrFailFast(callApplyCallSiteId < m_data.bodyData->profiledCallApplyCallSiteCount);
382+
383+
return reinterpret_cast<const FunctionJITTimeInfo *>(m_data.callApplyTargetInlinees[callApplyCallSiteId]);
384+
}
385+
349386
const FunctionJITTimeInfo *
350387
FunctionJITTimeInfo::GetLdFldInlinee(Js::InlineCacheIndex inlineCacheIndex) const
351388
{

lib/Backend/FunctionJITTimeInfo.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ class FunctionJITTimeInfo
2121
bool IsLdFldInlineePresent() const;
2222

2323
const FunctionJITTimeInfo * GetCallbackInlinee(Js::ProfileId profileId) const;
24+
const FunctionJITTimeInfo * GetCallApplyTargetInlinee(Js::ProfileId profileId) const;
25+
const Js::ProfileId GetCallApplyCallSiteIdForCallSiteId(Js::ProfileId profiledCallSiteId) const;
2426
const FunctionJITTimeInfo * GetLdFldInlinee(Js::InlineCacheIndex inlineCacheIndex) const;
2527
const FunctionJITTimeInfo * GetInlinee(Js::ProfileId profileId) const;
2628
const FunctionJITTimeInfo * GetNext() const;
@@ -45,6 +47,7 @@ class FunctionJITTimeInfo
4547
const FunctionJITRuntimeInfo *GetLdFldInlineeRuntimeData(const Js::InlineCacheIndex inlineCacheIndex) const;
4648
const FunctionJITRuntimeInfo * GetCallbackInlineeRuntimeData(const Js::ProfileId profiledCallSiteId) const;
4749
const FunctionJITRuntimeInfo * GetInlineeForCallbackInlineeRuntimeData(const Js::ProfileId profiledCallSiteId, intptr_t inlineeFuncBodyAddr) const;
50+
const FunctionJITRuntimeInfo * GetCallApplyTargetInlineeRuntimeData(const Js::ProfileId callApplyCallSiteId) const;
4851
bool ForceJITLoopBody() const;
4952
bool HasSharedPropertyGuards() const;
5053
bool HasSharedPropertyGuard(Js::PropertyId id) const;

lib/Backend/IR.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2017,6 +2017,22 @@ Instr::New(Js::OpCode opcode, Func *func)
20172017
return instr;
20182018
}
20192019

2020+
///----------------------------------------------------------------------------
2021+
///
2022+
/// Instr::New
2023+
///
2024+
/// Create an Instr with a byte code offset.
2025+
///
2026+
///----------------------------------------------------------------------------
2027+
2028+
Instr *
2029+
Instr::New(Js::OpCode opcode, Func *func, IR::Instr * bytecodeOffsetInstr)
2030+
{
2031+
Instr * instr = Instr::New(opcode, func);
2032+
instr->SetByteCodeOffset(bytecodeOffsetInstr);
2033+
return instr;
2034+
}
2035+
20202036
///----------------------------------------------------------------------------
20212037
///
20222038
/// Instr::New

lib/Backend/IR.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ class Instr
177177
}
178178
public:
179179
static Instr * New(Js::OpCode opcode, Func *func);
180+
static Instr * New(Js::OpCode opcode, Func *func, IR::Instr * bytecodeOffsetInstr);
180181
static Instr * New(Js::OpCode opcode, Opnd *dstOpnd, Func *func);
181182
static Instr * New(Js::OpCode opcode, Opnd *dstOpnd, Opnd *src1Opnd, Func *func);
182183
static Instr * New(Js::OpCode opcode, Opnd *dstOpnd, Opnd *src1Opnd, Opnd *src2Opnd, Func *func);

0 commit comments

Comments
 (0)