runtime: move goroutine state into stack-rooted getg context#2074
Closed
cpunion wants to merge 10 commits into
Closed
runtime: move goroutine state into stack-rooted getg context#2074cpunion wants to merge 10 commits into
cpunion wants to merge 10 commits into
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
This was referenced Jul 13, 2026
cpunion
force-pushed
the
codex/runtime-g-state
branch
from
July 13, 2026 10:28
43d891a to
acdfbaf
Compare
cpunion
force-pushed
the
codex/runtime-g-state
branch
6 times, most recently
from
July 14, 2026 02:07
763f657 to
3c2395b
Compare
cpunion
marked this pull request as draft
July 14, 2026 04:39
cpunion
force-pushed
the
codex/runtime-g-state
branch
2 times, most recently
from
July 14, 2026 14:31
b6260f1 to
397bb99
Compare
cpunion
force-pushed
the
codex/runtime-g-state
branch
from
July 15, 2026 00:36
397bb99 to
89701f5
Compare
Collaborator
Author
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.
Dependency
This PR is stacked on #2079 at
7f7ce3bd0. #2079 provides the current-context anchor and outer entry-context lifecycle. This PR only uses that facility to hold existing runtime goroutine state; it does not change locality directive semantics, storage planning, initialization, or lowering. The GitHub base remainsmainbecause the dependency branch is in a fork.Problem
The pthread-hosted runtime currently spreads state owned by one goroutine across unrelated mechanisms:
pthread_self/pthread_equal.There is no common runtime
gowner. Hot defer-chain reads take a dynamic pthread-key lookup, first use needs separate state setup, and each additional field needs another key or lifetime rule. #2079 alone does not migrate this existing runtime state, so these costs and ownership rules remain without this PR.Design
Introduce one small runtime-owned
g:On pthread-hosted LLGo targets,
gis stored inline in the active outer entry context.getgloads the existing native TLS current-context anchor and returns the address ofgat a fixed offset. The lookup has no pthread-key call, lock, allocation, hash, or dynamic search.The runtime publishes
LLGoNeedsLocalContextso generated entry wrappers install a context even when no source declaration otherwise requests one. This uses #2079's existingLOCAL_CONTEXTcache-fingerprint mode; it adds no compiler target-name check, exported compiler API, or build tag.Bare-metal, host-side non-LLGo tests, and the current single-threaded
nintendoswitchruntime use one process-globalg. Nintendo Switch does not currently provide the pthread/native-TLS runtime required by the hosted representation. Its existing build tag selects the fallback entirely inside the runtime, preserving the empty-program target build without adding compiler-side target logic. A future task-context implementation can replace that fallback without changinggetgcallers.Lifetime And Roots
main, LLGo-created goroutines, and exported Go entries install the outer context before runtime code can callgetg. Exported entries are included because a C-created thread must acquire valid runtime state before entering Go. Nested entries reuse the active context.Normal return restores the previous context.
runtime.Goexitperforms the same teardown beforepthread_exit. The outer context lives in a thread stack scanned by BDWGC, so pointers held bygremain visible withoutRegisterLocalRoot,GC_add_roots, a pthread destructor, or a separately registered TLS range.Cost
On a 64-bit pthread-hosted target:
ggaccess allocationgetgallocationThe 24-byte
gis the incremental context size added by this PR. A program that did not otherwise need an outer context pays the full 32-byte stack context and 8-byte thread anchor. The stack context is reserved once for each outer main/goroutine/exported entry, not for every Go function call.On the final #2079 rebase, the retained
GetThreadDeferbenchmark measured the inline path at 1.265-1.286 ns/op (500ms x 5) versus the retained 2.321-2.337 ns/op pthread-key baseline, with 0 B/op and 0 allocs/op on both steady paths. An earlier separately allocatedgprototype added roughly 64 B on first defer use; storingginline removed that allocation.Caller metadata, FIPS bypass depth,
sync.Pool, and genuinely dynamic TLS handles are intentionally unchanged.Validation
All local commands were serialized with
GOMAXPROCS=2,GOMEMLIMIT=2GiB,GOFLAGS=-p=1, and a 15 GiB process-tree or container limit. No test was skipped or ignored.ssa,internal/build, andclsuites pass on the final compiler/runtime: add //llgo:tls and //llgo:gls package variables #2079 rebase; peak process-tree RSS was about 1.83 GiB.TestRuntimeGStateIsolationand fulltest/llgoextpass; peak process-tree RSS was about 1.51 GiB and 1.37 GiB respectively.TestRuntimeGStateIsolation, and fulltest/llgoextpass.nintendoswitchempty-programdlfcn.hcross-compile failure. The final rebased branch builds that target successfully; no target was added to an ignore list.align 1versus emittedalign 4) and root-permission assumptions; these reproduce outside this PR and were not hidden by changing or skipping tests.ssaproduction lines are covered 13/13 (100%, no partial branches). The changedclfiles are codegen goldens rather than production code.cl/compile.go:1713, which was the old stacked head's only partial line.Commits
runtime: consolidate goroutine state behind getgtest: cover runtime g state isolation