[Wasm RyuJit] add length prefix to each jit code contribution - #127773

Merged
AndyAyersMS merged 1 commit into
dotnet:mainfrom
AndyAyersMS:JitEmitsCodeSizeInStreamForWasm
May 5, 2026
Merged

[Wasm RyuJit] add length prefix to each jit code contribution#127773
AndyAyersMS merged 1 commit into
dotnet:mainfrom
AndyAyersMS:JitEmitsCodeSizeInStreamForWasm

Conversation

@AndyAyersMS

Copy link
Copy Markdown
Member

And no longer do this on the host side. This will let the host split out funclets without having to parse the JIT-generated code.

And no longer do this on the host side. This will let the host split
out funclets without having to parse the JIT-generated code.
CopilotAI review requested due to automatic review settings May 4, 2026 21:19
@github-actionsgithub-actionsBot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label May 4, 2026
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

@adamperlin PTAL
fyi @dotnet/jit-contrib

Note we currently emit a maximal-length value. We could shrink this down as the JIT supports instructions that get smaller once the lengths of other instructions are known, but it is a bit clumsy as it is the first value in the encoded stream and so forces everything else to shift. It would be easier perhaps for the host to do this.

CopilotAI 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.

Pull request overview

This PR updates the Wasm RyuJIT emission pipeline so each JIT-produced function/funclet contribution includes its own length prefix, shifting the responsibility away from host-side prefixing/parsing and enabling simpler host splitting of funclets.

Changes:

  • Emit a new Wasm pseudo-instruction (INS_code_size) at the start of each method/funclet body to write a fixed-size (5-byte) length prefix.
  • Move funclet start/end location computation earlier (into genEmitMachineCode) and stop doing it in unwindEmit.
  • Update WasmObjectWriter to stop auto-length-prefixing the Wasm code section, while explicitly prefixing manually injected stubs.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
FileDescription
src/coreclr/tools/Common/Compiler/ObjectWriter/WasmObjectWriter.csStops section-writer auto prefixing for code section and explicitly writes length prefixes for inserted stubs.
src/coreclr/jit/unwindwasm.cppRemoves emitUpdateFuncletLocations() call from unwindEmit now that locations are computed earlier.
src/coreclr/jit/instrswasm.hAdds code_size instruction definition (format IF_CODE_SIZE).
src/coreclr/jit/emitwasm.hDeclares emitOutputULEB128Padded for emitting fixed-size prefixes.
src/coreclr/jit/emitwasm.cppImplements padded ULEB emission and adds encoding/printing support for IF_CODE_SIZE.
src/coreclr/jit/emitfmtswasm.hIntroduces CODE_SIZE instruction format.
src/coreclr/jit/codegenwasm.cppEmits INS_code_size at the start of root and funclet prologs.
src/coreclr/jit/codegencommon.cppComputes funclet locations earlier for Wasm so sizes/offsets are available during emission.

Comment threadsrc/coreclr/jit/codegencommon.cpp
kg
kg approved these changes May 5, 2026
@am11am11 added the arch-wasm WebAssembly architecture label May 5, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara
See info in area-owners.md if you want to be subscribed.

@adamperlinadamperlin 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.

This looks good to me. We'll also need to add a length prefix to each code blob created by the WasmEmitter in crossgen, but we can do that as a follow up!

@adamperlin

adamperlin commented May 5, 2026

Copy link
Copy Markdown
Contributor

Note we currently emit a maximal-length value. We could shrink this down as the JIT supports instructions that get smaller once the lengths of other instructions are known, but it is a bit clumsy as it is the first value in the encoded stream and so forces everything else to shift. It would be easier perhaps for the host to do this.

I think we can potentially have the host do this. We already need to implement padded relocation shrinkage and some other size optimizations on the host side, so this could be part of that work.

@AndyAyersMS
AndyAyersMS removed the request for review from MichalStrehovskyMay 5, 2026 19:46
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

/ba-g infrastructure issues

@AndyAyersMS
AndyAyersMS merged commit 0f84a10 into dotnet:mainMay 5, 2026
138 of 144 checks passed
adamperlin added a commit that referenced this pull request May 11, 2026
#127773 adds length prefixes directly to emitted Wasm code in the JIT.
This change is a follow up which adds length prefixes directly to
generated wasm import thunks and stubs in crossgen. It also removes the
logic in the Object Writer around handling length prefixes, since these
will now be encoded in the `ObjectData` itself.
@AndyAyersMSAndyAyersMS mentioned this pull request May 14, 2026
12 tasks
adamperlin added a commit that referenced this pull request Jun 2, 2026
> [!NOTE]
> This PR was created with assistance from Github Copilot
This PR adds handling to the Wasm Object Writer to extract funclets
attached to a compiled method as separate Wasm functions.
To do this, an `INodeWithFunclets` interface was added for ReadyToRun
and NativeAOT so that we can generically access EHInfo and FrameInfo
fields attached to nodes which represent managed method definitions.
We lay funclets out sequentially in the object file and they are added
to the Wasm table contiguously. This is required by #128222 and lets us
grab the funclet index using an offset from the index of the method it
is attached to, i.e., funclet `i` for method M is at `table_index(M) +
i`.
Follow up on #127773 and other Wasm EH work.
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jun 5, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-CodeGen-coreclrCLR 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.

5 participants

@AndyAyersMS@adamperlin@kg@am11
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

