From 5f5853c8a94787f6770a727fc7ca6de905065091 Mon Sep 17 00:00:00 2001 From: Michael Holman Date: Mon, 17 Oct 2016 18:40:34 -0700 Subject: [PATCH] fix issue when polymorphic inline info layouts differ in JIT and runtime data --- lib/Backend/FunctionJITTimeInfo.cpp | 25 ++++++++----------- .../Language/FunctionCodeGenRuntimeData.cpp | 12 +++++---- .../Language/FunctionCodeGenRuntimeData.h | 2 +- 3 files changed, 19 insertions(+), 20 deletions(-) diff --git a/lib/Backend/FunctionJITTimeInfo.cpp b/lib/Backend/FunctionJITTimeInfo.cpp index 27cab528d72..2e8795af584 100644 --- a/lib/Backend/FunctionJITTimeInfo.cpp +++ b/lib/Backend/FunctionJITTimeInfo.cpp @@ -40,6 +40,12 @@ FunctionJITTimeInfo::BuildJITTimeData( if (codeGenData->GetFunctionInfo()->HasBody()) { Assert(isInlinee == !!runtimeData); + const Js::FunctionCodeGenRuntimeData * targetRuntimeData = nullptr; + if (runtimeData) + { + // may be polymorphic, so seek the runtime data matching our JIT time data + targetRuntimeData = runtimeData->GetForTarget(codeGenData->GetFunctionInfo()->GetFunctionBody()); + } Js::FunctionBody * functionBody = codeGenData->GetFunctionBody(); if (functionBody->HasDynamicProfileInfo()) { @@ -79,25 +85,21 @@ FunctionJITTimeInfo::BuildJITTimeData( const Js::FunctionCodeGenRuntimeData * inlineeRuntimeData = nullptr; if (inlineeJITData->GetFunctionInfo()->HasBody()) { - Js::FunctionBody * inlinee = inlineeJITData->GetFunctionInfo()->GetFunctionBody(); - inlineeRuntimeData = isInlinee ? runtimeData->GetInlineeForTargetInlinee(i, inlinee) : functionBody->GetInlineeCodeGenRuntimeDataForTargetInlinee(i, inlinee); + inlineeRuntimeData = isInlinee ? targetRuntimeData->GetInlinee(i) : functionBody->GetInlineeCodeGenRuntimeData(i); } jitData->inlinees[i] = AnewStructZ(alloc, FunctionJITTimeDataIDL); BuildJITTimeData(alloc, inlineeJITData, inlineeRuntimeData, jitData->inlinees[i], true, isForegroundJIT); } } } - // TODO: OOP JIT, cleanup these checks jitData->profiledRuntimeData = AnewStructZ(alloc, FunctionJITRuntimeIDL); - if (isInlinee && runtimeData->ClonedInlineCaches()->HasInlineCaches()) + if (isInlinee && targetRuntimeData->ClonedInlineCaches()->HasInlineCaches()) { - // REVIEW: OOP JIT is this safe to be doing in background? jitData->profiledRuntimeData->clonedCacheCount = jitData->bodyData->inlineCacheCount; jitData->profiledRuntimeData->clonedInlineCaches = AnewArray(alloc, intptr_t, jitData->profiledRuntimeData->clonedCacheCount); for (uint j = 0; j < jitData->bodyData->inlineCacheCount; ++j) { - // REVIEW: OOP JIT, what to do with WriteBarrierPtr? - jitData->profiledRuntimeData->clonedInlineCaches[j] = (intptr_t)runtimeData->ClonedInlineCaches()->GetInlineCache(j); + jitData->profiledRuntimeData->clonedInlineCaches[j] = (intptr_t)targetRuntimeData->ClonedInlineCaches()->GetInlineCache(j); } } if (jitData->bodyData->inlineCacheCount > 0) @@ -115,7 +117,7 @@ FunctionJITTimeInfo::BuildJITTimeData( for (Js::InlineCacheIndex i = 0; i < jitData->bodyData->inlineCacheCount; ++i) { const Js::FunctionCodeGenJitTimeData * inlineeJITData = codeGenData->GetLdFldInlinee(i); - const Js::FunctionCodeGenRuntimeData * inlineeRuntimeData = isInlinee ? runtimeData->GetLdFldInlinee(i) : functionBody->GetLdFldInlineeCodeGenRuntimeData(i); + const Js::FunctionCodeGenRuntimeData * inlineeRuntimeData = isInlinee ? targetRuntimeData->GetLdFldInlinee(i) : functionBody->GetLdFldInlineeCodeGenRuntimeData(i); if (inlineeJITData != nullptr) { jitData->ldFldInlinees[i] = AnewStructZ(alloc, FunctionJITTimeDataIDL); @@ -138,12 +140,7 @@ FunctionJITTimeInfo::BuildJITTimeData( // only inlinee should be polymorphic Assert(isInlinee); jitData->next = AnewStructZ(alloc, FunctionJITTimeDataIDL); - const Js::FunctionCodeGenRuntimeData * nextRuntimeData = nullptr; - if (nextJITData->GetFunctionInfo()->HasBody()) - { - nextRuntimeData = runtimeData->GetNextForTarget(nextJITData->GetFunctionInfo()->GetFunctionBody()); - } - BuildJITTimeData(alloc, nextJITData, nextRuntimeData, jitData->next, true, isForegroundJIT); + BuildJITTimeData(alloc, nextJITData, runtimeData, jitData->next, true, isForegroundJIT); } } } diff --git a/lib/Runtime/Language/FunctionCodeGenRuntimeData.cpp b/lib/Runtime/Language/FunctionCodeGenRuntimeData.cpp index 5c5c64efaf9..fe4a2770365 100644 --- a/lib/Runtime/Language/FunctionCodeGenRuntimeData.cpp +++ b/lib/Runtime/Language/FunctionCodeGenRuntimeData.cpp @@ -27,14 +27,16 @@ namespace Js return &clonedInlineCaches; } - FunctionCodeGenRuntimeData * FunctionCodeGenRuntimeData::GetNextForTarget(FunctionBody *targetFuncBody) const + const FunctionCodeGenRuntimeData * FunctionCodeGenRuntimeData::GetForTarget(FunctionBody *targetFuncBody) const { - FunctionCodeGenRuntimeData * next = this->next; - if (next->GetFunctionBody() != targetFuncBody) + const FunctionCodeGenRuntimeData * target = this; + while (target && target->GetFunctionBody() != targetFuncBody) { - next = next->next; + target = target->next; } - return next; + // we should always find the info + Assert(target); + return target; } const FunctionCodeGenRuntimeData *FunctionCodeGenRuntimeData::GetInlinee(const ProfileId profiledCallSiteId) const diff --git a/lib/Runtime/Language/FunctionCodeGenRuntimeData.h b/lib/Runtime/Language/FunctionCodeGenRuntimeData.h index 694b030a023..149c21aecb3 100644 --- a/lib/Runtime/Language/FunctionCodeGenRuntimeData.h +++ b/lib/Runtime/Language/FunctionCodeGenRuntimeData.h @@ -36,7 +36,7 @@ namespace Js public: FunctionBody *GetFunctionBody() const; FunctionCodeGenRuntimeData *GetNext() const { return next; }; - FunctionCodeGenRuntimeData *GetNextForTarget(FunctionBody *targetFuncBody) const; + const FunctionCodeGenRuntimeData *GetForTarget(FunctionBody *targetFuncBody) const; const InlineCachePointerArray *ClonedInlineCaches() const; InlineCachePointerArray *ClonedInlineCaches();