[crossgen2][wasm] Shrink Code Section Relocs - #132029
Draft
adamperlin wants to merge 5 commits into
Draft
Conversation
…e section to allow relocation shrinkage
…r out of hot ResolveReloc function
…rom use of SectionWriter stream in ParseCodeBlobs
|
Azure Pipelines: Successfully started running 3 pipeline(s). 13 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
Contributor
There was a problem hiding this comment.
Pull request overview
This PR updates the CoreCLR Wasm object writer to support shrinking variable-length relocations in the Wasm code section, reducing output size by rewriting padded LEB relocations to their minimal encoded lengths and updating code-blob length prefixes accordingly.
Changes:
- Refactors relocation resolution to support a source→destination stream flow, enabling in-place rewriting for shrinkable code blobs.
- Adds code-section-specific parsing and rewriting of length-prefixed code blobs to shrink variable-length relocations and update blob sizes.
- Introduces helper APIs for stream-based ULEB128 decoding and variable-length relocation writing.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| src/coreclr/tools/Common/Compiler/ObjectWriter/WasmObjectWriter.cs | Adds code-section relocation shrinking logic and refactors relocation resolution to support rewriting into a destination stream. |
| src/coreclr/tools/Common/Compiler/ObjectWriter/Dwarf/DwarfHelper.cs | Adds a stream-based ULEB128 reader used by code-blob parsing. |
| src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs | Adds helpers to detect variable-length Wasm relocations and write minimally-sized LEB encodings. |
Suppressed comments (1)
src/coreclr/tools/Common/Compiler/ObjectWriter/WasmObjectWriter.cs:734
- Unused local
sectionStreamis created but never used; this is dead code and will trigger an unnecessary-using/unused-variable warning. Remove it (the relocation resolution already copies fromsection.StreamintowebcilStream).
MemoryStream sectionStream = new MemoryStream((int)section.Stream.Length);
Comment on lines
+1211
to
1219
| long startPos = dstStream.Position; | ||
| sectionStream.CopyTo(dstStream); | ||
| for (int i = 0; i < relocs.Count; i++) | ||
| { | ||
| sectionStream.Position = reloc.Offset + sectionStart; | ||
| sectionStream.Write(new Span<byte>(pData, Relocation.GetSize(reloc.Type))); | ||
| SymbolicRelocation reloc = relocs[i]; | ||
| ResolveReloc(sectionIndex, dstStream, srcPos: sectionStart + reloc.Offset, dstStream, destPos: sectionStart + reloc.Offset, reloc, relocScratchBuffer); | ||
| } | ||
| dstStream.Position = sectionStream.Length + startPos; | ||
| } |
Comment on lines
+126
to
+149
| public static ulong? ReadULEB128(Stream source, out int bytesRead) | ||
| { | ||
| ulong value = 0; | ||
| byte @byte; | ||
| int shift = 0; | ||
| long startPos = source.Position; | ||
|
|
||
| do | ||
| { | ||
| int b = source.ReadByte(); | ||
| if (b < 0) | ||
| { | ||
| bytesRead = (int)(source.Position - startPos); | ||
| return null; | ||
| } | ||
|
|
||
| @byte = (byte)b; | ||
| value |= ((ulong)@byte & 0x7f) << shift; | ||
| shift += 7; | ||
| } while ((@byte & 0x80) != 0); | ||
|
|
||
| bytesRead = (int)(source.Position - startPos); | ||
| return value; | ||
| } |
| src.GetBuffer().AsSpan((int)srcPos, (int)count).CopyTo(dest.GetBuffer().AsSpan((int)destPos, (int)count)); | ||
| } | ||
|
|
||
| private record CodeBlob(long Size, long Start, long End); |
Comment on lines
4
to
8
| using System; | ||
| using System.Diagnostics; | ||
| using System.Runtime.Serialization; | ||
| using ILCompiler.ObjectWriter; | ||
|
|
Comment on lines
4
to
9
| using System; | ||
| using System.Buffers.Binary; | ||
| using System.Collections; | ||
| using System.Collections.Generic; | ||
| using System.Diagnostics; | ||
| using System.IO; |
This was referenced Aug 8, 2026
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.
This PR implements a relocation shrinking optimization in the WasmObjectWriter. All relocations in Wasm code emitted by the JIT are currently padded to the max 32-bit ULEB length of 5 bytes, but their resolved values may be much shorter. This PR keeps behavior the same for non-code sections which don't have variable length relocs, while implementing a shrinking procedure to re-write each relocation in the code section to its minimal length. The LEB lengths of each code blob are updated accordingly after shrinkage.
This yields around
5%size savings for System.Private.CoreLib.