[Wasm RyuJit] add length prefix to each jit code contribution - #127773

Merged
AndyAyersMS merged 1 commit into
dotnet:mainfrom
AndyAyersMS:JitEmitsCodeSizeInStreamForWasm
May 5, 2026
Merged

[Wasm RyuJit] add length prefix to each jit code contribution#127773
AndyAyersMS merged 1 commit into
dotnet:mainfrom
AndyAyersMS:JitEmitsCodeSizeInStreamForWasm

Conversation

@AndyAyersMS

Copy link
Copy Markdown
Member

And no longer do this on the host side. This will let the host split out funclets without having to parse the JIT-generated code.

And no longer do this on the host side. This will let the host split
out funclets without having to parse the JIT-generated code.
CopilotAI review requested due to automatic review settings May 4, 2026 21:19
@github-actionsgithub-actionsBot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label May 4, 2026
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

@adamperlin PTAL
fyi @dotnet/jit-contrib

Note we currently emit a maximal-length value. We could shrink this down as the JIT supports instructions that get smaller once the lengths of other instructions are known, but it is a bit clumsy as it is the first value in the encoded stream and so forces everything else to shift. It would be easier perhaps for the host to do this.

CopilotAI 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.

Pull request overview

This PR updates the Wasm RyuJIT emission pipeline so each JIT-produced function/funclet contribution includes its own length prefix, shifting the responsibility away from host-side prefixing/parsing and enabling simpler host splitting of funclets.

Changes:

  • Emit a new Wasm pseudo-instruction (INS_code_size) at the start of each method/funclet body to write a fixed-size (5-byte) length prefix.
  • Move funclet start/end location computation earlier (into genEmitMachineCode) and stop doing it in unwindEmit.
  • Update WasmObjectWriter to stop auto-length-prefixing the Wasm code section, while explicitly prefixing manually injected stubs.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
FileDescription
src/coreclr/tools/Common/Compiler/ObjectWriter/WasmObjectWriter.csStops section-writer auto prefixing for code section and explicitly writes length prefixes for inserted stubs.
src/coreclr/jit/unwindwasm.cppRemoves emitUpdateFuncletLocations() call from unwindEmit now that locations are computed earlier.
src/coreclr/jit/instrswasm.hAdds code_size instruction definition (format IF_CODE_SIZE).
src/coreclr/jit/emitwasm.hDeclares emitOutputULEB128Padded for emitting fixed-size prefixes.
src/coreclr/jit/emitwasm.cppImplements padded ULEB emission and adds encoding/printing support for IF_CODE_SIZE.
src/coreclr/jit/emitfmtswasm.hIntroduces CODE_SIZE instruction format.
src/coreclr/jit/codegenwasm.cppEmits INS_code_size at the start of root and funclet prologs.
src/coreclr/jit/codegencommon.cppComputes funclet locations earlier for Wasm so sizes/offsets are available during emission.

Comment threadsrc/coreclr/jit/codegencommon.cpp
kg
kg approved these changes May 5, 2026
@am11am11 added the arch-wasm WebAssembly architecture label May 5, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara
See info in area-owners.md if you want to be subscribed.

@adamperlinadamperlin 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.

This looks good to me. We'll also need to add a length prefix to each code blob created by the WasmEmitter in crossgen, but we can do that as a follow up!

@adamperlin

adamperlin commented May 5, 2026

Copy link
Copy Markdown
Contributor

Note we currently emit a maximal-length value. We could shrink this down as the JIT supports instructions that get smaller once the lengths of other instructions are known, but it is a bit clumsy as it is the first value in the encoded stream and so forces everything else to shift. It would be easier perhaps for the host to do this.

I think we can potentially have the host do this. We already need to implement padded relocation shrinkage and some other size optimizations on the host side, so this could be part of that work.

@AndyAyersMS
AndyAyersMS removed the request for review from MichalStrehovskyMay 5, 2026 19:46
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

/ba-g infrastructure issues

@AndyAyersMS
AndyAyersMS merged commit 0f84a10 into dotnet:mainMay 5, 2026
138 of 144 checks passed
adamperlin added a commit that referenced this pull request May 11, 2026
#127773 adds length prefixes directly to emitted Wasm code in the JIT.
This change is a follow up which adds length prefixes directly to
generated wasm import thunks and stubs in crossgen. It also removes the
logic in the Object Writer around handling length prefixes, since these
will now be encoded in the `ObjectData` itself.
@AndyAyersMSAndyAyersMS mentioned this pull request May 14, 2026
12 tasks
adamperlin added a commit that referenced this pull request Jun 2, 2026
> [!NOTE]
> This PR was created with assistance from Github Copilot
This PR adds handling to the Wasm Object Writer to extract funclets
attached to a compiled method as separate Wasm functions.
To do this, an `INodeWithFunclets` interface was added for ReadyToRun
and NativeAOT so that we can generically access EHInfo and FrameInfo
fields attached to nodes which represent managed method definitions.
We lay funclets out sequentially in the object file and they are added
to the Wasm table contiguously. This is required by #128222 and lets us
grab the funclet index using an offset from the index of the method it
is attached to, i.e., funclet `i` for method M is at `table_index(M) +
i`.
Follow up on #127773 and other Wasm EH work.
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jun 5, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-CodeGen-coreclrCLR 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.

5 participants

@AndyAyersMS@adamperlin@kg@am11
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

