wasm: preserve compiler roots across suspended goroutines (based on #102 #105) - #111
Draft
cpunion wants to merge 5 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 cpunion/llgo#102 and cpunion/llgo#105.
Problem
The opt-in wasm collector from #105 can scan linear-memory globals and its heap, but it cannot see a live Go pointer held only in an SSA/wasm local. The same problem applies to locals in a suspended goroutine. Without explicit publication, a collection can reclaim an object that Go code still owns.
Implementation
internal/gcrootplan, an LLVM-independent backward liveness planner over Go SSA. It identifies pointer-bearing values live across instructions whose lowering may call the runtime.{ previous frame, map, roots[N] }, linked throughllvm_gc_root_chain.wasmcontextboundary.siglongjmp, so panic/recover andGoexitcannot leave skipped function frames linked.The package boundaries are intentional:
internal/gcrootplan: Go SSA data-flow analysis only.ssa: target-independent root-frame LLVM IR and root layout helpers.cl: classification and publication of Go values.runtime/internal/gcroot: execution-owner registration, switching, and enumeration.runtime/internal/wasmcontext.All compiler and runtime behavior remains gated by the existing internal
llgo_wasm_gcselection. Native, embedded, default wasm, and explicit WASI pthread builds do not enable compiler root frames.Execution flow
llvm_gc_root_chainin the outgoing owner and restores the incoming owner's chain before switching stacks.wasmcontext.Context.Closereleases the context storage.Validation
-O0, and-O3; J64 and P1 also pass-O3 -lto=thin.wasm-toolsand executes under Wasmtime 39; J32/J64 execute under Node 25.internal/gcrootplan, fullssa, focusedcl/build tests, and the complete runtime module pass.TestFromTestlibgo/mapzerowhile under QEMU and hit its 10-minute timeout; no D test failed.text/data/bss = 140/0/10).Independent diff against the combined #102 + #105 base: 37 files,
+1859/-68.Scope
This PR does not enable wasm GC by default and does not add cooperative safepoint polling. Default enablement and active-loop polling remain the next S stage after timers and this root ABI are integrated.