Skip to content

Commit 3eca75e

Browse files
committed
fix bugs with inlining import thunks and saving stale profile info after reparse
1 parent ab1ab30 commit 3eca75e

File tree

7 files changed

+43
-11
lines changed

7 files changed

+43
-11
lines changed

lib/Runtime/Base/FunctionBody.cpp

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1611,8 +1611,8 @@ namespace Js
16111611
m_isAsmJsFunction(false),
16121612
m_tag21(true)
16131613
#if DBG
1614-
,m_wasEverAsmjsMode(false)
1615-
,scopeObjectSize(0)
1614+
,m_wasEverAsmjsMode(false)
1615+
,scopeObjectSize(0)
16161616
#endif
16171617
{
16181618
this->functionInfo = RecyclerNew(scriptContext->GetRecycler(), FunctionInfo, entryPoint, attributes, functionId, this);
@@ -1661,7 +1661,7 @@ namespace Js
16611661
m_reparsed(proxy->IsReparsed()),
16621662
m_tag21(true)
16631663
#if DBG
1664-
,m_wasEverAsmjsMode(proxy->m_wasEverAsmjsMode)
1664+
, m_wasEverAsmjsMode(proxy->m_wasEverAsmjsMode)
16651665
#endif
16661666
{
16671667
FunctionInfo * functionInfo = proxy->GetFunctionInfo();
@@ -4936,7 +4936,24 @@ namespace Js
49364936
this->SetByteCodeInLoopCount(0);
49374937

49384938
#if ENABLE_PROFILE_INFO
4939-
this->dynamicProfileInfo = nullptr;
4939+
if (this->dynamicProfileInfo != nullptr)
4940+
{
4941+
GetSourceContextInfo()->sourceDynamicProfileManager->RemoveDynamicProfileInfo(GetFunctionInfo()->GetLocalFunctionId());
4942+
4943+
#ifdef DYNAMIC_PROFILE_STORAGE
4944+
DynamicProfileInfoList * profileInfoList = GetScriptContext()->GetProfileInfoList();
4945+
for (auto iter = profileInfoList->GetEditingIterator(); iter.IsValid(); iter.Next())
4946+
{
4947+
DynamicProfileInfo * info = iter.Data();
4948+
if (info->HasFunctionBody() && info->GetFunctionBody() == this)
4949+
{
4950+
iter.UnlinkCurrent();
4951+
break;
4952+
}
4953+
}
4954+
#endif
4955+
this->dynamicProfileInfo = nullptr;
4956+
}
49404957
#endif
49414958
this->hasExecutionDynamicProfileInfo = false;
49424959

lib/Runtime/Base/FunctionBody.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1724,13 +1724,16 @@ namespace Js
17241724
void SetIsAsmjsMode(bool value)
17251725
{
17261726
m_isAsmjsMode = value;
1727-
#if DBG
1727+
#if DBG
17281728
if (value)
17291729
{
17301730
m_wasEverAsmjsMode = true;
17311731
}
1732-
#endif
1732+
#endif
17331733
}
1734+
#if DBG
1735+
bool WasEverAsmJsMode() const { return m_wasEverAsmjsMode; }
1736+
#endif
17341737

17351738
void SetIsWasmFunction(bool val)
17361739
{
@@ -1965,6 +1968,9 @@ namespace Js
19651968

19661969
// Indicates if the function has been reparsed for debug attach/detach scenario.
19671970
FieldWithBarrier(bool) m_reparsed : 1;
1971+
#if DBG
1972+
FieldWithBarrier(bool) m_wasEverAsmjsMode : 1; // has m_isAsmjsMode ever been true
1973+
#endif
19681974

19691975
// This field is not required for deferred parsing but because our thunks can't handle offsets > 128 bytes
19701976
// yet, leaving this here for now. We can look at optimizing the function info and function proxy structures some
@@ -1993,7 +1999,6 @@ namespace Js
19931999

19942000
public:
19952001
#if DBG
1996-
FieldWithBarrier(bool) m_wasEverAsmjsMode; // has m_isAsmjsMode ever been true
19972002
FieldWithBarrier(Js::LocalFunctionId) deferredParseNextFunctionId;
19982003
#endif
19992004
#if DBG

lib/Runtime/ByteCode/ByteCodeEmitter.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1803,7 +1803,7 @@ void ByteCodeGenerator::InitScopeSlotArray(FuncInfo * funcInfo)
18031803
{
18041804
Js::PropertyId *propertyIdsForScopeSlotArray = RecyclerNewArrayLeafZ(scriptContext->GetRecycler(), Js::PropertyId, scopeSlotCount);
18051805
byteCodeFunction->SetPropertyIdsForScopeSlotArray(propertyIdsForScopeSlotArray, scopeSlotCount, scopeSlotCountForParamScope);
1806-
AssertMsg(!byteCodeFunction->IsReparsed() || byteCodeFunction->m_wasEverAsmjsMode || byteCodeFunction->scopeSlotArraySize == scopeSlotCount,
1806+
AssertMsg(!byteCodeFunction->IsReparsed() || byteCodeFunction->WasEverAsmJsMode() || byteCodeFunction->scopeSlotArraySize == scopeSlotCount,
18071807
"The slot array size is different between debug and non-debug mode");
18081808
#if DEBUG
18091809
for (UINT i = 0; i < scopeSlotCount; i++)
@@ -1930,7 +1930,7 @@ void ByteCodeGenerator::LoadAllConstants(FuncInfo *funcInfo)
19301930
// A reparse should result in the same size of the activation object.
19311931
// Exclude functions which were created from the ByteCodeCache.
19321932
AssertMsg(!byteCodeFunction->IsReparsed() || byteCodeFunction->HasGeneratedFromByteCodeCache() ||
1933-
byteCodeFunction->scopeObjectSize == count || byteCodeFunction->m_wasEverAsmjsMode,
1933+
byteCodeFunction->scopeObjectSize == count || byteCodeFunction->WasEverAsmJsMode(),
19341934
"The activation object size is different between debug and non-debug mode");
19351935
byteCodeFunction->scopeObjectSize = count;
19361936
#endif

lib/Runtime/Language/DynamicProfileInfo.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1843,7 +1843,6 @@ namespace Js
18431843
#if DBG_DUMP
18441844
writer->Log(this);
18451845
#endif
1846-
18471846
FunctionBody * functionBody = this->GetFunctionBody();
18481847
Js::ArgSlot paramInfoCount = functionBody->GetProfiledInParamsCount();
18491848
if (!writer->Write(functionBody->GetLocalFunctionId())

lib/Runtime/Language/SourceDynamicProfileManager.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,14 @@ namespace Js
5252
dynamicProfileInfoMap.Item(functionId, dynamicProfileInfo);
5353
}
5454

55+
void SourceDynamicProfileManager::RemoveDynamicProfileInfo(LocalFunctionId functionId)
56+
{
57+
dynamicProfileInfoMap.Remove(functionId);
58+
#ifdef DYNAMIC_PROFILE_STORAGE
59+
dynamicProfileInfoMapSaving.Remove(functionId);
60+
#endif
61+
}
62+
5563
void SourceDynamicProfileManager::MarkAsExecuted(LocalFunctionId functionId)
5664
{
5765
Assert(startupFunctions != nullptr);

lib/Runtime/Language/SourceDynamicProfileManager.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ namespace Js
3333
DynamicProfileInfo * GetDynamicProfileInfo(FunctionBody * functionBody);
3434
Recycler* GetRecycler() { return recycler; }
3535
void UpdateDynamicProfileInfo(LocalFunctionId functionId, DynamicProfileInfo * dynamicProfileInfo);
36+
void RemoveDynamicProfileInfo(LocalFunctionId functionId);
3637
void MarkAsExecuted(LocalFunctionId functionId);
3738
static SourceDynamicProfileManager * LoadFromDynamicProfileStorage(SourceContextInfo* info, ScriptContext* scriptContext, IActiveScriptDataCache* profileDataCache);
3839
void EnsureStartupFunctions(uint numberOfFunctions);

lib/WasmReader/WasmByteCodeGenerator.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -963,7 +963,9 @@ EmitInfo WasmBytecodeGenerator::EmitCall()
963963
funcNum = GetReader()->m_currentNode.call.num;
964964
WasmFunctionInfo* calleeInfo = m_module->GetWasmFunctionInfo(funcNum);
965965
calleeSignature = calleeInfo->GetSignature();
966-
if (!isImportCall)
966+
// currently only handle inlining internal function calls
967+
// in future we can expand to all calls by adding checks in inliner and falling back to call in case ScriptFunction doesn't match
968+
if (GetReader()->m_currentNode.call.funcType == FunctionIndexTypes::Function)
967969
{
968970
profileId = GetNextProfileId();
969971
}

0 commit comments

Comments
 (0)