[Wasm RyuJit] add length prefix to each jit code contribution - #127773

Merged
AndyAyersMS merged 1 commit into
dotnet:mainfrom
AndyAyersMS:JitEmitsCodeSizeInStreamForWasm
May 5, 2026
Merged

[Wasm RyuJit] add length prefix to each jit code contribution#127773
AndyAyersMS merged 1 commit into
dotnet:mainfrom
AndyAyersMS:JitEmitsCodeSizeInStreamForWasm

Conversation

@AndyAyersMS

Copy link
Copy Markdown
Member

And no longer do this on the host side. This will let the host split out funclets without having to parse the JIT-generated code.

And no longer do this on the host side. This will let the host split
out funclets without having to parse the JIT-generated code.
CopilotAI review requested due to automatic review settings May 4, 2026 21:19
@github-actionsgithub-actionsBot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label May 4, 2026
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

@adamperlin PTAL
fyi @dotnet/jit-contrib

Note we currently emit a maximal-length value. We could shrink this down as the JIT supports instructions that get smaller once the lengths of other instructions are known, but it is a bit clumsy as it is the first value in the encoded stream and so forces everything else to shift. It would be easier perhaps for the host to do this.

CopilotAI 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.

Pull request overview

This PR updates the Wasm RyuJIT emission pipeline so each JIT-produced function/funclet contribution includes its own length prefix, shifting the responsibility away from host-side prefixing/parsing and enabling simpler host splitting of funclets.

Changes:

  • Emit a new Wasm pseudo-instruction (INS_code_size) at the start of each method/funclet body to write a fixed-size (5-byte) length prefix.
  • Move funclet start/end location computation earlier (into genEmitMachineCode) and stop doing it in unwindEmit.
  • Update WasmObjectWriter to stop auto-length-prefixing the Wasm code section, while explicitly prefixing manually injected stubs.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
FileDescription
src/coreclr/tools/Common/Compiler/ObjectWriter/WasmObjectWriter.csStops section-writer auto prefixing for code section and explicitly writes length prefixes for inserted stubs.
src/coreclr/jit/unwindwasm.cppRemoves emitUpdateFuncletLocations() call from unwindEmit now that locations are computed earlier.
src/coreclr/jit/instrswasm.hAdds code_size instruction definition (format IF_CODE_SIZE).
src/coreclr/jit/emitwasm.hDeclares emitOutputULEB128Padded for emitting fixed-size prefixes.
src/coreclr/jit/emitwasm.cppImplements padded ULEB emission and adds encoding/printing support for IF_CODE_SIZE.
src/coreclr/jit/emitfmtswasm.hIntroduces CODE_SIZE instruction format.
src/coreclr/jit/codegenwasm.cppEmits INS_code_size at the start of root and funclet prologs.
src/coreclr/jit/codegencommon.cppComputes funclet locations earlier for Wasm so sizes/offsets are available during emission.

Comment threadsrc/coreclr/jit/codegencommon.cpp
kg
kg approved these changes May 5, 2026
@am11am11 added the arch-wasm WebAssembly architecture label May 5, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara
See info in area-owners.md if you want to be subscribed.

@adamperlinadamperlin 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.

This looks good to me. We'll also need to add a length prefix to each code blob created by the WasmEmitter in crossgen, but we can do that as a follow up!

@adamperlin

adamperlin commented May 5, 2026

Copy link
Copy Markdown
Contributor

Note we currently emit a maximal-length value. We could shrink this down as the JIT supports instructions that get smaller once the lengths of other instructions are known, but it is a bit clumsy as it is the first value in the encoded stream and so forces everything else to shift. It would be easier perhaps for the host to do this.

I think we can potentially have the host do this. We already need to implement padded relocation shrinkage and some other size optimizations on the host side, so this could be part of that work.

@AndyAyersMS
AndyAyersMS removed the request for review from MichalStrehovskyMay 5, 2026 19:46
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

/ba-g infrastructure issues

@AndyAyersMS
AndyAyersMS merged commit 0f84a10 into dotnet:mainMay 5, 2026
138 of 144 checks passed
adamperlin added a commit that referenced this pull request May 11, 2026
#127773 adds length prefixes directly to emitted Wasm code in the JIT.
This change is a follow up which adds length prefixes directly to
generated wasm import thunks and stubs in crossgen. It also removes the
logic in the Object Writer around handling length prefixes, since these
will now be encoded in the `ObjectData` itself.
@AndyAyersMSAndyAyersMS mentioned this pull request May 14, 2026
12 tasks
adamperlin added a commit that referenced this pull request Jun 2, 2026
> [!NOTE]
> This PR was created with assistance from Github Copilot
This PR adds handling to the Wasm Object Writer to extract funclets
attached to a compiled method as separate Wasm functions.
To do this, an `INodeWithFunclets` interface was added for ReadyToRun
and NativeAOT so that we can generically access EHInfo and FrameInfo
fields attached to nodes which represent managed method definitions.
We lay funclets out sequentially in the object file and they are added
to the Wasm table contiguously. This is required by #128222 and lets us
grab the funclet index using an offset from the index of the method it
is attached to, i.e., funclet `i` for method M is at `table_index(M) +
i`.
Follow up on #127773 and other Wasm EH work.
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jun 5, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-CodeGen-coreclrCLR 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.

5 participants

@AndyAyersMS@adamperlin@kg@am11
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

