Skip to content

Commit 4706ddf

Browse files
committed
[MERGE #1760 @MikeHolman] fix issue when polymorphic inline info layouts differ in JIT and runtime data
Merge pull request #1760 from MikeHolman:polyinlining Exact order of next pointers for polymorphic CodeGen JIT and CodeGen Runtime data may differ. So, while walking CodeGen JIT data during BuildJITTimeData data we should pass along the head CodeGen Runtime pointer, otherwise inner calls will not be able to find inlinees who appear earlier in the list.
2 parents 3ac075b + 5f5853c commit 4706ddf

File tree

3 files changed

+19
-20
lines changed

3 files changed

+19
-20
lines changed

lib/Backend/FunctionJITTimeInfo.cpp

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ FunctionJITTimeInfo::BuildJITTimeData(
4040
if (codeGenData->GetFunctionInfo()->HasBody())
4141
{
4242
Assert(isInlinee == !!runtimeData);
43+
const Js::FunctionCodeGenRuntimeData * targetRuntimeData = nullptr;
44+
if (runtimeData)
45+
{
46+
// may be polymorphic, so seek the runtime data matching our JIT time data
47+
targetRuntimeData = runtimeData->GetForTarget(codeGenData->GetFunctionInfo()->GetFunctionBody());
48+
}
4349
Js::FunctionBody * functionBody = codeGenData->GetFunctionBody();
4450
if (functionBody->HasDynamicProfileInfo())
4551
{
@@ -79,25 +85,21 @@ FunctionJITTimeInfo::BuildJITTimeData(
7985
const Js::FunctionCodeGenRuntimeData * inlineeRuntimeData = nullptr;
8086
if (inlineeJITData->GetFunctionInfo()->HasBody())
8187
{
82-
Js::FunctionBody * inlinee = inlineeJITData->GetFunctionInfo()->GetFunctionBody();
83-
inlineeRuntimeData = isInlinee ? runtimeData->GetInlineeForTargetInlinee(i, inlinee) : functionBody->GetInlineeCodeGenRuntimeDataForTargetInlinee(i, inlinee);
88+
inlineeRuntimeData = isInlinee ? targetRuntimeData->GetInlinee(i) : functionBody->GetInlineeCodeGenRuntimeData(i);
8489
}
8590
jitData->inlinees[i] = AnewStructZ(alloc, FunctionJITTimeDataIDL);
8691
BuildJITTimeData(alloc, inlineeJITData, inlineeRuntimeData, jitData->inlinees[i], true, isForegroundJIT);
8792
}
8893
}
8994
}
90-
// TODO: OOP JIT, cleanup these checks
9195
jitData->profiledRuntimeData = AnewStructZ(alloc, FunctionJITRuntimeIDL);
92-
if (isInlinee && runtimeData->ClonedInlineCaches()->HasInlineCaches())
96+
if (isInlinee && targetRuntimeData->ClonedInlineCaches()->HasInlineCaches())
9397
{
94-
// REVIEW: OOP JIT is this safe to be doing in background?
9598
jitData->profiledRuntimeData->clonedCacheCount = jitData->bodyData->inlineCacheCount;
9699
jitData->profiledRuntimeData->clonedInlineCaches = AnewArray(alloc, intptr_t, jitData->profiledRuntimeData->clonedCacheCount);
97100
for (uint j = 0; j < jitData->bodyData->inlineCacheCount; ++j)
98101
{
99-
// REVIEW: OOP JIT, what to do with WriteBarrierPtr?
100-
jitData->profiledRuntimeData->clonedInlineCaches[j] = (intptr_t)runtimeData->ClonedInlineCaches()->GetInlineCache(j);
102+
jitData->profiledRuntimeData->clonedInlineCaches[j] = (intptr_t)targetRuntimeData->ClonedInlineCaches()->GetInlineCache(j);
101103
}
102104
}
103105
if (jitData->bodyData->inlineCacheCount > 0)
@@ -115,7 +117,7 @@ FunctionJITTimeInfo::BuildJITTimeData(
115117
for (Js::InlineCacheIndex i = 0; i < jitData->bodyData->inlineCacheCount; ++i)
116118
{
117119
const Js::FunctionCodeGenJitTimeData * inlineeJITData = codeGenData->GetLdFldInlinee(i);
118-
const Js::FunctionCodeGenRuntimeData * inlineeRuntimeData = isInlinee ? runtimeData->GetLdFldInlinee(i) : functionBody->GetLdFldInlineeCodeGenRuntimeData(i);
120+
const Js::FunctionCodeGenRuntimeData * inlineeRuntimeData = isInlinee ? targetRuntimeData->GetLdFldInlinee(i) : functionBody->GetLdFldInlineeCodeGenRuntimeData(i);
119121
if (inlineeJITData != nullptr)
120122
{
121123
jitData->ldFldInlinees[i] = AnewStructZ(alloc, FunctionJITTimeDataIDL);
@@ -138,12 +140,7 @@ FunctionJITTimeInfo::BuildJITTimeData(
138140
// only inlinee should be polymorphic
139141
Assert(isInlinee);
140142
jitData->next = AnewStructZ(alloc, FunctionJITTimeDataIDL);
141-
const Js::FunctionCodeGenRuntimeData * nextRuntimeData = nullptr;
142-
if (nextJITData->GetFunctionInfo()->HasBody())
143-
{
144-
nextRuntimeData = runtimeData->GetNextForTarget(nextJITData->GetFunctionInfo()->GetFunctionBody());
145-
}
146-
BuildJITTimeData(alloc, nextJITData, nextRuntimeData, jitData->next, true, isForegroundJIT);
143+
BuildJITTimeData(alloc, nextJITData, runtimeData, jitData->next, true, isForegroundJIT);
147144
}
148145
}
149146
}

lib/Runtime/Language/FunctionCodeGenRuntimeData.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,16 @@ namespace Js
2727
return &clonedInlineCaches;
2828
}
2929

30-
FunctionCodeGenRuntimeData * FunctionCodeGenRuntimeData::GetNextForTarget(FunctionBody *targetFuncBody) const
30+
const FunctionCodeGenRuntimeData * FunctionCodeGenRuntimeData::GetForTarget(FunctionBody *targetFuncBody) const
3131
{
32-
FunctionCodeGenRuntimeData * next = this->next;
33-
if (next->GetFunctionBody() != targetFuncBody)
32+
const FunctionCodeGenRuntimeData * target = this;
33+
while (target && target->GetFunctionBody() != targetFuncBody)
3434
{
35-
next = next->next;
35+
target = target->next;
3636
}
37-
return next;
37+
// we should always find the info
38+
Assert(target);
39+
return target;
3840
}
3941

4042
const FunctionCodeGenRuntimeData *FunctionCodeGenRuntimeData::GetInlinee(const ProfileId profiledCallSiteId) const

lib/Runtime/Language/FunctionCodeGenRuntimeData.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ namespace Js
3636
public:
3737
FunctionBody *GetFunctionBody() const;
3838
FunctionCodeGenRuntimeData *GetNext() const { return next; };
39-
FunctionCodeGenRuntimeData *GetNextForTarget(FunctionBody *targetFuncBody) const;
39+
const FunctionCodeGenRuntimeData *GetForTarget(FunctionBody *targetFuncBody) const;
4040
const InlineCachePointerArray<InlineCache> *ClonedInlineCaches() const;
4141
InlineCachePointerArray<InlineCache> *ClonedInlineCaches();
4242

0 commit comments

Comments
 (0)