runtime/wasm: enable cooperative safepoints and GC by default (based on #107 #111) - #116
Draft
cpunion wants to merge 4 commits into
Draft
Conversation
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
This was referenced Aug 1, 2026
Open
LLGo baseline benchmarks
Program measurements
Core language and compiler benchmarks
Compared only with the latest matching platform in the main series. Warning
|
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.
Depends on #107 and #111.
Part of xgo-dev#2152.
Problem
#111 preserves compiler-published roots for running and suspended goroutines, but collection still requires an internal opt-in tag. A CPU-bound goroutine can also monopolize the single wasm worker indefinitely, preventing host timers, runnable goroutines, and timer-triggered GC from running.
Implementation
internal/safepointplanCFG analysis. It inserts polls at declared Go function entries and DFS cycle-closing backedges, intersecting reducible and irreducible cycles without polling every loop block.Origin/Parentbefore instrumentation. Runtime packages,//go:nosplit, cgo bodies, and package-less synthetic forwarding wrappers remain outside instrumentation.LLGO_WASI_THREADS=1behavior as the historical pthread/non-GC path. Combining it explicitly with the internalllgo_wasm_gcsource-selection tag remains an error.syscall/js.Valuenested in another struct.posix_memalignfrom the collector allocator because Emscripten GC selection uses-sMALLOC=none.The planner, compiler emission, root liveness, poll budget, scheduler slow path, host event queue, and collector remain separate modules.
Runtime flow
Validation
All local work used
GOMAXPROCS=2,GOMEMLIMIT=4GiB, and-p=1; Ubuntu containers were limited to 2 CPUs and 6 GiB.ssa,internal/build, and runtime-module tests pass on macOS.-O0and-O3; J64 and P1 ThinLTO pass.-O3on J32/J64/P1.wasm-tools validate --features all.llvm_gc_root_chain, collector, orCooperativeSafepointsymbol.Coverage highlights from local profiles:
internal/safepointplan: 100%runtime/internal/pollbudget: 100%configureWasmGCandhasBuildTag: 100%Cost
On Apple M4 Max, the warm
BenchmarkBudgetPollrange is 1.797-1.862 ns/op, median 1.828 ns/op, with 0 B/op and 0 allocs/op.A target-level
-O3microbenchmark compares the same 20-million-iteration arithmetic loop with a normal poll at every backedge against a//go:nosplitno-poll control. Values are medians of five rounds:This intentionally minimal loop is a worst case: the relative increase is 41-47%, while the absolute backedge cost is about 1.6-1.7 ns and does not allocate.
Enabling the collector and polls by default increases the unoptimized scheduler fixture relative to the direct #107 + #111 integration base:
Non-wasm output is unaffected:
Review scope
Excluding the dependency merge, this PR changes 21 files with +786/-30. Four commits separate nested type-patch correctness, compiler planning/emission, runtime polling, and default build/acceptance behavior. M1/M2 continuation work is intentionally outside this PR.