Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[JIT]: Inline TLS field access for GC type #85619

Merged
merged 26 commits into from
May 13, 2023
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
01af65b
Add CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE_NOCTOR_OPTIMIZED
kunalspathak Apr 20, 2023
9142bcf
Merge remote-tracking branch 'kp/tls_gc'
kunalspathak May 1, 2023
abbfe77
Working prototype
kunalspathak May 1, 2023
743420e
Rename ThreadStaticBlock to NonGCThreadStaticBlock
kunalspathak May 1, 2023
be1914e
Add GCThreadStaticBlock
kunalspathak May 1, 2023
966e7a0
fix linux build
kunalspathak May 2, 2023
26626ad
Restrict the optimization to non-generics
kunalspathak May 3, 2023
772d9e7
Update the guid
kunalspathak May 3, 2023
4378b96
Add canOptimizeHelper check
kunalspathak May 3, 2023
5907d0c
Merge remote-tracking branch 'origin/main' into tls_gc
kunalspathak May 3, 2023
269719f
Rename and related methods from typeIDMap to NonGCTypeID
kunalspathak May 5, 2023
a9073ab
Introduce GCTypeIDMap and getGCThreadLocalFieldInfo()
kunalspathak May 9, 2023
cea1888
Use GCThreadLocalFieldInfo()
kunalspathak May 9, 2023
7ba1bda
fix the bug about gc tracking
kunalspathak May 10, 2023
1290ac6
Merge remote-tracking branch 'origin/main' into tls_gc
kunalspathak May 10, 2023
bdf0aa9
resolve merge conflicts
kunalspathak May 10, 2023
ba49c20
remove the commented code
kunalspathak May 10, 2023
ce6cbcd
add comment
kunalspathak May 11, 2023
c14f5a2
Merge branch 'main' into tls_gc
kunalspathak May 11, 2023
bb43e00
Unify some of the non-gc/gc methods
kunalspathak May 12, 2023
5b8a022
fix missing methods
kunalspathak May 12, 2023
5e81673
update the comments
kunalspathak May 12, 2023
8383cf6
Track gc for derefernce of object handle
kunalspathak May 12, 2023
1f4c8ef
fix the superpmi methods
kunalspathak May 12, 2023
ef9532e
review feedback
kunalspathak May 12, 2023
69766df
Merge remote-tracking branch 'origin/main' into tls_gc
kunalspathak May 12, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 10 additions & 3 deletions src/coreclr/inc/corinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,7 @@ enum CorInfoHelpFunc
CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_NOCTOR,
CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE_DYNAMICCLASS,
CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_DYNAMICCLASS,
CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE_NOCTOR_OPTIMIZED,
CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_NOCTOR_OPTIMIZED,

/* Debugger */
Expand Down Expand Up @@ -1729,8 +1730,11 @@ struct CORINFO_THREAD_STATIC_BLOCKS_INFO
{
CORINFO_CONST_LOOKUP tlsIndex;
uint32_t offsetOfThreadLocalStoragePointer;
uint32_t offsetOfMaxThreadStaticBlocks;
uint32_t offsetOfThreadStaticBlocks;
uint32_t offsetOfNonGCMaxThreadStaticBlocks;
kunalspathak marked this conversation as resolved.
Show resolved Hide resolved
uint32_t offsetOfGCMaxThreadStaticBlocks;
uint32_t offsetOfNonGCThreadStaticBlocks;
uint32_t offsetOfGCThreadStaticBlocks;
uint32_t offsetOfGCDataPointer;
};

//----------------------------------------------------------------------------
Expand Down Expand Up @@ -2733,7 +2737,10 @@ class ICorStaticInfo
CORINFO_FIELD_INFO *pResult
) = 0;