[Wasm RyuJit] add length prefix to each jit code contribution - #127773

Merged
AndyAyersMS merged 1 commit into
dotnet:mainfrom
AndyAyersMS:JitEmitsCodeSizeInStreamForWasm
May 5, 2026
Merged

[Wasm RyuJit] add length prefix to each jit code contribution#127773
AndyAyersMS merged 1 commit into
dotnet:mainfrom
AndyAyersMS:JitEmitsCodeSizeInStreamForWasm

Conversation

@AndyAyersMS

Copy link
Copy Markdown
Member

And no longer do this on the host side. This will let the host split out funclets without having to parse the JIT-generated code.

And no longer do this on the host side. This will let the host split
out funclets without having to parse the JIT-generated code.
CopilotAI review requested due to automatic review settings May 4, 2026 21:19
@github-actionsgithub-actionsBot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label May 4, 2026
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

@adamperlin PTAL
fyi @dotnet/jit-contrib

Note we currently emit a maximal-length value. We could shrink this down as the JIT supports instructions that get smaller once the lengths of other instructions are known, but it is a bit clumsy as it is the first value in the encoded stream and so forces everything else to shift. It would be easier perhaps for the host to do this.

CopilotAI 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.

Pull request overview

This PR updates the Wasm RyuJIT emission pipeline so each JIT-produced function/funclet contribution includes its own length prefix, shifting the responsibility away from host-side prefixing/parsing and enabling simpler host splitting of funclets.

Changes:

  • Emit a new Wasm pseudo-instruction (INS_code_size) at the start of each method/funclet body to write a fixed-size (5-byte) length prefix.
  • Move funclet start/end location computation earlier (into genEmitMachineCode) and stop doing it in unwindEmit.
  • Update WasmObjectWriter to stop auto-length-prefixing the Wasm code section, while explicitly prefixing manually injected stubs.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
FileDescription
src/coreclr/tools/Common/Compiler/ObjectWriter/WasmObjectWriter.csStops section-writer auto prefixing for code section and explicitly writes length prefixes for inserted stubs.
src/coreclr/jit/unwindwasm.cppRemoves emitUpdateFuncletLocations() call from unwindEmit now that locations are computed earlier.
src/coreclr/jit/instrswasm.hAdds code_size instruction definition (format IF_CODE_SIZE).
src/coreclr/jit/emitwasm.hDeclares emitOutputULEB128Padded for emitting fixed-size prefixes.
src/coreclr/jit/emitwasm.cppImplements padded ULEB emission and adds encoding/printing support for IF_CODE_SIZE.
src/coreclr/jit/emitfmtswasm.hIntroduces CODE_SIZE instruction format.
src/coreclr/jit/codegenwasm.cppEmits INS_code_size at the start of root and funclet prologs.
src/coreclr/jit/codegencommon.cppComputes funclet locations earlier for Wasm so sizes/offsets are available during emission.

Comment threadsrc/coreclr/jit/codegencommon.cpp
kg
kg approved these changes May 5, 2026
@am11am11 added the arch-wasm WebAssembly architecture label May 5, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara
See info in area-owners.md if you want to be subscribed.

@adamperlinadamperlin 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.

This looks good to me. We'll also need to add a length prefix to each code blob created by the WasmEmitter in crossgen, but we can do that as a follow up!

@adamperlin

adamperlin commented May 5, 2026

Copy link
Copy Markdown
Contributor

Note we currently emit a maximal-length value. We could shrink this down as the JIT supports instructions that get smaller once the lengths of other instructions are known, but it is a bit clumsy as it is the first value in the encoded stream and so forces everything else to shift. It would be easier perhaps for the host to do this.

I think we can potentially have the host do this. We already need to implement padded relocation shrinkage and some other size optimizations on the host side, so this could be part of that work.

@AndyAyersMS
AndyAyersMS removed the request for review from MichalStrehovskyMay 5, 2026 19:46
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

/ba-g infrastructure issues

@AndyAyersMS
AndyAyersMS merged commit 0f84a10 into dotnet:mainMay 5, 2026
138 of 144 checks passed
adamperlin added a commit that referenced this pull request May 11, 2026
#127773 adds length prefixes directly to emitted Wasm code in the JIT.
This change is a follow up which adds length prefixes directly to
generated wasm import thunks and stubs in crossgen. It also removes the
logic in the Object Writer around handling length prefixes, since these
will now be encoded in the `ObjectData` itself.
@AndyAyersMSAndyAyersMS mentioned this pull request May 14, 2026
12 tasks
adamperlin added a commit that referenced this pull request Jun 2, 2026
> [!NOTE]
> This PR was created with assistance from Github Copilot
This PR adds handling to the Wasm Object Writer to extract funclets
attached to a compiled method as separate Wasm functions.
To do this, an `INodeWithFunclets` interface was added for ReadyToRun
and NativeAOT so that we can generically access EHInfo and FrameInfo
fields attached to nodes which represent managed method definitions.
We lay funclets out sequentially in the object file and they are added
to the Wasm table contiguously. This is required by #128222 and lets us
grab the funclet index using an offset from the index of the method it
is attached to, i.e., funclet `i` for method M is at `table_index(M) +
i`.
Follow up on #127773 and other Wasm EH work.
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jun 5, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-CodeGen-coreclrCLR 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.

5 participants

@AndyAyersMS@adamperlin@kg@am11
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

