Skip to content

Reduce WebAssembly managed method prologs - #135440

Draft
davidwrighton wants to merge 3 commits into
dotnet:mainfrom
davidwrighton:MoreEfficientProlog
Draft

davidwrighton wants to merge 3 commits into
dotnet:mainfrom
davidwrighton:MoreEfficientProlog

Conversation

@davidwrighton

@davidwrighton davidwrighton commented Oct 8, 2026 •

Copy link
Copy Markdown
Member

Description

Reduce CoreCLR WebAssembly R2R managed method prologs by replacing per-method function-table-index materialization with compact frame identities:

  • ordinary managed methods store their incoming portable entrypoint
  • managed JIT helpers store a constant negative odd CoreLib runtime-function identity
  • funclets store a tagged establishing-frame pointer
  • reverse P/Invoke methods retain a positive odd function-table-index identity because they have no portable-entrypoint argument

Stack processing resolves these identities to the method's virtual IP. The interpreter is unchanged.

The frame-identity relocation carries its target method explicitly so the JIT interface does not assume it always refers to the method being compiled. This also supports future use by direct inter-method calls.

Size impact

Measured on System.Private.CoreLib.wasm using Release browser builds after merging the body-deduplication change from #134623 into main:

Configuration Bytes Wasm functions Code bytes
main baseline 24,447,002 48,280 12,036,573
New prologs 22,091,102 38,467 10,705,558
Difference -2,355,900 (9.64%) -9,813 -1,331,015 (11.06%)

The embedded WebCIL data remained unchanged at 7,897,194 bytes. The remaining saving comes primarily from fewer physical Wasm bodies and the smaller associated function-name data.

Call performance

Measured with R2R-compiled Wasm under Node.js. The hot Leaf callee calls a separate non-inlined method, forcing Leaf to use an unwindable frame and execute the changed PEP-saving prolog on every entry. Disassembly confirms that the baseline materializes its table index while the changed body stores its incoming PEP.

Each sample performs 40,000,000 entries into Leaf, arranged as 1, 2, 4, or 8 sequential calls per loop iteration. Each result is the median of nine independent processes; each process reports the median of nine samples. Baseline and changed processes were alternated.

Calls per iteration Baseline per call New prologs per call Difference
1 20.5859 ns 13.8341 ns -32.80%
2 13.0693 ns 13.2345 ns +1.26%
4 12.6670 ns 12.8688 ns +1.59%
8 12.4607 ns 12.6702 ns +1.68%

The one-call loop exhibits a distinct V8 optimization effect and does not agree with the converged repeated-call cases. The 2/4/8-call cases consistently show a 1.26% to 1.68% Wasm call-performance regression, approximately 1.5%.

Validation

  • ./build.sh -os browser -c Release -subset clr+libs — passed for both merged-main baseline and changed builds
  • ./build.sh -os browser -c Release -subset clr.r2rtests -test — passed: 169 total, 130 passed, 39 skipped
  • python3 src/coreclr/scripts/jitformat.py -r . -o linux -a x64 — passed
  • Interpreted and R2R smoke tests passed, including compacting GC, nested catch/filter/finally, managed helper throws, stack walking, localloc, and compiled reverse P/Invoke

Note

This pull request description was generated with GitHub Copilot.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging @dotnet/jit-contrib for JIT-EE GUID update

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 7 pipeline(s).
9 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @dotnet/crossgen-contrib
See info in area-owners.md if you want to be subscribed.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant