Skip to content

Add app-specific CoreCLR WASM FCall trimming - #136655

Merged
jkoritzinsky merged 17 commits into
mainfrom
dev/jkoritzinsky/fcall-trimming
Nov 13, 2026
Merged

jkoritzinsky merged 17 commits into
mainfrom
dev/jkoritzinsky/fcall-trimming

Conversation

@jkoritzinsky

@jkoritzinsky jkoritzinsky commented Oct 29, 2026 •

Copy link
Copy Markdown
Member

Extend CoreCLR's existing QCall entrypoint lookup to cover FCalls, so browser and WASI application relinking can discard native FCall implementations when their managed InternalCall declarations have been trimmed.

Approach

  • Replace ecalllist.h registrations with C-linkage Type_Method implementations and the shared QCall/FCall entrypoint resolver on all CoreCLR platforms. Ordinary FCalls derive their lookup name from CoreLib metadata and cache the resolved native address. The non-WASM static table is sorted and uses binary search.
  • Keep dynamically assigned String bindings and special delegate/COM constructor handling separate from the shared table.
  • Extend the existing portable-callhelper generator to collect FCalls alongside QCalls from its CoreLib input. WASM application relinks use the post-trim managed closure to emit the combined table and resolver in the existing callhelpers-pinvoke.cpp.
  • Include the generated table in the checked-in browser/WASI snapshots used by prebuilt runtimes. Configuration-independent helper declarations allow the same snapshots to support Debug/Checked and Release; CoreLib's library-build-only descriptor preserves the necessary declarations without permanently rooting them in applications.

There is no FCall manifest, source-line descriptor scheme, table-layout SDK header, or fourth generated helper source. Application-specific native trimming remains WASM-only; the named FCall binding mechanism is shared across CoreCLR platforms.

Validation

The following local runs cover the current shared-table implementation, including commit 2c58a649758:

  • Windows x64 Debug runtime, CoreLib, and library testhost builds passed.
  • Browser-wasm and WASI-wasm Release CoreLib/testhost builds, snapshot regeneration, and native runtime builds passed. Regenerated snapshots differed only by the expected exception-helper rename.
  • 241 targeted exception, exception-data dictionary, and ExceptionDispatchInfo tests passed on Windows Debug, with no failures or skips.
  • 128 WasmArgumentLayoutTests passed in each of Windows Debug, browser Release, and WASI Release (384 executions total), with no failures or skips.
  • Standalone exception-data/dispatch smoke checks passed on Windows, Node (browser), and wasmtime (WASI), each exiting with code 100. These exercise the renamed FCall through exception data access and exception-dispatch/stack-trace operations.

Earlier shared-table validation also checked browser/WASI Debug-versus-Release generated-table parity, deterministic regeneration, and removal of unused validation helpers during application trimming. Those checks preceded the naming-only cleanups; they are not being presented as fresh runs at the latest commit.

Debug/Checked WASM native builds and the full cross-platform test matrix were not run locally for this revision. These results do not assert CI completion.

Size measurements

The previously reported focused-smoke and Havit Bootstrap size numbers were measured against the superseded descriptor/manifest prototype. They have been removed because they do not establish savings for the current shared-table design. Native payload size, compressed payload size, and startup/performance measurements have not been rerun for this implementation.

Note

This implementation and PR description were generated with GitHub Copilot.

Generate ECall manifests from runtime headers and emit app-specific tables from surviving CoreLib InternalCalls. Integrate discardable native descriptors, browser and WASI relinking, manifest generation and staging, and coverage for the shared parser and table generation.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@dotnet-policy-service dotnet-policy-service Bot added linkable-framework Issues associated with delivering a linker friendly framework labels Oct 29, 2026
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 4 pipeline(s).
12 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.

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

@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @agocke
See info in area-owners.md if you want to be subscribed.

Stage CoreCLR WASM native assets for WASI, exclude ECall headers from NativeAOT builds, and avoid CA1866 in the shared runtime header parser.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@jkotas

jkotas commented Oct 29, 2026

Copy link
Copy Markdown
Member

(bonus points for unifying the scheme with NAOT too)

@jkotas jkotas left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DllImports/QCalls and FCalls are the same problem. Can we unify the lookup tables for the two so that we do not have to have two different infras to look them up and trim them?

jkoritzinsky and others added 2 commits October 30, 2026 15:28
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

# Conflicts:
#	src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/WasmArgumentLayoutTests.cs
Resolve fixed-address FCalls through the shared native QCall table and generate app-specific WASM bindings in callhelpers-pinvoke.cpp. Preserve existing QCall ordering and dynamic String bindings while removing the separate ECall export infrastructure and unused-entry diagnostics.

Update browser/WASI helper snapshots, trimming coverage, and runtime documentation.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@jkoritzinsky
jkoritzinsky marked this pull request as draft October 31, 2026 02:42
@jkoritzinsky

Copy link
Copy Markdown
Member Author

Pushed a commit with the new design to run it against CI, but switched this back to draft while I polish it.

Comment thread src/coreclr/vm/qcallentrypoints.cpp Resolved
Comment thread src/coreclr/vm/qcallentrypoints.cpp Resolved
jkoritzinsky and others added 2 commits November 9, 2026 10:20
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot AI 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.

🟡 Changes recommended

The PR description still describes a different implementation and needs to clarify which reported measurements and validation runs cover the current shared QCall/FCall table design.

1 open issue
4 resolved since last review

Review effort: Balanced

Comment thread src/coreclr/vm/ecall.cpp Resolved
Comment thread docs/design/coreclr/botr/corelib.md Resolved
jkoritzinsky and others added 2 commits November 9, 2026 15:45
Keep validation FCall declarations and the GC-mode QCall available in all CoreLib configurations. Preserve the declarations during library trimming without rooting them in applications, and use the generated resolver for prebuilt WebAssembly runtimes.

Remove the skip-table option and special native archive placement. Use RuntimeHelper_ identifiers for generated ABI aliases and cover the shared table in generator tests.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Drop the obsolete Agile qualifier from IsImmutableException in the managed declaration and callers, matching native implementation, shared entrypoint table, generated WebAssembly snapshots, and documentation example. Exception immutability behavior and ABI signatures are unchanged.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@jkoritzinsky
jkoritzinsky requested a review from jkotas November 10, 2026 00:14
Comment thread src/coreclr/vm/runtimehelpers.cpp Resolved
Leave browser memmove/memset wrapper resolution to the generated tables. Remove their declarations and special-case entries from runtimehelpers.cpp while preserving the libc entries and SunOS workaround.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@jkoritzinsky
jkoritzinsky enabled auto-merge (squash) November 10, 2026 18:24
@jkotas

jkotas commented Nov 10, 2026

Copy link
Copy Markdown
Member

Conflicts

Reconcile the upstream managed memory-pressure implementation with named FCall bindings. Register the four new GC helpers as C-linkage functions, update memory-pressure event QCalls, retain removal of ecalllist.h, and regenerate both WASM helper snapshots.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@jkoritzinsky
jkoritzinsky requested a review from jkotas November 11, 2026 22:46
@jkoritzinsky

Copy link
Copy Markdown
Member Author

/ba-g work item failed to launch

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

Labels

arch-wasm WebAssembly architecture area-VM-coreclr linkable-framework Issues associated with delivering a linker friendly framework

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

5 participants