[Wasm RyuJit] add length prefix to each jit code contribution - #127773

Merged
AndyAyersMS merged 1 commit into
dotnet:mainfrom
AndyAyersMS:JitEmitsCodeSizeInStreamForWasm
May 5, 2026
Merged

[Wasm RyuJit] add length prefix to each jit code contribution#127773
AndyAyersMS merged 1 commit into
dotnet:mainfrom
AndyAyersMS:JitEmitsCodeSizeInStreamForWasm

Conversation

@AndyAyersMS

Copy link
Copy Markdown
Member

And no longer do this on the host side. This will let the host split out funclets without having to parse the JIT-generated code.

And no longer do this on the host side. This will let the host split
out funclets without having to parse the JIT-generated code.
CopilotAI review requested due to automatic review settings May 4, 2026 21:19
@github-actionsgithub-actionsBot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label May 4, 2026
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

@adamperlin PTAL
fyi @dotnet/jit-contrib

Note we currently emit a maximal-length value. We could shrink this down as the JIT supports instructions that get smaller once the lengths of other instructions are known, but it is a bit clumsy as it is the first value in the encoded stream and so forces everything else to shift. It would be easier perhaps for the host to do this.

CopilotAI 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.

Pull request overview

This PR updates the Wasm RyuJIT emission pipeline so each JIT-produced function/funclet contribution includes its own length prefix, shifting the responsibility away from host-side prefixing/parsing and enabling simpler host splitting of funclets.

Changes:

  • Emit a new Wasm pseudo-instruction (INS_code_size) at the start of each method/funclet body to write a fixed-size (5-byte) length prefix.
  • Move funclet start/end location computation earlier (into genEmitMachineCode) and stop doing it in unwindEmit.
  • Update WasmObjectWriter to stop auto-length-prefixing the Wasm code section, while explicitly prefixing manually injected stubs.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
FileDescription
src/coreclr/tools/Common/Compiler/ObjectWriter/WasmObjectWriter.csStops section-writer auto prefixing for code section and explicitly writes length prefixes for inserted stubs.
src/coreclr/jit/unwindwasm.cppRemoves emitUpdateFuncletLocations() call from unwindEmit now that locations are computed earlier.
src/coreclr/jit/instrswasm.hAdds code_size instruction definition (format IF_CODE_SIZE).
src/coreclr/jit/emitwasm.hDeclares emitOutputULEB128Padded for emitting fixed-size prefixes.
src/coreclr/jit/emitwasm.cppImplements padded ULEB emission and adds encoding/printing support for IF_CODE_SIZE.
src/coreclr/jit/emitfmtswasm.hIntroduces CODE_SIZE instruction format.
src/coreclr/jit/codegenwasm.cppEmits INS_code_size at the start of root and funclet prologs.
src/coreclr/jit/codegencommon.cppComputes funclet locations earlier for Wasm so sizes/offsets are available during emission.

Comment threadsrc/coreclr/jit/codegencommon.cpp
kg
kg approved these changes May 5, 2026
@am11am11 added the arch-wasm WebAssembly architecture label May 5, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara
See info in area-owners.md if you want to be subscribed.

@adamperlinadamperlin 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.

This looks good to me. We'll also need to add a length prefix to each code blob created by the WasmEmitter in crossgen, but we can do that as a follow up!

@adamperlin

adamperlin commented May 5, 2026

Copy link
Copy Markdown
Contributor

Note we currently emit a maximal-length value. We could shrink this down as the JIT supports instructions that get smaller once the lengths of other instructions are known, but it is a bit clumsy as it is the first value in the encoded stream and so forces everything else to shift. It would be easier perhaps for the host to do this.

I think we can potentially have the host do this. We already need to implement padded relocation shrinkage and some other size optimizations on the host side, so this could be part of that work.

@AndyAyersMS
AndyAyersMS removed the request for review from MichalStrehovskyMay 5, 2026 19:46
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

/ba-g infrastructure issues

@AndyAyersMS
AndyAyersMS merged commit 0f84a10 into dotnet:mainMay 5, 2026
138 of 144 checks passed
adamperlin added a commit that referenced this pull request May 11, 2026
#127773 adds length prefixes directly to emitted Wasm code in the JIT.
This change is a follow up which adds length prefixes directly to
generated wasm import thunks and stubs in crossgen. It also removes the
logic in the Object Writer around handling length prefixes, since these
will now be encoded in the `ObjectData` itself.
@AndyAyersMSAndyAyersMS mentioned this pull request May 14, 2026
12 tasks
adamperlin added a commit that referenced this pull request Jun 2, 2026
> [!NOTE]
> This PR was created with assistance from Github Copilot
This PR adds handling to the Wasm Object Writer to extract funclets
attached to a compiled method as separate Wasm functions.
To do this, an `INodeWithFunclets` interface was added for ReadyToRun
and NativeAOT so that we can generically access EHInfo and FrameInfo
fields attached to nodes which represent managed method definitions.
We lay funclets out sequentially in the object file and they are added
to the Wasm table contiguously. This is required by #128222 and lets us
grab the funclet index using an offset from the index of the method it
is attached to, i.e., funclet `i` for method M is at `table_index(M) +
i`.
Follow up on #127773 and other Wasm EH work.
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jun 5, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-CodeGen-coreclrCLR 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.

5 participants

@AndyAyersMS@adamperlin@kg@am11
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

[Wasm RyuJit] add length prefix to each jit code contribution - #127773

Merged
AndyAyersMS merged 1 commit into
dotnet:mainfrom
AndyAyersMS:JitEmitsCodeSizeInStreamForWasm
May 5, 2026
Merged

[Wasm RyuJit] add length prefix to each jit code contribution#127773
AndyAyersMS merged 1 commit into
dotnet:mainfrom
AndyAyersMS:JitEmitsCodeSizeInStreamForWasm

Conversation

@AndyAyersMS

Copy link
Copy Markdown
Member

And no longer do this on the host side. This will let the host split out funclets without having to parse the JIT-generated code.

And no longer do this on the host side. This will let the host split
out funclets without having to parse the JIT-generated code.
CopilotAI review requested due to automatic review settings May 4, 2026 21:19
@github-actionsgithub-actionsBot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label May 4, 2026
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

@adamperlin PTAL
fyi @dotnet/jit-contrib

Note we currently emit a maximal-length value. We could shrink this down as the JIT supports instructions that get smaller once the lengths of other instructions are known, but it is a bit clumsy as it is the first value in the encoded stream and so forces everything else to shift. It would be easier perhaps for the host to do this.

CopilotAI 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.

Pull request overview

This PR updates the Wasm RyuJIT emission pipeline so each JIT-produced function/funclet contribution includes its own length prefix, shifting the responsibility away from host-side prefixing/parsing and enabling simpler host splitting of funclets.

Changes:

  • Emit a new Wasm pseudo-instruction (INS_code_size) at the start of each method/funclet body to write a fixed-size (5-byte) length prefix.
  • Move funclet start/end location computation earlier (into genEmitMachineCode) and stop doing it in unwindEmit.
  • Update WasmObjectWriter to stop auto-length-prefixing the Wasm code section, while explicitly prefixing manually injected stubs.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
FileDescription
src/coreclr/tools/Common/Compiler/ObjectWriter/WasmObjectWriter.csStops section-writer auto prefixing for code section and explicitly writes length prefixes for inserted stubs.
src/coreclr/jit/unwindwasm.cppRemoves emitUpdateFuncletLocations() call from unwindEmit now that locations are computed earlier.
src/coreclr/jit/instrswasm.hAdds code_size instruction definition (format IF_CODE_SIZE).
src/coreclr/jit/emitwasm.hDeclares emitOutputULEB128Padded for emitting fixed-size prefixes.
src/coreclr/jit/emitwasm.cppImplements padded ULEB emission and adds encoding/printing support for IF_CODE_SIZE.
src/coreclr/jit/emitfmtswasm.hIntroduces CODE_SIZE instruction format.
src/coreclr/jit/codegenwasm.cppEmits INS_code_size at the start of root and funclet prologs.
src/coreclr/jit/codegencommon.cppComputes funclet locations earlier for Wasm so sizes/offsets are available during emission.

Comment threadsrc/coreclr/jit/codegencommon.cpp
kg
kg approved these changes May 5, 2026
@am11am11 added the arch-wasm WebAssembly architecture label May 5, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara
See info in area-owners.md if you want to be subscribed.

@adamperlinadamperlin 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.

This looks good to me. We'll also need to add a length prefix to each code blob created by the WasmEmitter in crossgen, but we can do that as a follow up!

@adamperlin

adamperlin commented May 5, 2026

Copy link
Copy Markdown
Contributor

Note we currently emit a maximal-length value. We could shrink this down as the JIT supports instructions that get smaller once the lengths of other instructions are known, but it is a bit clumsy as it is the first value in the encoded stream and so forces everything else to shift. It would be easier perhaps for the host to do this.

I think we can potentially have the host do this. We already need to implement padded relocation shrinkage and some other size optimizations on the host side, so this could be part of that work.

@AndyAyersMS
AndyAyersMS removed the request for review from MichalStrehovskyMay 5, 2026 19:46
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

/ba-g infrastructure issues

@AndyAyersMS
AndyAyersMS merged commit 0f84a10 into dotnet:mainMay 5, 2026
138 of 144 checks passed
adamperlin added a commit that referenced this pull request May 11, 2026
#127773 adds length prefixes directly to emitted Wasm code in the JIT.
This change is a follow up which adds length prefixes directly to
generated wasm import thunks and stubs in crossgen. It also removes the
logic in the Object Writer around handling length prefixes, since these
will now be encoded in the `ObjectData` itself.
@AndyAyersMSAndyAyersMS mentioned this pull request May 14, 2026
12 tasks
adamperlin added a commit that referenced this pull request Jun 2, 2026
> [!NOTE]
> This PR was created with assistance from Github Copilot
This PR adds handling to the Wasm Object Writer to extract funclets
attached to a compiled method as separate Wasm functions.
To do this, an `INodeWithFunclets` interface was added for ReadyToRun
and NativeAOT so that we can generically access EHInfo and FrameInfo
fields attached to nodes which represent managed method definitions.
We lay funclets out sequentially in the object file and they are added
to the Wasm table contiguously. This is required by #128222 and lets us
grab the funclet index using an offset from the index of the method it
is attached to, i.e., funclet `i` for method M is at `table_index(M) +
i`.
Follow up on #127773 and other Wasm EH work.
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jun 5, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-CodeGen-coreclrCLR 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.

5 participants

@AndyAyersMS@adamperlin@kg@am11
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

[Wasm RyuJit] add length prefix to each jit code contribution - #127773

Merged
AndyAyersMS merged 1 commit into
dotnet:mainfrom
AndyAyersMS:JitEmitsCodeSizeInStreamForWasm
May 5, 2026
Merged

[Wasm RyuJit] add length prefix to each jit code contribution#127773
AndyAyersMS merged 1 commit into
dotnet:mainfrom
AndyAyersMS:JitEmitsCodeSizeInStreamForWasm

Conversation

@AndyAyersMS

Copy link
Copy Markdown
Member

And no longer do this on the host side. This will let the host split out funclets without having to parse the JIT-generated code.

And no longer do this on the host side. This will let the host split
out funclets without having to parse the JIT-generated code.
CopilotAI review requested due to automatic review settings May 4, 2026 21:19
@github-actionsgithub-actionsBot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label May 4, 2026
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

@adamperlin PTAL
fyi @dotnet/jit-contrib

Note we currently emit a maximal-length value. We could shrink this down as the JIT supports instructions that get smaller once the lengths of other instructions are known, but it is a bit clumsy as it is the first value in the encoded stream and so forces everything else to shift. It would be easier perhaps for the host to do this.

CopilotAI 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.

Pull request overview

This PR updates the Wasm RyuJIT emission pipeline so each JIT-produced function/funclet contribution includes its own length prefix, shifting the responsibility away from host-side prefixing/parsing and enabling simpler host splitting of funclets.

Changes:

  • Emit a new Wasm pseudo-instruction (INS_code_size) at the start of each method/funclet body to write a fixed-size (5-byte) length prefix.
  • Move funclet start/end location computation earlier (into genEmitMachineCode) and stop doing it in unwindEmit.
  • Update WasmObjectWriter to stop auto-length-prefixing the Wasm code section, while explicitly prefixing manually injected stubs.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
FileDescription
src/coreclr/tools/Common/Compiler/ObjectWriter/WasmObjectWriter.csStops section-writer auto prefixing for code section and explicitly writes length prefixes for inserted stubs.
src/coreclr/jit/unwindwasm.cppRemoves emitUpdateFuncletLocations() call from unwindEmit now that locations are computed earlier.
src/coreclr/jit/instrswasm.hAdds code_size instruction definition (format IF_CODE_SIZE).
src/coreclr/jit/emitwasm.hDeclares emitOutputULEB128Padded for emitting fixed-size prefixes.
src/coreclr/jit/emitwasm.cppImplements padded ULEB emission and adds encoding/printing support for IF_CODE_SIZE.
src/coreclr/jit/emitfmtswasm.hIntroduces CODE_SIZE instruction format.
src/coreclr/jit/codegenwasm.cppEmits INS_code_size at the start of root and funclet prologs.
src/coreclr/jit/codegencommon.cppComputes funclet locations earlier for Wasm so sizes/offsets are available during emission.

Comment threadsrc/coreclr/jit/codegencommon.cpp
kg
kg approved these changes May 5, 2026
@am11am11 added the arch-wasm WebAssembly architecture label May 5, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara
See info in area-owners.md if you want to be subscribed.

@adamperlinadamperlin 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.

This looks good to me. We'll also need to add a length prefix to each code blob created by the WasmEmitter in crossgen, but we can do that as a follow up!

@adamperlin

adamperlin commented May 5, 2026

Copy link
Copy Markdown
Contributor

Note we currently emit a maximal-length value. We could shrink this down as the JIT supports instructions that get smaller once the lengths of other instructions are known, but it is a bit clumsy as it is the first value in the encoded stream and so forces everything else to shift. It would be easier perhaps for the host to do this.

I think we can potentially have the host do this. We already need to implement padded relocation shrinkage and some other size optimizations on the host side, so this could be part of that work.

@AndyAyersMS
AndyAyersMS removed the request for review from MichalStrehovskyMay 5, 2026 19:46
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

/ba-g infrastructure issues

@AndyAyersMS
AndyAyersMS merged commit 0f84a10 into dotnet:mainMay 5, 2026
138 of 144 checks passed
adamperlin added a commit that referenced this pull request May 11, 2026
#127773 adds length prefixes directly to emitted Wasm code in the JIT.
This change is a follow up which adds length prefixes directly to
generated wasm import thunks and stubs in crossgen. It also removes the
logic in the Object Writer around handling length prefixes, since these
will now be encoded in the `ObjectData` itself.
@AndyAyersMSAndyAyersMS mentioned this pull request May 14, 2026
12 tasks
adamperlin added a commit that referenced this pull request Jun 2, 2026
> [!NOTE]
> This PR was created with assistance from Github Copilot
This PR adds handling to the Wasm Object Writer to extract funclets
attached to a compiled method as separate Wasm functions.
To do this, an `INodeWithFunclets` interface was added for ReadyToRun
and NativeAOT so that we can generically access EHInfo and FrameInfo
fields attached to nodes which represent managed method definitions.
We lay funclets out sequentially in the object file and they are added
to the Wasm table contiguously. This is required by #128222 and lets us
grab the funclet index using an offset from the index of the method it
is attached to, i.e., funclet `i` for method M is at `table_index(M) +
i`.
Follow up on #127773 and other Wasm EH work.
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jun 5, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-CodeGen-coreclrCLR 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.

5 participants

@AndyAyersMS@adamperlin@kg@am11
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

[Wasm RyuJit] add length prefix to each jit code contribution - #127773

Merged
AndyAyersMS merged 1 commit into
dotnet:mainfrom
AndyAyersMS:JitEmitsCodeSizeInStreamForWasm
May 5, 2026
Merged

[Wasm RyuJit] add length prefix to each jit code contribution#127773
AndyAyersMS merged 1 commit into
dotnet:mainfrom
AndyAyersMS:JitEmitsCodeSizeInStreamForWasm

Conversation

@AndyAyersMS

Copy link
Copy Markdown
Member

And no longer do this on the host side. This will let the host split out funclets without having to parse the JIT-generated code.

And no longer do this on the host side. This will let the host split
out funclets without having to parse the JIT-generated code.
CopilotAI review requested due to automatic review settings May 4, 2026 21:19
@github-actionsgithub-actionsBot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label May 4, 2026
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

@adamperlin PTAL
fyi @dotnet/jit-contrib

Note we currently emit a maximal-length value. We could shrink this down as the JIT supports instructions that get smaller once the lengths of other instructions are known, but it is a bit clumsy as it is the first value in the encoded stream and so forces everything else to shift. It would be easier perhaps for the host to do this.

CopilotAI 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.

Pull request overview

This PR updates the Wasm RyuJIT emission pipeline so each JIT-produced function/funclet contribution includes its own length prefix, shifting the responsibility away from host-side prefixing/parsing and enabling simpler host splitting of funclets.

Changes:

  • Emit a new Wasm pseudo-instruction (INS_code_size) at the start of each method/funclet body to write a fixed-size (5-byte) length prefix.
  • Move funclet start/end location computation earlier (into genEmitMachineCode) and stop doing it in unwindEmit.
  • Update WasmObjectWriter to stop auto-length-prefixing the Wasm code section, while explicitly prefixing manually injected stubs.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
FileDescription
src/coreclr/tools/Common/Compiler/ObjectWriter/WasmObjectWriter.csStops section-writer auto prefixing for code section and explicitly writes length prefixes for inserted stubs.
src/coreclr/jit/unwindwasm.cppRemoves emitUpdateFuncletLocations() call from unwindEmit now that locations are computed earlier.
src/coreclr/jit/instrswasm.hAdds code_size instruction definition (format IF_CODE_SIZE).
src/coreclr/jit/emitwasm.hDeclares emitOutputULEB128Padded for emitting fixed-size prefixes.
src/coreclr/jit/emitwasm.cppImplements padded ULEB emission and adds encoding/printing support for IF_CODE_SIZE.
src/coreclr/jit/emitfmtswasm.hIntroduces CODE_SIZE instruction format.
src/coreclr/jit/codegenwasm.cppEmits INS_code_size at the start of root and funclet prologs.
src/coreclr/jit/codegencommon.cppComputes funclet locations earlier for Wasm so sizes/offsets are available during emission.

Comment threadsrc/coreclr/jit/codegencommon.cpp
kg
kg approved these changes May 5, 2026
@am11am11 added the arch-wasm WebAssembly architecture label May 5, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara
See info in area-owners.md if you want to be subscribed.

@adamperlinadamperlin 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.

This looks good to me. We'll also need to add a length prefix to each code blob created by the WasmEmitter in crossgen, but we can do that as a follow up!

@adamperlin

adamperlin commented May 5, 2026

Copy link
Copy Markdown
Contributor

Note we currently emit a maximal-length value. We could shrink this down as the JIT supports instructions that get smaller once the lengths of other instructions are known, but it is a bit clumsy as it is the first value in the encoded stream and so forces everything else to shift. It would be easier perhaps for the host to do this.

I think we can potentially have the host do this. We already need to implement padded relocation shrinkage and some other size optimizations on the host side, so this could be part of that work.

@AndyAyersMS
AndyAyersMS removed the request for review from MichalStrehovskyMay 5, 2026 19:46
@AndyAyersMS

Copy link
Copy Markdown
MemberAuthor

/ba-g infrastructure issues

@AndyAyersMS
AndyAyersMS merged commit 0f84a10 into dotnet:mainMay 5, 2026
138 of 144 checks passed
adamperlin added a commit that referenced this pull request May 11, 2026
#127773 adds length prefixes directly to emitted Wasm code in the JIT.
This change is a follow up which adds length prefixes directly to
generated wasm import thunks and stubs in crossgen. It also removes the
logic in the Object Writer around handling length prefixes, since these
will now be encoded in the `ObjectData` itself.
@AndyAyersMSAndyAyersMS mentioned this pull request May 14, 2026
12 tasks
adamperlin added a commit that referenced this pull request Jun 2, 2026
> [!NOTE]
> This PR was created with assistance from Github Copilot
This PR adds handling to the Wasm Object Writer to extract funclets
attached to a compiled method as separate Wasm functions.
To do this, an `INodeWithFunclets` interface was added for ReadyToRun
and NativeAOT so that we can generically access EHInfo and FrameInfo
fields attached to nodes which represent managed method definitions.
We lay funclets out sequentially in the object file and they are added
to the Wasm table contiguously. This is required by #128222 and lets us
grab the funclet index using an offset from the index of the method it
is attached to, i.e., funclet `i` for method M is at `table_index(M) +
i`.
Follow up on #127773 and other Wasm EH work.
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jun 5, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-CodeGen-coreclrCLR 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.

5 participants

@AndyAyersMS@adamperlin@kg@am11