Skip to content

Commit

Permalink
[LoongArch64] Enable TLS on linux/loongarch64 only for static resolve…
Browse files Browse the repository at this point in the history
…r. (#106250)
  • Loading branch information
shushanhf authored and pull[bot] committed Sep 26, 2024
1 parent 0176860 commit 2023020
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 3 deletions.
17 changes: 16 additions & 1 deletion src/coreclr/vm/loongarch64/asmhelpers.S
Original file line number Diff line number Diff line change
Expand Up @@ -1088,7 +1088,7 @@ GenerateProfileHelper ProfileTailcall, PROFILE_TAILCALL
NESTED_ENTRY OnCallCountThresholdReachedStub, _TEXT, NoHandler
PROLOG_WITH_TRANSITION_BLOCK

addi.d $a0, $sp, __PWTB_TransitionBlock // TransitionBlock *
addi.d $a0, $sp, __PWTB_TransitionBlock // TransitionBlock *
ori $a1, $t1, 0 // stub-identifying token
bl C_FUNC(OnCallCountThresholdReached)
ori $t4,$a0,0
Expand All @@ -1112,3 +1112,18 @@ LEAF_ENTRY GetThreadStaticsVariableOffset, _TEXT
EPILOG_RETURN
LEAF_END GetThreadStaticsVariableOffset, _TEXT
// ------------------------------------------------------------------

// ------------------------------------------------------------------
// size_t GetTLSResolverAddress()

// Helper to get the TLS resolver address. This will be then used to determine if we have a static or dynamic resolver.
LEAF_ENTRY GetTLSResolverAddress, _TEXT
// $fp,$ra
PROLOG_SAVE_REG_PAIR_INDEXED 22, 1, 16
pcalau12i $a0, %desc_pc_hi20(t_ThreadStatics)
addi.d $a0, $a0, %desc_pc_lo12(t_ThreadStatics)
ld.d $a0, $a0, %desc_ld(t_ThreadStatics)
EPILOG_RESTORE_REG_PAIR_INDEXED 22, 1, 16
EPILOG_RETURN
LEAF_END GetTLSResolverAddress, _TEXT
// ------------------------------------------------------------------
26 changes: 24 additions & 2 deletions src/coreclr/vm/threadstatics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -784,9 +784,9 @@ void FreeTLSIndicesForLoaderAllocator(LoaderAllocator *pLoaderAllocator)

static void* GetTlsIndexObjectAddress();

#if !defined(TARGET_OSX) && defined(TARGET_UNIX) && defined(TARGET_ARM64)
#if !defined(TARGET_OSX) && defined(TARGET_UNIX) && (defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64))
extern "C" size_t GetTLSResolverAddress();
#endif // !TARGET_OSX && TARGET_UNIX && TARGET_ARM64
#endif // !TARGET_OSX && TARGET_UNIX && (TARGET_ARM64 || TARGET_LOONGARCH64)

bool CanJITOptimizeTLSAccess()
{
Expand Down Expand Up @@ -833,6 +833,28 @@ bool CanJITOptimizeTLSAccess()
}
#endif
}
#elif defined(TARGET_LOONGARCH64)
// Optimization is enabled for linux/loongarch64 only for static resolver.
// For static resolver, the TP offset is same for all threads.
// For dynamic resolver, TP offset returned is for the current thread and
// will be different for the other threads.
uint32_t* resolverAddress = reinterpret_cast<uint32_t*>(GetTLSResolverAddress());

if (
// ld.d a0, a0, 8
(resolverAddress[0] == 0x28c02084) &&
// ret
(resolverAddress[1] == 0x4c000020)
)
{
optimizeThreadStaticAccess = true;
#ifdef _DEBUG
if (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_AssertNotStaticTlsResolver) != 0)
{
_ASSERTE(!"Detected static resolver in use when not expected");
}
#endif
}
#else
optimizeThreadStaticAccess = true;
#if !defined(TARGET_OSX) && defined(TARGET_UNIX) && defined(TARGET_AMD64)
Expand Down

0 comments on commit 2023020

Please sign in to comment.