Skip to content

[Wasm RyuJIT] Wire up GC info encoding/decoding for Wasm#126932

Draft
kg wants to merge 8 commits intodotnet:mainfrom
kg:wasm-gcinfo-1
Draft

[Wasm RyuJIT] Wire up GC info encoding/decoding for Wasm#126932
kg wants to merge 8 commits intodotnet:mainfrom
kg:wasm-gcinfo-1

Conversation

@kg
Copy link
Copy Markdown
Member

@kg kg commented Apr 15, 2026

This set of changes is sufficient to R2R release S.P.CoreLib like before but with gc info encoding wired up and working. Still figuring out how to clean some of it up, feedback welcome.

@kg kg added the NO-MERGE The PR is not ready for merge yet (see discussion for detailed reasons) label Apr 15, 2026
Copilot AI review requested due to automatic review settings April 15, 2026 03:04
@kg kg added NO-REVIEW Experimental/testing PR, do NOT review it arch-wasm WebAssembly architecture labels Apr 15, 2026
@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 Apr 15, 2026
@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.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR enables GC info encoding/decoding support for the CoreCLR WASM RyuJIT backend by turning on GCInfo generation, adding the necessary encoder/decoder sources to the WASM JIT build, and introducing a WASM-specific GC info encoding definition.

Changes:

  • Enable EMIT_GENERATE_GCINFO for WASM and wire up CodeGen::genCreateAndStoreGCInfo to use GcInfoEncoder.
  • Add/adjust conditional compilation to skip register-GC-tracking paths on WASM while still enabling GC info generation.
  • Update CMake wiring to link WASM standalone JITs against the appropriate gcinfo_* library and add a universal wasm gcinfo target.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/coreclr/jit/targetwasm.h Enables GC info generation for WASM (but comment needs updating).
src/coreclr/jit/gcinfo.cpp Disables register pointer marking path for WASM.
src/coreclr/jit/gcencode.cpp Disables register-state-change recording for WASM.
src/coreclr/jit/emit.cpp Disables register-GC live update emission for WASM.
src/coreclr/jit/codegenwasm.cpp Implements GCInfo creation/emission via GcInfoEncoder for WASM.
src/coreclr/jit/codegenlinear.cpp Skips GC register update/debug validation paths for WASM.
src/coreclr/jit/codegencommon.cpp Skips register-based GC liveness updates/validation for WASM.
src/coreclr/jit/CMakeLists.txt Ensures standalone JIT links a gcinfo lib and builds gcencode/gcdecode for WASM JIT.
src/coreclr/inc/gcinfotypes.h Adds Wasm32GcInfoEncoding and sets it as the WASM target encoding.
src/coreclr/gcinfo/CMakeLists.txt Adds gcinfo_universal_wasm target (currently under the wrong build condition for the failing scenario).

Comment thread src/coreclr/gcinfo/CMakeLists.txt
Comment thread src/coreclr/jit/targetwasm.h Outdated
@kg
Copy link
Copy Markdown
Member Author

kg commented Apr 16, 2026

Latest problem: with

--singlemethodtypename:"System.AppContext"
--singlemethodname:"OnUnhandledException"
--singlemethodindex:2

We call genEmitUnwindDebugGCandEH multiple times on some methods, and the second call attempts to overwrite existing debug information and (rightly, as far as I can tell) fails. I can't figure out why we're doing this, maybe something to do with funclets?

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.

Comment on lines +4649 to 4652
#ifndef TARGET_WASM
// Precondition: byRefMask is a subset of regMask.
assert((byRefMask & ~regMask) == 0);

Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

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

With the new #ifndef TARGET_WASM guard inside gcInfoRecordGCRegStateChange, the WASM build compiles an empty function body that doesn’t reference any of the parameters. On toolchains that enable -Wunused-parameter (often as -Werror in CoreCLR builds), this can fail the build. Consider either adding explicit unused-parameter suppression for the WASM case or moving the #ifndef to exclude the whole implementation and providing a small stub that marks parameters as unused.

