blob: e9819fa4d826bd8ebc08bbcd0d3a4aa7838f9f3d [file]
//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------
#include "RuntimeLanguagePch.h"
#include "Language/FunctionCodeGenRuntimeData.h"
namespace Js
{
FunctionCodeGenRuntimeData::FunctionCodeGenRuntimeData(FunctionBody *const functionBody)
: functionBody(functionBody), inlinees(nullptr), next(nullptr)
{
}
FunctionBody *FunctionCodeGenRuntimeData::GetFunctionBody() const
{
return functionBody;
}
const InlineCachePointerArray<InlineCache> *FunctionCodeGenRuntimeData::ClonedInlineCaches() const
{
return &clonedInlineCaches;
}
InlineCachePointerArray<InlineCache> *FunctionCodeGenRuntimeData::ClonedInlineCaches()
{
return &clonedInlineCaches;
}
const FunctionCodeGenRuntimeData * FunctionCodeGenRuntimeData::GetForTarget(FunctionBody *targetFuncBody) const
{
const FunctionCodeGenRuntimeData * target = this;
while (target && target->GetFunctionBody() != targetFuncBody)
{
target = target->next;
}
// we should always find the info
Assert(target);
return target;
}
const FunctionCodeGenRuntimeData *FunctionCodeGenRuntimeData::GetInlinee(const ProfileId profiledCallSiteId) const
{
Assert(profiledCallSiteId < functionBody->GetProfiledCallSiteCount());
return inlinees ? inlinees[profiledCallSiteId] : nullptr;
}
const FunctionCodeGenRuntimeData *FunctionCodeGenRuntimeData::GetInlineeForTargetInlinee(const ProfileId profiledCallSiteId, FunctionBody *inlineeFuncBody) const
{
Assert(profiledCallSiteId < functionBody->GetProfiledCallSiteCount());
if (!inlinees)
{
return nullptr;
}
FunctionCodeGenRuntimeData *runtimeData = inlinees[profiledCallSiteId];
while (runtimeData && runtimeData->GetFunctionBody() != inlineeFuncBody)
{
runtimeData = runtimeData->next;
}
return runtimeData;
}
void FunctionCodeGenRuntimeData::SetupRecursiveInlineeChain(
Recycler *const recycler,
const ProfileId profiledCallSiteId,
FunctionBody *const inlinee)
{
Assert(recycler);
Assert(profiledCallSiteId < functionBody->GetProfiledCallSiteCount());
Assert(inlinee == functionBody);
if (!inlinees)
{
inlinees = RecyclerNewArrayZ(recycler, Field(FunctionCodeGenRuntimeData*), functionBody->GetProfiledCallSiteCount());
}
inlinees[profiledCallSiteId] = this;
}
FunctionCodeGenRuntimeData *FunctionCodeGenRuntimeData::EnsureInlinee(
Recycler *const recycler,
const ProfileId profiledCallSiteId,
FunctionBody *const inlinee)
{
Assert(recycler);
Assert(profiledCallSiteId < functionBody->GetProfiledCallSiteCount());
Assert(inlinee);
if (!inlinees)
{
inlinees = RecyclerNewArrayZ(recycler, Field(FunctionCodeGenRuntimeData *), functionBody->GetProfiledCallSiteCount());
}
const auto inlineeData = inlinees[profiledCallSiteId];
if (!inlineeData)
{
return inlinees[profiledCallSiteId] = RecyclerNew(recycler, FunctionCodeGenRuntimeData, inlinee);
}
// Find the right code gen runtime data
FunctionCodeGenRuntimeData *next = inlineeData;
while (next && next->functionBody != inlinee)
{
next = next->next;
}
if (next)
{
return next;
}
FunctionCodeGenRuntimeData *runtimeData = RecyclerNew(recycler, FunctionCodeGenRuntimeData, inlinee);
runtimeData->next = inlineeData;
return inlinees[profiledCallSiteId] = runtimeData;
}
const FunctionCodeGenRuntimeData *FunctionCodeGenRuntimeData::GetLdFldInlinee(const InlineCacheIndex inlineCacheIndex) const
{
Assert(inlineCacheIndex < functionBody->GetInlineCacheCount());
return ldFldInlinees ? ldFldInlinees[inlineCacheIndex] : nullptr;
}
const FunctionCodeGenRuntimeData *FunctionCodeGenRuntimeData::GetRuntimeDataFromFunctionInfo(FunctionInfo *polyFunctionInfo) const
{
const FunctionCodeGenRuntimeData *next = this;
FunctionProxy *polyFunctionProxy = polyFunctionInfo->GetFunctionProxy();
while (next && next->functionBody != polyFunctionProxy)
{
next = next->next;
}
return next;
}
FunctionCodeGenRuntimeData *FunctionCodeGenRuntimeData::EnsureLdFldInlinee(
Recycler *const recycler,
const InlineCacheIndex inlineCacheIndex,
FunctionBody *const inlinee)
{
Assert(recycler);
Assert(inlineCacheIndex < functionBody->GetInlineCacheCount());
Assert(inlinee);
if (!ldFldInlinees)
{
ldFldInlinees = RecyclerNewArrayZ(recycler, Field(FunctionCodeGenRuntimeData *), functionBody->GetInlineCacheCount());
}
const auto inlineeData = ldFldInlinees[inlineCacheIndex];
if (!inlineeData)
{
return ldFldInlinees[inlineCacheIndex] = RecyclerNew(recycler, FunctionCodeGenRuntimeData, inlinee);
}
return inlineeData;
}
}