virtual uint32_t getThreadLocalFieldInfo (
virtual uint32_t getNonGCThreadLocalFieldInfo (
kunalspathak marked this conversation as resolved.
Show resolved Hide resolved
CORINFO_FIELD_HANDLE field) = 0;

virtual uint32_t getGCThreadLocalFieldInfo (
CORINFO_FIELD_HANDLE field) = 0;

virtual void getThreadLocalStaticBlocksInfo (
Expand Down
5 changes: 4 additions & 1 deletion src/coreclr/inc/icorjitinfoimpl_generated.h
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,10 @@ void getFieldInfo(
CORINFO_ACCESS_FLAGS flags,
CORINFO_FIELD_INFO* pResult) override;

uint32_t getThreadLocalFieldInfo(
uint32_t getNonGCThreadLocalFieldInfo(
CORINFO_FIELD_HANDLE field) override;

uint32_t getGCThreadLocalFieldInfo(
CORINFO_FIELD_HANDLE field) override;

void getThreadLocalStaticBlocksInfo(
Expand Down
10 changes: 5 additions & 5 deletions src/coreclr/inc/jiteeversionguid.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ typedef const GUID *LPCGUID;
#define GUID_DEFINED
#endif // !GUID_DEFINED

constexpr GUID JITEEVersionIdentifier = { /* 50246073-be42-4227-b9e1-edc585672820 */
0x50246073,
0xbe42,
0x4227,
{0xb9, 0xe1, 0xed, 0xc5, 0x85, 0x67, 0x28, 0x20}
constexpr GUID JITEEVersionIdentifier = { /* f63c2964-bae9-448f-baaf-9c9f2d4292f2 */
0xf63c2964,
0xbae9,
0x448f,
{0xba, 0xaf, 0x9c, 0x9f, 0x2d, 0x42, 0x92, 0xf2}
};

//////////////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down
3 changes: 2 additions & 1 deletion src/coreclr/inc/jithelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,9 @@
JITHELPER(CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE, JIT_GetSharedNonGCThreadStaticBase, CORINFO_HELP_SIG_REG_ONLY)
JITHELPER(CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE_NOCTOR, JIT_GetSharedGCThreadStaticBase, CORINFO_HELP_SIG_REG_ONLY)
JITHELPER(CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_NOCTOR, JIT_GetSharedNonGCThreadStaticBase, CORINFO_HELP_SIG_REG_ONLY)
JITHELPER(CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE_DYNAMICCLASS, JIT_GetSharedGCThreadStaticBaseDynamicClass, CORINFO_HELP_SIG_REG_ONLY)
JITHELPER(CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE_DYNAMICCLASS, JIT_GetSharedGCThreadStaticBaseDynamicClass, CORINFO_HELP_SIG_REG_ONLY)
JITHELPER(CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_DYNAMICCLASS, JIT_GetSharedNonGCThreadStaticBaseDynamicClass, CORINFO_HELP_SIG_REG_ONLY)
JITHELPER(CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE_NOCTOR_OPTIMIZED, JIT_GetSharedGCThreadStaticBaseOptimized, CORINFO_HELP_SIG_REG_ONLY)
JITHELPER(CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_NOCTOR_OPTIMIZED, JIT_GetSharedNonGCThreadStaticBaseOptimized, CORINFO_HELP_SIG_REG_ONLY)

// Debugger
Expand Down
3 changes: 2 additions & 1 deletion src/coreclr/jit/ICorJitInfo_names_generated.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ DEF_CLR_API(getFieldClass)
DEF_CLR_API(getFieldType)
DEF_CLR_API(getFieldOffset)
DEF_CLR_API(getFieldInfo)
DEF_CLR_API(getThreadLocalFieldInfo)
DEF_CLR_API(getNonGCThreadLocalFieldInfo)
DEF_CLR_API(getGCThreadLocalFieldInfo)
DEF_CLR_API(getThreadLocalStaticBlocksInfo)
DEF_CLR_API(isFieldStatic)
DEF_CLR_API(getArrayOrStringLength)
Expand Down
17 changes: 13 additions & 4 deletions src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -971,12 +971,21 @@ void WrapICorJitInfo::getFieldInfo(
API_LEAVE(getFieldInfo);
}

uint32_t WrapICorJitInfo::getThreadLocalFieldInfo(
uint32_t WrapICorJitInfo::getNonGCThreadLocalFieldInfo(
CORINFO_FIELD_HANDLE field)
{
API_ENTER(getThreadLocalFieldInfo);
uint32_t temp = wrapHnd->getThreadLocalFieldInfo(field);
API_LEAVE(getThreadLocalFieldInfo);
API_ENTER(getNonGCThreadLocalFieldInfo);
uint32_t temp = wrapHnd->getNonGCThreadLocalFieldInfo(field);
API_LEAVE(getNonGCThreadLocalFieldInfo);
return temp;
}

uint32_t WrapICorJitInfo::getGCThreadLocalFieldInfo(
CORINFO_FIELD_HANDLE field)
{
API_ENTER(getGCThreadLocalFieldInfo);
uint32_t temp = wrapHnd->getGCThreadLocalFieldInfo(field);
API_LEAVE(getGCThreadLocalFieldInfo);
return temp;
}

Expand Down
3 changes: 2 additions & 1 deletion src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -7816,7 +7816,8 @@ class Compiler
void eeGetFieldInfo(CORINFO_RESOLVED_TOKEN* pResolvedToken,
CORINFO_ACCESS_FLAGS flags,
CORINFO_FIELD_INFO* pResult);
uint32_t eeGetThreadLocalFieldInfo(CORINFO_FIELD_HANDLE field);
uint32_t eeGetNonGCThreadLocalFieldInfo(CORINFO_FIELD_HANDLE field);
uint32_t eeGetGCThreadLocalFieldInfo(CORINFO_FIELD_HANDLE field);

// Get the flags

Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/compiler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3518,6 +3518,7 @@ inline bool Compiler::IsSharedStaticHelper(GenTree* tree)
helper == CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE ||
helper == CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE ||
helper == CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE_NOCTOR ||
helper == CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE_NOCTOR_OPTIMIZED ||
helper == CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_NOCTOR ||
helper == CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_NOCTOR_OPTIMIZED ||
helper == CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE_DYNAMICCLASS ||
Expand Down
10 changes: 8 additions & 2 deletions src/coreclr/jit/ee_il_dll.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,15 @@ void Compiler::eeGetFieldInfo(CORINFO_RESOLVED_TOKEN* pResolvedToken,
}

FORCEINLINE
uint32_t Compiler::eeGetThreadLocalFieldInfo(CORINFO_FIELD_HANDLE field)
uint32_t Compiler::eeGetNonGCThreadLocalFieldInfo(CORINFO_FIELD_HANDLE field)
{
return info.compCompHnd->getThreadLocalFieldInfo(field);
return info.compCompHnd->getNonGCThreadLocalFieldInfo(field);
}

FORCEINLINE
uint32_t Compiler::eeGetGCThreadLocalFieldInfo(CORINFO_FIELD_HANDLE field)
{
return info.compCompHnd->getGCThreadLocalFieldInfo(field);
}

/*****************************************************************************
Expand Down
7 changes: 5 additions & 2 deletions src/coreclr/jit/flowgraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -698,7 +698,8 @@ bool Compiler::fgIsCommaThrow(GenTree* tree, bool forFolding /* = false */)
// cls - The class handle
// helper - The helper function
// typeIndex - The static block type index. Used only for
// CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_NOCTOR_OPTIMIZED to cache
// CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_NOCTOR_OPTIMIZED or
// CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE_NOCTOR_OPTIMIZED to cache
// the static block in an array at index typeIndex.
//
// Return Value:
Expand All @@ -715,6 +716,7 @@ GenTreeCall* Compiler::fgGetStaticsCCtorHelper(CORINFO_CLASS_HANDLE cls, CorInfo
switch (helper)
{
case CORINFO_HELP_GETSHARED_GCSTATIC_BASE_NOCTOR:
case CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE_NOCTOR_OPTIMIZED:
bNeedClassID = false;
FALLTHROUGH;

Expand Down Expand Up @@ -795,7 +797,8 @@ GenTreeCall* Compiler::fgGetStaticsCCtorHelper(CORINFO_CLASS_HANDLE cls, CorInfo

result = gtNewHelperCallNode(helper, type, opModuleIDArg, opClassIDArg);
}
else if (helper == CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_NOCTOR_OPTIMIZED)
else if ((helper == CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_NOCTOR_OPTIMIZED) ||
(helper == CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE_NOCTOR_OPTIMIZED))
{
result = gtNewHelperCallNode(helper, type, gtNewIconNode(typeIndex));
result->SetExpTLSFieldAccess();
Expand Down
61 changes: 46 additions & 15 deletions src/coreclr/jit/helperexpansion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,8 @@ bool Compiler::fgExpandRuntimeLookupsForCall(BasicBlock** pBlock, Statement* stm

//------------------------------------------------------------------------------
// fgExpandThreadLocalAccess: Inline the CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_NOCTOR_OPTIMIZED
// helper. See fgExpandThreadLocalAccessForCall for details.
// or CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE_NOCTOR_OPTIMIZED helper. See
// fgExpandThreadLocalAccessForCall for details.
//
// Returns:
// PhaseStatus indicating what, if anything, was changed.
Expand Down Expand Up @@ -446,7 +447,7 @@ PhaseStatus Compiler::fgExpandThreadLocalAccess()

//------------------------------------------------------------------------------
// fgExpandThreadLocalAccessForCall : Expand the CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_NOCTOR_OPTIMIZED
// that access fields marked with [ThreadLocal].
// or CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE_NOCTOR_OPTIMIZED, that access fields marked with [ThreadLocal].
//
// Arguments:
// pBlock - Block containing the helper call to expand. If expansion is performed,
Expand Down Expand Up @@ -483,20 +484,39 @@ bool Compiler::fgExpandThreadLocalAccessForCall(BasicBlock** pBlock, Statement*
assert(!"Unsupported scenario of optimizing TLS access on Arm32");
#endif

JITDUMP("Expanding thread static local access for [%06d] in " FMT_BB ":\n", dspTreeID(call), block->bbNum);
DISPTREE(call);
JITDUMP("\n");
bool isGCThreadStatic =
eeGetHelperNum(call->gtCallMethHnd) == CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE_NOCTOR_OPTIMIZED;

CORINFO_THREAD_STATIC_BLOCKS_INFO threadStaticBlocksInfo;
info.compCompHnd->getThreadLocalStaticBlocksInfo(&threadStaticBlocksInfo);
JITDUMP("getThreadLocalStaticBlocksInfo\n:");

uint32_t offsetOfMaxThreadStaticBlocksVal = 0;
uint32_t offsetOfThreadStaticBlocksVal = 0;
if (isGCThreadStatic)
{
JITDUMP("getThreadLocalStaticBlocksInfo (GC)\n:");
offsetOfMaxThreadStaticBlocksVal = threadStaticBlocksInfo.offsetOfGCMaxThreadStaticBlocks;
offsetOfThreadStaticBlocksVal = threadStaticBlocksInfo.offsetOfGCThreadStaticBlocks;
}
else
{
JITDUMP("getThreadLocalStaticBlocksInfo (NonGC)\n:");
offsetOfMaxThreadStaticBlocksVal = threadStaticBlocksInfo.offsetOfNonGCMaxThreadStaticBlocks;
offsetOfThreadStaticBlocksVal = threadStaticBlocksInfo.offsetOfNonGCThreadStaticBlocks;
}

JITDUMP("tlsIndex= %u\n", (ssize_t)threadStaticBlocksInfo.tlsIndex.addr);
JITDUMP("offsetOfMaxThreadStaticBlocks= %u\n", threadStaticBlocksInfo.offsetOfMaxThreadStaticBlocks);
JITDUMP("offsetOfThreadLocalStoragePointer= %u\n", threadStaticBlocksInfo.offsetOfThreadLocalStoragePointer);
JITDUMP("offsetOfThreadStaticBlocks= %u\n", threadStaticBlocksInfo.offsetOfThreadStaticBlocks);
JITDUMP("offsetOfMaxThreadStaticBlocks= %u\n", offsetOfMaxThreadStaticBlocksVal);
JITDUMP("offsetOfThreadStaticBlocks= %u\n", offsetOfThreadStaticBlocksVal);
JITDUMP("offsetOfGCDataPointer= %u\n", threadStaticBlocksInfo.offsetOfGCDataPointer);

assert(threadStaticBlocksInfo.tlsIndex.accessType == IAT_VALUE);
assert(eeGetHelperNum(call->gtCallMethHnd) == CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_NOCTOR_OPTIMIZED);

JITDUMP("Expanding thread static local access for [%06d] in " FMT_BB ":\n", dspTreeID(call), block->bbNum);
DISPTREE(call);
JITDUMP("\n");
assert((eeGetHelperNum(call->gtCallMethHnd) == CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_NOCTOR_OPTIMIZED) ||
(eeGetHelperNum(call->gtCallMethHnd) == CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE_NOCTOR_OPTIMIZED));

call->ClearExpTLSFieldAccess();
assert(call->gtArgs.CountArgs() == 1);
Expand All @@ -508,6 +528,7 @@ bool Compiler::fgExpandThreadLocalAccessForCall(BasicBlock** pBlock, Statement*
DebugInfo debugInfo = stmt->GetDebugInfo();
block = fgSplitBlockBeforeTree(block, stmt, call, &newFirstStmt, &callUse);
*pBlock = block;
var_types callType = call->TypeGet();
assert(prevBb != nullptr && block != nullptr);

// Block ops inserted by the split need to be morphed here since we are after morph.
Expand All @@ -523,8 +544,8 @@ bool Compiler::fgExpandThreadLocalAccessForCall(BasicBlock** pBlock, Statement*

// Grab a temp to store result (it's assigned from either fastPathBb or fallbackBb)
unsigned threadStaticBlockLclNum = lvaGrabTemp(true DEBUGARG("TLS field access"));
lvaTable[threadStaticBlockLclNum].lvType = TYP_I_IMPL;
threadStaticBlockLcl = gtNewLclvNode(threadStaticBlockLclNum, call->TypeGet());
lvaTable[threadStaticBlockLclNum].lvType = callType;
threadStaticBlockLcl = gtNewLclvNode(threadStaticBlockLclNum, callType);

*callUse = gtClone(threadStaticBlockLcl);

Expand Down Expand Up @@ -564,8 +585,7 @@ bool Compiler::fgExpandThreadLocalAccessForCall(BasicBlock** pBlock, Statement*
GenTree* tlsLclValueUse = gtNewLclVarNode(tlsLclNum);

// Create tree for "maxThreadStaticBlocks = tls[offsetOfMaxThreadStaticBlocks]"
GenTree* offsetOfMaxThreadStaticBlocks =
gtNewIconNode(threadStaticBlocksInfo.offsetOfMaxThreadStaticBlocks, TYP_I_IMPL);
GenTree* offsetOfMaxThreadStaticBlocks = gtNewIconNode(offsetOfMaxThreadStaticBlocksVal, TYP_I_IMPL);
GenTree* maxThreadStaticBlocksRef =
gtNewOperNode(GT_ADD, TYP_I_IMPL, gtCloneExpr(tlsLclValueUse), offsetOfMaxThreadStaticBlocks);
GenTree* maxThreadStaticBlocksValue =
Expand All @@ -577,7 +597,7 @@ bool Compiler::fgExpandThreadLocalAccessForCall(BasicBlock** pBlock, Statement*
maxThreadStaticBlocksCond = gtNewOperNode(GT_JTRUE, TYP_VOID, maxThreadStaticBlocksCond);

// Create tree for "threadStaticBlockBase = tls[offsetOfThreadStaticBlocks]"
GenTree* offsetOfThreadStaticBlocks = gtNewIconNode(threadStaticBlocksInfo.offsetOfThreadStaticBlocks, TYP_I_IMPL);
GenTree* offsetOfThreadStaticBlocks = gtNewIconNode(offsetOfThreadStaticBlocksVal, TYP_I_IMPL);
GenTree* threadStaticBlocksRef =
gtNewOperNode(GT_ADD, TYP_I_IMPL, gtCloneExpr(tlsLclValueUse), offsetOfThreadStaticBlocks);
GenTree* threadStaticBlocksValue =
Expand Down Expand Up @@ -642,6 +662,17 @@ bool Compiler::fgExpandThreadLocalAccessForCall(BasicBlock** pBlock, Statement*
fgNewBBFromTreeAfter(BBJ_ALWAYS, threadStaticBlockNullCondBB, fallbackValueDef, debugInfo, true);

// fastPathBb
if (isGCThreadStatic)
{
// Need to add extra indirection to access the data pointer.

threadStaticBlockBaseLclValueUse =
gtNewIndir(TYP_I_IMPL, threadStaticBlockBaseLclValueUse, GTF_IND_NONFAULTING);
kunalspathak marked this conversation as resolved.
Show resolved Hide resolved
threadStaticBlockBaseLclValueUse =
gtNewOperNode(GT_ADD, callType, threadStaticBlockBaseLclValueUse,
gtNewIconNode(threadStaticBlocksInfo.offsetOfGCDataPointer, TYP_I_IMPL));
}

GenTree* fastPathValueDef =
gtNewStoreLclVarNode(threadStaticBlockLclNum, gtCloneExpr(threadStaticBlockBaseLclValueUse));
BasicBlock* fastPathBb = fgNewBBFromTreeAfter(BBJ_ALWAYS, fallbackBb, fastPathValueDef, debugInfo, true);
Expand Down
10 changes: 9 additions & 1 deletion src/coreclr/jit/importer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3963,7 +3963,15 @@ GenTree* Compiler::impImportStaticFieldAccess(CORINFO_RESOLVED_TOKEN* pResolvedT

case CORINFO_FIELD_STATIC_TLS_MANAGED:

typeIndex = info.compCompHnd->getThreadLocalFieldInfo(pResolvedToken->hField);
if (pFieldInfo->helper == CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_NOCTOR_OPTIMIZED)
{
typeIndex = info.compCompHnd->getNonGCThreadLocalFieldInfo(pResolvedToken->hField);
}
else
{
assert(pFieldInfo->helper == CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE_NOCTOR_OPTIMIZED);
typeIndex = info.compCompHnd->getGCThreadLocalFieldInfo(pResolvedToken->hField);
}

FALLTHROUGH;
case CORINFO_FIELD_STATIC_SHARED_STATIC_HELPER:
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1476,6 +1476,7 @@ void HelperCallProperties::init()
case CORINFO_HELP_GETSHARED_GCSTATIC_BASE_NOCTOR:
case CORINFO_HELP_GETSHARED_NONGCSTATIC_BASE_NOCTOR:
case CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE_NOCTOR:
case CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE_NOCTOR_OPTIMIZED:
case CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_NOCTOR:
case CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_NOCTOR_OPTIMIZED:

Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/jit/valuenum.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12238,6 +12238,9 @@ VNFunc Compiler::fgValueNumberJitHelperMethodVNFunc(CorInfoHelpFunc helpFunc)
case CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE_NOCTOR:
vnf = VNF_GetsharedGcthreadstaticBaseNoctor;
break;
case CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE_NOCTOR_OPTIMIZED:
vnf = VNF_GetsharedGcthreadstaticBaseNoctorOptimized;
break;
case CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_NOCTOR:
vnf = VNF_GetsharedNongcthreadstaticBaseNoctor;
break;
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/valuenumfuncs.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ ValueNumFuncDef(GetgenericsNongcthreadstaticBase, 1, false, true, true)
ValueNumFuncDef(GetsharedGcthreadstaticBase, 2, false, true, true)
ValueNumFuncDef(GetsharedNongcthreadstaticBase, 2, false, true, true)
ValueNumFuncDef(GetsharedGcthreadstaticBaseNoctor, 2, false, true, true)
ValueNumFuncDef(GetsharedGcthreadstaticBaseNoctorOptimized, 1, false, true, true)
ValueNumFuncDef(GetsharedNongcthreadstaticBaseNoctor, 2, false, true, true)
ValueNumFuncDef(GetsharedNongcthreadstaticBaseNoctorOptimized, 1, false, true, true)
ValueNumFuncDef(GetsharedGcthreadstaticBaseDynamicclass, 2, false, true, true)
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/tools/Common/JitInterface/CorInfoHelpFunc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ public enum CorInfoHelpFunc
CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE,
CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE,
CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE_NOCTOR,
CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE_NOCTOR_OPTIMIZED,
CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_NOCTOR,
CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_NOCTOR_OPTIMIZED,
CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE_DYNAMICCLASS,
Expand Down
11 changes: 10 additions & 1 deletion src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2859,7 +2859,16 @@ private nuint printFieldName(CORINFO_FIELD_STRUCT_* fld, byte* buffer, nuint buf
}

#pragma warning disable CA1822 // Mark members as static
private uint getThreadLocalFieldInfo(CORINFO_FIELD_STRUCT_* fld)
private uint getNonGCThreadLocalFieldInfo(CORINFO_FIELD_STRUCT_* fld)
#pragma warning restore CA1822 // Mark members as static
{
// Implemented for JIT only for now.

return 0;
}

#pragma warning disable CA1822 // Mark members as static
private uint getGCThreadLocalFieldInfo(CORINFO_FIELD_STRUCT_* fld)
#pragma warning restore CA1822 // Mark members as static
{
// Implemented for JIT only for now.
Expand Down