Skip to content

[wasm] Avoid Spilling Many GC-ref Typed Tree Temps - #135577

Merged
adamperlin merged 5 commits into
dotnet:mainfrom
adamperlin:adamperlin/wasm-spill-refs-opt
Oct 15, 2026
Merged

adamperlin merged 5 commits into
dotnet:mainfrom
adamperlin:adamperlin/wasm-spill-refs-opt

Conversation

@adamperlin

@adamperlin adamperlin commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

The current fgWasmSpillRefs pass spills all outstanding GC-ref typed temporary values, even if those temps are consumed by the most immediate call. However, for calls it should be the callee's responsibility to maintain GC safety of any incoming GC-ref typed args (either by spilling to a pinned stack home, spilling and reloading, or potentially avoiding spilling at all, see #135543). In the R2R fixup case, where a thunk will fix up the call target on first invocation, we should also be GC-protecting all incoming args by default (See the spilling logic in crossgen2 WasmImportThunk.cs).

This PR removes the need for spilling in cases like:

MyClass x = Allocate();
Use(x);

Note that the spilling STILL needs to happen for nested calls, where a ref has an outstanding use which is NOT its most immediate parent.

MyClass x = Allocate();
M(x, F()) // <-- temporary value of x is an operand of the call to M, and may be live across the other sub-tree call, F where a GC might occur.

Results

SuperPMI

Total bytes of base: 8771651
Total bytes of diff: 8555629
Total bytes of delta: -216,022 (-2.46% of base)

Local Benchmarks

Metric CoreCLR baseline CoreCLR after Change
Mobile cold startup 7,474 ms 6,901 ms 7.7% faster
Desktop walkthrough 5.60 s 6.05 s 8.1% slower
Desktop cold download 10.324 MB 10.215 MB 1.1% smaller
Havit publish 150.81 s 149.21 s 1.1% faster
Cold download and startup improve as expected. I didn't put too much weight on the walkthrough benchmark because it is only run once and is pretty variable.

@github-actions github-actions Bot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Oct 10, 2026
@azure-pipelines

Copy link
Copy Markdown
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.

@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
See info in area-owners.md if you want to be subscribed.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Explicit call null checks can invoke a GC-triggering throw helper before the callee protects the newly unspilled arguments.

1 open finding
What changed in this PR

Optimizes Wasm GC-reference handling by avoiding unnecessary spills for arguments passed directly to managed calls.

Changes:

  • Extracts operand-use removal into a reusable helper.
  • Removes managed-call arguments before spilling other live references.
  • Preserves spills for nested, helper, and unmanaged calls.

A blocking GC-safety issue remains for managed calls with explicit null checks.

File Description
src/​coreclr/​jit/​fgwasm.cpp Refines GC-reference spill decisions around calls.

🧠 Review effort: Balanced

Comment thread src/coreclr/jit/fgwasm.cpp Outdated
Comment thread src/coreclr/jit/fgwasm.cpp Outdated
@adamperlin
adamperlin force-pushed the adamperlin/wasm-spill-refs-opt branch from 06c6b43 to 9f2a77c Compare October 14, 2026 23:33
@adamperlin
adamperlin marked this pull request as ready for review October 14, 2026 23:44
@adamperlin
adamperlin requested a review from EgorBo October 14, 2026 23:45
@adamperlin

Copy link
Copy Markdown
Contributor Author

cc @dotnet/wasm-contrib

@EgorBo EgorBo left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks very similar to what async.cpp does, wondering if we can share that

@adamperlin
adamperlin merged commit 2165605 into dotnet:main Oct 15, 2026
128 of 131 checks passed
@adamperlin
adamperlin deleted the adamperlin/wasm-spill-refs-opt branch October 15, 2026 15:52
@dotnet-milestone-bot dotnet-milestone-bot Bot added this to the 12.0-preview1 milestone Oct 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants