Repository navigation
Compact Wasm ReadyToRun GC and unwind metadata - #135821
davidwrighton wants to merge 25 commits into
Conversation
Specialize register-free codecs, use implicit frame-relative pointer-scaled slots, enable slim headers, encode flags-first offset runs, and normalize unwind frames to 16-byte units. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Retain and consume the zero tracked-slot and safepoint counts, while specializing away tracked descriptors and lifetime parsing. Keep interpreter and native-target tracked-root support. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use ReadyToRun 33.0 to distinguish the compact codec from older images and the separate proposed 32.0 frame-identity format. Reject older Wasm images in single-file and composite loading and in the managed reader before decoding. Keep native minimum-version handling unchanged. Add cross-target header compatibility regressions and document the encoding. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Azure Pipelines: Successfully started running 8 pipeline(s). 7 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
|
Tagging subscribers to this area: @dotnet/crossgen-contrib |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Generalize shrinking slot flags and bounded register encoding, pack Wasm unwind data, and omit redundant Wasm header fields. Select the whole-image Brotli-winning integer bases while retaining version-aware readers and focused decoder coverage. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Resolve the StackWalk documentation conflict by retaining packed GC/unwind metadata alongside upstream's handle-based unwind lookup. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Require ReadyToRun 33 and GCInfo v6 on every runtime target. Remove legacy Wasm header and slot decoding while preserving older native formats in cDAC, R2R inspection tools, and the SOS decoder. Add v5 native and interpreter fixtures and update the format documentation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Invert the Wasm pinned bit for slot sorting and encoding so pinned object roots sort last and omit repeated flags. Update native, ReadyToRun, and cDAC readers, regression coverage, and format documentation while retaining non-Wasm and interpreter encoding. Fresh same-input retail CoreLib measurements: image 20,891,864 -> 20,890,520 bytes; GC/unwind table 25,802 -> 24,448 bytes; whole-image Brotli q11/window22 3,806,455 -> 3,804,636 bytes. Decoded GC metadata matches for 52,559 methods. These use current IL rather than the historical measurement inputs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Select InterpreterGcInfoDecoder for reverse-P/Invoke detection, generic-context prolog checks, and interruptible-range enumeration on interpreter frames. Keep native frame decoding unchanged. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 798665fd-8e9d-46c8-b56c-843764cdb3d1
Set the Wasm GC encoder's frame register even when optimization removes the linear-memory frame, preserving the compact header invariant. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 798665fd-8e9d-46c8-b56c-843764cdb3d1
Preserve both the Wasm GC header-version tests and upstream's type-token fixup tests when resolving R2RTestSuites.cs. Rebuilt browser cross-components and passed all six cases of both theories. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 798665fd-8e9d-46c8-b56c-843764cdb3d1
…36553) <!-- --> ## Summary Use `InterpreterGcInfoDecoder` rather than the target-native `GcInfoDecoder` when inspecting an interpreted frame in: - `SfiNextWorker`, for reverse-P/Invoke detection during exception propagation. - `SafeToReportGenericParamContext`, for the generic-context prolog length. - `FindFirstInterruptiblePoint`, for the GC-reporting location when unwinding between funclets. Interpreter GC metadata has different encoding parameters and normalization from native metadata. Select the decoder using the frame's code manager, guarded by `FEATURE_INTERPRETER`, and preserve the existing decoder for native frames. Found while investigating #135821. This PR is independently based on `main` and contains no Wasm metadata-format or code-generation changes. The decoder mismatch predates that work; an observable release-mode iOS failure has not been demonstrated. ## Validation - `./build.sh clr.runtime -rc Checked` on this standalone branch: passed, zero warnings and errors. - Session-local caught-exception, generic-GC, and uncaught reverse-P/Invoke probes on this standalone branch: passed with normal execution and with `DOTNET_Interpreter='*' DOTNET_ReadyToRun=0`. The uncaught probe terminated as expected and retained `MessageFromMyException`. - On the Wasm metadata branch, the reverse-P/Invoke probe reproduced the missing-message/assertion failure before this fix and preserved the exception message afterward; the checked browser runtime build also passed. This is supplementary evidence, not a standalone-branch browser test. - `git diff upstream/main...HEAD --check`: passed. - No new checked-in regression test; existing `WasmBuildAppTest.ExceptionFromMain` caught the EH regression. - iOS execution and the full test suites were not run. > [!NOTE] > This pull request description and code changes were generated with GitHub Copilot. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 798665fd-8e9d-46c8-b56c-843764cdb3d1
Preserve upstream ReadyToRun 33.0 contextual GCRefMaps and 33.1 Wasm profiling support. Allocate ReadyToRun 34.0 to GCInfo v6, synchronize runtime/compiler/reader version boundaries, and retain the upstream cDAC test additions alongside compact Wasm fixtures. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Expose the existing GCInfo inspection interface through the cDAC COM object. Forward header, interruptible-range, safe-point, and slot-lifetime queries to the appropriate platform or interpreter decoder, with sized-buffer and HRESULT handling. Add regression coverage for interface discovery, unmanaged vtable calls, field mappings, buffer sizing, and failure outputs. Validate the NativeAOT cDAC build and 626 focused tests. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep ISOSDacInterface18 stack-base semantics independent of decoder enums and GCInfo versions. Document the existing API values and cover v5/v6 decoding, native COM output, and unsupported bases. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
🟡 Changes recommended
The v5 interpreter decoder can silently miss GC roots, Wasm reverse-P/Invoke offsets are incorrectly scaled, and the GCInfo contract still describes obsolete encoding.
3 open issues
What changed in this PR
This PR introduces GCInfo v6 and ReadyToRun 34.0 to reduce shared GC metadata size and Wasm GC/unwind overhead, coordinating the compiler, runtime, diagnostic readers, and format documentation.
Changes:
- Adds compact flags-first slot encoding and packed Wasm unwind data, with synchronized format versions.
- Updates native and managed decoders and implements cDAC’s existing
ISOSDacInterface18GC-info methods. - Adds decoding, compatibility, unwinding, and COM-interface regression coverage.
| File | Description |
|---|---|
| src/native/managed/cdac/tests/UnitTests/WasmUnwinderTests.cs | Tests packed unwind fields and malformed values. |
| src/native/managed/cdac/tests/UnitTests/StackWalkTests.cs | Updates Wasm header and unwind fixtures. |
| src/native/managed/cdac/tests/UnitTests/GCInfoTests.cs | Adds decoder and SOS interface regression tests. |
| src/native/managed/cdac/tests/UnitTests/ExecutionManager/ExecutionManagerTests.cs | Tests v6 mapping and packed unwind sizing. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/SOSDacImpl.cs | Implements four Interface18 GC-info methods. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/ISOSDacInterface.cs | Documents stable stack-base meanings. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StackWalk/Context/Wasm/WasmUnwinder.cs | Extracts frame sizes from packed unwind data. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/GCInfo/X86/GCInfo.cs | Accepts version 6 for unchanged x86 encoding. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/GCInfo/PlatformTraits/WasmGCInfoTraits.cs | Defines compact Wasm decoding traits. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/GCInfo/PlatformTraits/InterpreterGCInfoTraits.cs | Marks interpreter slots as register-free. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/GCInfo/PlatformTraits/IGCInfoTraits.cs | Adds shared compact-format trait defaults. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/GCInfo/PlatformTraits/ARMGCInfoTraits.cs | Defines ARM’s bounded register width. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/GCInfo/GCInfoDecoder.cs | Decodes compact headers and v6 slot tables. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/Helpers/UnwindDataSize.cs | Shares bounded Wasm ULEB128 reading. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/ExecutionManagerCore.ReadyToRunJitManager.cs | Maps ReadyToRun 34 onward to GCInfo v6. |
| src/coreclr/vm/wasm/helpers.cpp | Uses packed unwind data during stack walking. |
| src/coreclr/vm/readytoruninfo.cpp | Reads packed unwind values and virtual-IP spans. |
| src/coreclr/vm/proftoeeinterfaceimpl.cpp | Uses the current GCInfo version for profiling. |
| src/coreclr/vm/gcinfodecoder.cpp | Decodes compact slots and specializes Wasm handling. |
| src/coreclr/vm/gc_unwind_x86.inl | Uses the current GCInfo version for x86 unwinding. |
| src/coreclr/vm/codeman.h | Removes runtime image-version mapping declaration. |
| src/coreclr/vm/codeman.cpp | Updates unwind sizing and runtime GCInfo version selection. |
| src/coreclr/tools/Common/Internal/Runtime/ModuleHeaders.cs | Advances compiler format constants to 34.0. |
| src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Wasm32/UnwindInfo.cs | Decodes packed frame size and virtual-IP span. |
| src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs | Rejects older Wasm headers before caching them. |
| src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunMethod.cs | Preserves historical mappings while adding v6. |
| src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/NativeReader.cs | Returns 64-bit ULEB128 values. |
| src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/GCInfoTypes.cs | Updates register widths and Wasm normalization. |
| src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/GcSlotTable.cs | Reads v6 slots while retaining legacy decoding. |
| src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/GcInfo.cs | Reads compact Wasm headers and implicit fields. |
| src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/RuntimeFunctionsTableNode.cs | Extracts virtual-IP spans from packed unwind blobs. |
| src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCases/R2RTestSuites.cs | Adds regular/composite header compatibility tests. |
| src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/GcInfoDecoderTests.cs | Adds slot, header, and unwind decoding tests. |
| src/coreclr/nativeaot/Runtime/inc/ModuleHeaders.h | Synchronizes NativeAOT format constants. |
| src/coreclr/jit/unwindwasm.cpp | Emits interleaved Wasm unwind fields. |
| src/coreclr/jit/gcencode.cpp | Requires explicit stack-slot bases. |
| src/coreclr/jit/codegenwasm.cpp | Sets the implicit Wasm frame register consistently. |
| src/coreclr/inc/sospriv.idl | Documents version-independent stack-base values. |
| src/coreclr/inc/readytorun.h | Raises current and minimum ReadyToRun versions. |
| src/coreclr/inc/gcinfotypes.h | Defines compact-format platform traits. |
| src/coreclr/inc/gcinfoencoder.h | Updates encoder declarations and format comments. |
| src/coreclr/inc/gcinfodecoder.h | Adds compact slot-reading helpers and version handling. |
| src/coreclr/inc/gcinfo.h | Advances GCInfo to v6 and simplifies runtime selection. |
| src/coreclr/inc/clrnt.h | Adds shared packed-unwind extraction. |
| src/coreclr/gcinfo/gcinfoencoder.cpp | Emits grouped slots and compact Wasm headers. |
| docs/design/datacontracts/StackWalk.md | Documents packed Wasm unwinding. |
| docs/design/datacontracts/reader-version-history.md | Updates the supported ReadyToRun minimum. |
| docs/design/datacontracts/GCInfo.md | Documents compact Wasm headers and encoding parameters. |
| docs/design/datacontracts/ExecutionManager.md | Updates historical GCInfo version mappings. |
| docs/design/coreclr/botr/readytorun-format.md | Specifies v6 slots, packed unwind data, and compatibility. |
Review effort: Balanced
| private IEnumerable<DecodePoints> DecodeSlotTable() | ||
| { | ||
| if (_reader.ReadBits(1, ref _bitOffset) != 0) | ||
| if (TTraits.HAS_REGISTER_SLOTS && _reader.ReadBits(1, ref _bitOffset) != 0) |
| [Theory] | ||
| [InlineData(new byte[] { 0x09, 0x08, 0x20, 0x00 }, 8, uint.MaxValue, -1, 0u)] | ||
| [InlineData(new byte[] { 0x01, 0x09, 0x01, 0x00 }, -1, 1u, -1, 0u)] | ||
| [InlineData(new byte[] { 0x01, 0x0A, 0x03, 0x00 }, -1, uint.MaxValue, 3, 0u)] |
| The tables and decoding pseudocode below describe the common layout. Wasm platform GCInfo | ||
| version 6 omits `UsingStackBaseRegister`, `StackBaseRegister`, and `PrologSize` as described | ||
| above, and omits `NumSafePoints` only for slim headers. Its fat `HeaderFlags` occupy nine |
| private IEnumerable<DecodePoints> DecodeSlotTable() | ||
| { | ||
| if (_reader.ReadBits(1, ref _bitOffset) != 0) | ||
| if (TTraits.HAS_REGISTER_SLOTS && _reader.ReadBits(1, ref _bitOffset) != 0) |
| yield break; | ||
| } | ||
|
|
||
| private void DecodeStackSlots(uint count, bool isUntracked) |
There was a problem hiding this comment.
It may be nice to note that this method and ReadRegisterValue are for the v6 GCInfo decoding.
| } | ||
| } | ||
|
|
||
| if (TTraits.USES_COMPACT_WASM_HEADER || _gcVersion >= 6) |
There was a problem hiding this comment.
Does WASM support gcinfo version below 6? If not, is the TTraits.USES_COMPACT_WASM_HEADER in this guard required?
| if (IsRuntimeVersionAtLeast(11)) | ||
| return 5; | ||
| return 6; |
There was a problem hiding this comment.
Is this intended to be backported to net11? I was under the impression this would be for 12.
Decode the JIT's interleaved unwind fields before emitting NativeAOT xdata and pdata. This fixes the Checked WASI frame-size assertion exposed by NativeAOT test compilation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Consume the pre-v6 register-presence bit even when interpreter traits prohibit register slots. Correct the v5 interpreter fixture so it detects lost stack roots. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Report byte offsets consistently with other special stack slots and the native decoder. Cover both positive and negative Wasm offsets. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Describe shrinking flags-first descriptors, bounded register integers, compact stack bases, grouped offsets, and version-specific count bits. Keep the non-Wasm v5 algorithms explicitly labeled as legacy. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Wasm platform GCInfo supports only v6, so its traits need not override the version check used by the other platforms. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Preserve GCInfo v5 for .NET 11 and the existing mappings for earlier runtimes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Correct architecture-specific frame registers, transition scaling and range mapping, indirect live-state payload sizes, ARM64 EnC header parsing, and lazy cDAC outgoing-area decoding. Add regressions using the existing v5 format. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add a separate stack-parameter-area decode point for GetHeader while keeping ReversePInvoke aligned with the native decoder. Cover early stopping for generic-context lookups and slim headers. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
## Summary - Print the GC info address before choosing the ISOSDacInterface18 or legacy decoding path. Previously, successful Interface18 decoding returned before the address was printed. - Preserve the existing address format and legacy decoding behavior, printing the address exactly once. - Extend the existing GCInfo test to assert that MethodDesc and instruction-pointer inputs report the same GC info address. Discovered while working on dotnet/runtime#135821. ## Validation - Repository build succeeded with system CMake 3.28.3: `./build.sh /p:WarningsNotAsErrors=NU1903`. The override retains an existing ILCompiler package advisory as a warning; no package or build configuration changes are included. - Focused `SOS.Tests.CodeInfoTests.GcInfo_ReportsEncoding` test passed for both legacy DAC and cDAC on .NET 11 (2 cases). - The available cDAC does not implement ISOSDacInterface18, so these runs verify existing-path compatibility, not Interface18 execution. The fix prints the address from the already-retrieved code header before querying Interface18, ensuring its successful early return cannot omit that output. End-to-end verification with an implementing cDAC remains outstanding. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: d6045f2a-f938-4892-bdfa-016e6e58fc35
<!-- --> ## Summary Fix seven pre-existing GCInfo reader defects without changing the on-disk format, GCInfo/R2R version, encoder, or Wasm-specific behavior: - Decode LoongArch64's normalized frame pointer as register 22, not register 2. - Decode RISC-V64's normalized stack pointer as register 2, not register 9, while retaining support for the older nonzero encoding. - Denormalize fully interruptible transition offsets before combining them with byte-based ranges. - Map transitions correctly at half-open range boundaries and across multiple skipped ranges, including methods without explicit interruptible ranges. - Measure indirect safe-point payloads using the furthest referenced bitmap end, rather than the last bitmap visited. Cover both ordinary and RLE bitmaps. - Consume ARM64's additional EnC fixed-frame-size field so subsequent fields remain aligned. This is a latent parser issue; ordinary crossgen2 compilation does not enable EnC. - Decode cDAC's outgoing/scratch parameter area before returning a header, using a separate stop point that preserves the native reverse-P/Invoke decoding boundary. The PR contains only diagnostic/tooling decoder fixes and regression tests, based on `main`. It does not depend on the GCInfo v6 work in #135821. ## Validation Added 36 R2R regression cases and seven cDAC cases using the existing GCInfo v5 format. Before applying the original fixes, the new tests demonstrated 28 R2R failures and five cDAC failures. Additional review regressions verify that generic-context lookup does not read the outgoing area and that slim-header decoding does not read the safe-point count. Both commands below were run successfully on this isolated, main-based branch with zero build warnings or errors: ```sh ./dotnet.sh build src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/ILCompiler.ReadyToRun.Tests.csproj -c Checked /p:RuntimeConfiguration=Checked /p:LibrariesConfiguration=Release /p:CoreCLRConfiguration=Checked /t:Build,Test ``` Result: **179 passed, 0 failed, 15 existing skips**, including all 36 new regression cases. ```sh ./dotnet.sh build src/native/managed/cdac/tests/UnitTests/Microsoft.Diagnostics.DataContractReader.Tests.csproj -c Checked /p:RuntimeConfiguration=Checked /p:LibrariesConfiguration=Release /t:Build,Test ``` Result: **3,969 passed, 0 failed, 0 skipped**, including all seven new regression cases. The fixtures exercise AMD64, ARM32, ARM64, LoongArch64, and RISC-V64 decoding on Linux x64; they are not native execution tests on those other architectures. > [!NOTE] > This PR and its description were prepared with GitHub Copilot. --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…asm-gc-metadata Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> # Conflicts: # src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/GCInfoTypes.cs



Description
Compact GC metadata on platforms using the shared GC-info codec, and reduce Wasm ReadyToRun GC/unwind overhead. This started as an extraction from #135553; the slot-format improvements now extend beyond Wasm.
The safepoint-state and chunked-liveness wire formats are unchanged: no changes to chunk sizes, chunk pointers, bitmap/RLE masks, final-state bits, or per-slot transition lists. The transition-count, chunk-pointer, and deduplication alternatives discussed during investigation are not implemented by this PR.
Update the native encoder/decoder, JIT/runtime unwind handling, ReadyToRun reader, cDAC, golden fixtures, and format documentation together. The runtime uses one GCInfo format. cDAC and R2RDump retain older non-Wasm decoding; all legacy Wasm decoding paths and fixtures are removed.
The original extraction came from commits
d65c910ebcband8fd135cd964. This PR does not include two-phase compilation, direct calls, managed frame-identity changes, runtime-function byte planes, or eager reconstruction allocation. The separate byte-plane opportunity remains #135796.cDAC GCInfo decoding and SOS interface
Complete the previously declared
ISOSDacInterface18implementation in cDAC: expose it through COM and implementGetGCInfoHeader,GetGCInfoInterruptibleRanges,GetGCInfoSafePoints, andGetGCInfoSlotLifetimesusing the existing contracts. Select the interpreter decoder for interpreted methods and the platform decoder otherwise. Preserve the two-call sized-buffer protocol, initialize valid outputs on failure, and return explicit HRESULTs for invalid inputs and contract errors. This allows SOS's existing Interface18 path to use managed decoding when the updated cDAC is selected.The bridge normalizes internal decoder stack-base values to the existing, version-independent API meaning:
0=SP,1=SOSGCInfoHeader.StackBaseRegister, ignored for register slots. This matches the existing SOS formatter across supported platforms and GCInfo versions; no diagnostics-side change is needed. Unsupported internal stack-base values return an error rather than being exposed or silently interpreted as SP. Document these stable values in both the native IDL and managed interface declaration.Standalone format compatibility
This draft uses ReadyToRun 34.0 / GCInfo version 6, with synchronized CoreCLR, compiler, and NativeAOT format constants. The CoreCLR minimum ReadyToRun version is 34 on every architecture. Older R2R code is disabled, with IL fallback where available; runtime decoders always use GCInfo v6 rather than selecting an encoding from the image version.
cDAC continues to decode non-Wasm GCInfo v5 for older runtimes, and R2RDump retains historical non-Wasm formats and their version mapping. R2R 33.0/33.1 maps to GCInfo v5; R2R 34.0 and later maps to v6. Wasm has only the current GC/unwind encoding; the managed reader rejects Wasm images older than R2R 34 before caching or decoding their headers.
The latest merge incorporates upstream main
1f07b2634a8, which uses R2R 33.1 and GCInfo v5. Its contextual GCRefMap changes (33.0) and Wasm profiling helper (33.1) are upstream changes, not additions made by this PR. Moving this PR's compact GC/unwind format to 34.0 avoids assigning different layouts to upstream's version 33.Regular/composite reader regressions cover patched versions 31, 32, 33, and 34: older Wasm images are rejected, repeated accesses cannot bypass validation, and native inspection retains older-header support. That native tooling support does not relax the runtime's new minimum.
Historical measurements and limitations
The following previously recorded, isolated retail ReadyToRun CoreLib measurements used the same IL/PGO inputs within each architecture, optimized retail code generation, and default function order. Wasm comparisons used
--parallelism:1: parallel compilation varied a small writable-data region, so all compression controls and the selected result were rebuilt serially.These measurements were captured at
b89730723e6, before the subsequent upstream merges and runtime compatibility cleanup. Image sizes and compression results have not been remeasured for the current R2R 34.0 merge.Historical Wasm: upstream baseline versus measured variant
The baseline is upstream main
6f6de27e4095e296b4aea472fbd2fb30455d01be. Compression covers the entire same uncompressed images, not an independently compressed GC region.All sizes are bytes. gzip used zlib 1.3.1 with
mtime=0and no filename; Zstd used 1.5.7 without a dictionary or checksum. GC/unwind savings are included in image savings, not additive. Native-code node size was 11,729,435 bytes in both measured images.The Brotli winner was selected from 30 full-image candidates: it saved another 530 Brotli bytes versus the untuned format. The raw-size-optimal alternative made the image 10,160 bytes smaller but Brotli 4,583 bytes larger than the selected result.
The production cross-JIT at that measurement point reproduced the selected image byte-for-byte, SHA-256
f7c1d41a1a70315bcc386ac7156b63aa61c0f53b75afc67226107a047850fd13. Recompression reproduced 3,851,964 Brotli bytes, and decoded GC metadata matched for 52,559 methods.Historical x64: original native slot encoding versus measured variant
This control isolates the original native slot encoder using the same retail cross-JIT objects and IL/PGO inputs; it is not a separate freshly rebuilt upstream-main native image.
Native-code node size was 5,820,297 bytes in both measured x64 images. The measured Arm64 image was 18,969,600 bytes, with 408,767 bytes of GC payload and a 777,512-byte GC/unwind table. Wasm-specific header omissions and tuning left those x64/Arm64 GC blobs and image sizes unchanged; decoded-metadata comparisons covered 55,245 x64 and 55,271 Arm64 methods.
No new native-runtime image comparison or throughput/startup benefit is claimed.
Validation
Post-merge validation (the full runtime/library builds preceded the cDAC-only Interface18 follow-up; cDAC was rebuilt afterward):
GcInfoDecoderTests: 1,898 passed per target, on linux/x64 Checked and browser/wasm Release.GCInfoTests,StackWalkTests,WasmUnwinderTests,ExecutionManagerTests,FunctionTableAccessTests, andIXCLRDataProcessTests: 628 passed, including R2R 33 -> GCInfo v5 and R2R 34 -> v6.CheckIomethods.git diff --check upstream/main: passed.Exact build/test commands and results
Validation remains scoped: full native/Wasm runtime suites, live browser/SOS execution, and end-to-end GC-stress execution have not been run for this final state. This remains a draft.
Note
This PR description was generated with GitHub Copilot.