Skip to content

Commit 2021113

Browse files
davidwrightonpull[bot]
authored andcommitted
Fix perf problems found in investigation of issue dotnet#107728 (dotnet#107806)
- `CheckRunClassInitThrowing` didn't check to see if the class had been initialized before taking a lock - `EnsureTlsIndexAllocated` didn't check if the Tls index had been allocated before setting the flag via an expensive Interlocked call to indicate that it had been allocated - And finally `JIT_GetNonGCThreadStaticBaseOptimized` and `JIT_GetGCThreadStaticBaseOptimized` were missing the fast paths which avoided even calling those apis at all. Perf with a small benchmark which does complex multithreaded work... | Runtime | Time | | ---- | ---- | | .NET 8 | 00.9414682 s | | .NET 9 before this fix | 22.8079382 | | .NET 9 with this fix | 00.2004539 | Fixes dotnet#107728
1 parent 15212ca commit 2021113

File tree

2 files changed

+19
-3
lines changed

2 files changed

+19
-3
lines changed

src/coreclr/vm/jithelpers.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -901,6 +901,12 @@ HCIMPL1(void*, JIT_GetNonGCThreadStaticBaseOptimized, UINT32 staticBlockIndex)
901901

902902
FCALL_CONTRACT;
903903

904+
staticBlock = GetThreadLocalStaticBaseIfExistsAndInitialized(staticBlockIndex);
905+
if (staticBlock != NULL)
906+
{
907+
return staticBlock;
908+
}
909+
904910
HELPER_METHOD_FRAME_BEGIN_RET_0(); // Set up a frame
905911
TLSIndex tlsIndex(staticBlockIndex);
906912
// Check if the class constructor needs to be run
@@ -975,6 +981,12 @@ HCIMPL1(void*, JIT_GetGCThreadStaticBaseOptimized, UINT32 staticBlockIndex)
975981

976982
FCALL_CONTRACT;
977983

984+
staticBlock = GetThreadLocalStaticBaseIfExistsAndInitialized(staticBlockIndex);
985+
if (staticBlock != NULL)
986+
{
987+
return staticBlock;
988+
}
989+
978990
HELPER_METHOD_FRAME_BEGIN_RET_0(); // Set up a frame
979991

980992
TLSIndex tlsIndex(staticBlockIndex);

src/coreclr/vm/methodtable.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3797,8 +3797,8 @@ void MethodTable::CheckRunClassInitThrowing()
37973797
// To find GC hole easier...
37983798
TRIGGERSGC();
37993799

3800-
// Don't initialize shared generic instantiations (e.g. MyClass<__Canon>)
3801-
if (IsSharedByGenericInstantiations())
3800+
// Don't initialize shared generic instantiations (e.g. MyClass<__Canon>), or an already initialized MethodTable
3801+
if (IsClassInited() || IsSharedByGenericInstantiations())
38023802
return;
38033803

38043804
_ASSERTE(!ContainsGenericVariables());
@@ -3903,7 +3903,11 @@ void MethodTable::EnsureTlsIndexAllocated()
39033903
CONTRACTL_END;
39043904

39053905
PTR_MethodTableAuxiliaryData pAuxiliaryData = GetAuxiliaryDataForWrite();
3906-
if (!pAuxiliaryData->IsTlsIndexAllocated() && GetNumThreadStaticFields() > 0)
3906+
3907+
if (pAuxiliaryData->IsTlsIndexAllocated())
3908+
return;
3909+
3910+
if (GetNumThreadStaticFields() > 0)
39073911
{
39083912
ThreadStaticsInfo *pThreadStaticsInfo = MethodTableAuxiliaryData::GetThreadStaticsInfo(GetAuxiliaryDataForWrite());
39093913
// Allocate space for normal statics if we might have them

0 commit comments

Comments
 (0)