[Wasm RyuJIT] Wire up GC info encoding/decoding for Wasm#126932
[Wasm RyuJIT] Wire up GC info encoding/decoding for Wasm#126932kg wants to merge 8 commits intodotnet:mainfrom
Conversation
|
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch |
There was a problem hiding this comment.
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_GCINFOfor WASM and wire upCodeGen::genCreateAndStoreGCInfoto useGcInfoEncoder. - 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). |
|
Latest problem: with 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? |
| #ifndef TARGET_WASM | ||
| // Precondition: byRefMask is a subset of regMask. | ||
| assert((byRefMask & ~regMask) == 0); | ||
|
|
There was a problem hiding this comment.
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.
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.: |
… are working as designed
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
| @@ -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++) | |||
There was a problem hiding this comment.
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.
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.