Expand TLS access inline for Apple platforms - #133050
Draft
EgorBo wants to merge 2 commits into
Draft
Conversation
On Apple targets the JIT called dyld's `tlv_get_addr` thunk to get the
address of `t_ThreadStatics`. Inline its fast path instead, like the
other 64-bit targets do.
The VM derives the pthread TSD key of coreclr's thread local block from
the TLV descriptor and the offset of `t_ThreadStatics` within that block,
validates them against the descriptor, and passes the key to the JIT in
the new `tlsPthreadKey` field. If anything does not check out the key
stays 0 and the JIT keeps calling the thunk.
arm64:
mrs xd, tpidrro_el0
and xd, xd, #~7
ldr xd, [xd, #key * 8]
x64:
mov xd, gs:[key * 8]
Fixes dotnet#133041
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Azure Pipelines: Successfully started running 6 pipeline(s). 10 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
Member
Author
|
@EgorBot -macos_arm --envvars DOTNET_JitDisasm:IntTls using BenchmarkDotNet.Attributes;
public class MyBench
{
[ThreadStatic] static int _tls1;
[ThreadStatic] static string _tls2;
[Benchmark] public int IntTls() => _tls1;
[Benchmark] public string StringTls() => _tls2;
} |
Contributor
|
Tagging @dotnet/jit-contrib for JIT-EE GUID update |
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
The cache publication has a C++ data race, and the intended Apple code generation lacks automated coverage.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Optimizes CoreCLR thread-static access on Apple x64/arm64 by bypassing dyld’s TLS thunk when its descriptor can be safely validated.
Changes:
- Derives and caches the pthread TSD key and thread-static offset.
- Emits direct GS/TPIDRRO TLS loads with thunk fallback.
- Extends JIT-EE and SuperPMI structures and updates versioning.
File summaries
| File | Description |
|---|---|
src/coreclr/vm/threadstatics.cpp |
Discovers and caches Apple TLS metadata. |
src/coreclr/jit/helperexpansion.cpp |
Selects direct Apple TLS access. |
src/coreclr/jit/emitarm64.cpp |
Emits TPIDRRO-based loads. |
src/coreclr/jit/codegenarm64.cpp |
Guards Apple TLS-handle handling. |
src/coreclr/jit/instrsarm64.h |
Defines the TPIDRRO instruction. |
src/coreclr/inc/corinfo.h |
Adds the pthread key field. |
src/coreclr/inc/jiteeversionguid.h |
Updates JIT-EE versioning. |
src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs |
Mirrors the field for managed tooling. |
src/coreclr/tools/superpmi/superpmi-shared/agnostic.h |
Extends the serialized structure. |
src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp |
Records, dumps, and replays the key. |
Review details
- Files reviewed: 10/10 changed files
- Comments generated: 2
- Review effort level: Balanced
Address PR feedback: the payload was published with plain writes behind a volatile flag, which is a data race between racing initializers. Use Volatile<T> so all accesses are atomic. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
EgorBo
force-pushed
the
EgorBo/apple-inline-tls
branch
from
September 2, 2026 00:22
97e380b to
cf7b38c
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #133041. (mostly just AI, to see if it passes CI)
On Apple targets the JIT emitted a call to dyld's
tlv_get_addrthunk to obtain the address oft_ThreadStatics. Inline its fast path instead, like the other 64-bit targets already do.The VM derives the pthread TSD key of coreclr's thread local block from the TLV descriptor, plus the offset of
t_ThreadStaticswithin that block (folded intooffsetOfBaseOfThreadLocalData), and passes the key to the JIT in the newtlsPthreadKeyfield. The derived offset must exactly match the descriptor'soffsetfield in one of the two layouts dyld has shipped; if anything does not check out,tlsPthreadKeystays 0 and the JIT keeps calling the thunk.; Assembly listing for method MyBench:IntTls():int:this (Tier1) ; Emitting BLENDED_CODE for arm64 on Apple ; Tier1 code ; optimized code ; optimized using Synthesized PGO ; fp based frame ; partially interruptible ; with Synthesized PGO: fgCalledCount is 100 ; No PGO data G_M000_IG01: ;; offset=0x0000 stp fp, lr, [sp, #-0x10]! mov fp, sp G_M000_IG02: ;; offset=0x0008 - movz x0, #0xAFE0 - movk x0, #823 LSL #16 - movk x0, #1 LSL #32 - movz x1, #0xAFE0 - movk x1, #823 LSL #16 - movk x1, #1 LSL #32 - ldr x1, [x1] - blr x1 ;; <-- call - add x0, x0, #60 + mrs x0, tpidrro_el0 + and x0, x0, #-8 + ldr x0, [x0, #0x810] + add x0, x0, #356 ldr w0, [x0, #0x10] -G_M000_IG03: ;; offset=0x0030 +G_M000_IG03: ;; offset=0x001C ldp fp, lr, [sp], #0x10 ret lr -; Total bytes of code 56 +; Total bytes of code 36x64 —
mov rax, gs:[key*8], reusing the existingFLD_GLOBAL_GScodegen.Notes
__threadstate through the thunk, which instantiates the block. The invariant is written down inhelperexpansion.cpp.ILCompiler/Program.cs), sofgExpandThreadLocalAccessForCallNativeAOTis not reachable on Apple. Enabling them there needs TLV section/reloc support inMachObjectWriterfirst, and would use the thunk rather than this inline sequence (the key is only known at load time).