Copilot uses AI. Check for mistakes.
Comment thread src/coreclr/jit/CMakeLists.txt
@kg
Copy link
Copy Markdown
Member Author

kg commented Apr 17, 2026

Latest problem: with

--singlemethodtypename:"System.AppContext"
--singlemethodname:"OnUnhandledException"
--singlemethodindex:2

We call genEmitUnwindDebugGCandEH multiple times on some methods, and the second call attempts to overwrite existing debug information and (rightly, as far as I can tell) fails. I can't figure out why we're doing this, maybe something to do with funclets?

This was intentional behavior - we were failing the compilation of a method as R2R unsupported late enough in compilation that debug info had already been generated, then hit an assertion the second time we tried to generate debug info (on the retried compilation). I think the asserts are just wrong in this case.

Now failing with block(s) missing a bbEmitCookie in particular methods, i.e.:

--singlemethodtypename:"System.GC"
--singlemethodname:"RunFinalizers"
--singlemethodindex:1
*************** In genSetScopeInfo()
VarLocInfo count is 7
; Variable debug info: 7 live ranges, 4 vars for method System.GC:RunFinalizers():uint
(V00 SP) : From 00000000h to 0000000Ah, in $1
(V01 arg0) : From 0000006Ah to 00000152h, in '[0] (1 slot)
(V01 arg0) : From 00000178h to 000001ECh, in '[0] (1 slot)
(V02 loc1) : From 00000074h to 0000014Ah, in '[56] (1 slot)
(V02 loc1) : From 00000150h to 00000159h, in '[56] (1 slot)
(V02 loc1) : From 00000178h to 000001ECh, in '[56] (1 slot)
(V04 loc3) : From 000000DEh to 000000F2h, in $2
*************** In gcInfoBlockHdrSave()
Set code length to 493.
Set stack base register to NA.
Stack slot id for offset 52 (0x34) (frame) (untracked) = 0.
Z:\runtime\src\coreclr\jit\jiteh.cpp:1120
Assertion failed 'cookie != nullptr' in 'System.GC:RunFinalizers():uint' during 'Emit GC+EH tables' (IL size 81; hash 0x81ce67df; FullOpts)

Copilot AI review requested due to automatic review settings April 17, 2026 01:21
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 3 comments.

Comment thread src/coreclr/jit/codegenlinear.cpp Outdated
@kg kg removed NO-REVIEW Experimental/testing PR, do NOT review it NO-MERGE The PR is not ready for merge yet (see discussion for detailed reasons) labels Apr 17, 2026
Copilot AI review requested due to automatic review settings April 17, 2026 01:51
@kg kg force-pushed the wasm-gcinfo-1 branch from 5ba8436 to 02ce8d6 Compare April 17, 2026 01:56
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Comment thread src/coreclr/jit/gcencode.cpp
Comment on lines 1584 to 1614
@@ -1601,7 +1606,9 @@ private void setVars(CORINFO_METHOD_STRUCT_* ftn, uint cVars, NativeVarInfo* var
/// </summary>
private void setBoundaries(CORINFO_METHOD_STRUCT_* ftn, uint cMap, OffsetMapping* pMap)
{
Debug.Assert(_debugLocInfos == null);
// FIXME: This can erroneously trigger when a method fails compilation late and we
// successfully retry compilation after the failure.
// Debug.Assert(_debugLocInfos == null);

_debugLocInfos = new OffsetMapping[cMap];
for (int i = 0; i < cMap; i++)
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

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

Commenting out the asserts here avoids the immediate retry issue, but it also removes useful debug validation and leaves a lingering FIXME in production code. Since setVars/setBoundaries appear to be allowed to run multiple times on a single CorInfoImpl instance (e.g., after a late compilation failure + retry), consider explicitly resetting the stored debug info state when starting a new compilation attempt (or before retry) and keep the asserts, rather than leaving them commented out.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

arch-wasm WebAssembly architecture 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.

2 participants