Skip to content

[wasm][interpreter] Defer managed calli cookie resolution to execution time#125455

Merged
radekdoulik merged 17 commits intodotnet:mainfrom
radekdoulik:clr-wasm-improve-calli-cookie-resolution
Mar 18, 2026
Merged

[wasm][interpreter] Defer managed calli cookie resolution to execution time#125455
radekdoulik merged 17 commits intodotnet:mainfrom
radekdoulik:clr-wasm-improve-calli-cookie-resolution

Conversation

@radekdoulik
Copy link
Member

@radekdoulik radekdoulik commented Mar 11, 2026

On portable entry point platforms, calli instructions targeting managed code previously required the compiler to compute a signature cookie at compile time via GetCookieForInterpreterCalliSig. This caused assertion failures for delegate shuffle thunks and
required a hard-coded missingCookies table in the WASM build generator to pre-generate interp-to-native stubs for every possible managed calli signature.

Implements #121222

Changes

Compiler (compiler.cpp):

  • For managed and FCall callis on FEATURE_PORTABLE_ENTRYPOINTS platforms, pass NULL cookie instead of computing it at compile time. The interpreter resolves the call at runtime from the PortableEntryPoint's MethodDesc.
  • Unmanaged callis (PInvoke) continue to compute the cookie at compile time.
  • For CORINFO_CALL_CODE_POINTER / CORINFO_VIRTUALCALL_LDVIRTFTN paths, pass NULL cookie since these targets always have a MethodDesc and take the CALL_INTERP_METHOD fast path.

Newobj helper MethodDesc (jitinterface.cpp, RuntimeHelpers.CoreCLR.cs, corelib.h):

  • Add a dummy InternalCall method NewobjHelperDummy(IntPtr) -> object providing a MethodDesc with the correct signature for newobj allocator JIT helpers, to make them look like regular FCall.
  • In getHelperFtnStatic, attach this dummy MethodDesc to newobj helper PortableEntryPoints (CORINFO_HELP_NEWFAST through CORINFO_HELP_NEWSFAST_ALIGN8_FINALIZE) so the interpreter can derive the call cookie from the MethodDesc instead of deferring via signature
    token lookup.

Executor (interpexec.cpp):

  • At execution time, managed calli targets are portable entry points with a MethodDesc. Interpreted methods have no native entry point in the PortableEntryPoint and are dispatched via CALL_INTERP_METHOD. FCalls and now also Newobj allocator helpers carry both a native
    entry point and a dummy MethodDesc; the call cookie is derived from the MethodDesc and the native code is invoked via InvokeCalliStub.

Portable entry points (precode_portable.cpp, precode_portable.hpp):

  • Add Init(void* nativeEntryPoint, MethodDesc* pMD) overload for creating a PortableEntryPoint with both native code and an attached MethodDesc.

Generator cleanup (ManagedToNativeGenerator.cs, callhelpers-interp-to-managed.cpp):

  • Remove the hard-coded missingCookies array (40 signatures) from the WASM build task.
  • Remove 40 corresponding pre-generated interp-to-native stubs (~288 lines) that are no longer needed.

@radekdoulik radekdoulik added this to the Future milestone Mar 11, 2026
@radekdoulik radekdoulik added the arch-wasm WebAssembly architecture label Mar 11, 2026
@radekdoulik radekdoulik requested a review from maraf as a code owner March 11, 2026 20:26
Copilot AI review requested due to automatic review settings March 11, 2026 20:26
@radekdoulik radekdoulik requested review from janvorli and removed request for janvorli March 11, 2026 20:27
@dotnet-policy-service
Copy link
Contributor

Tagging subscribers to this area: @BrzVlad, @janvorli, @kg
See info in area-owners.md if you want to be subscribed.

@radekdoulik
Copy link
Member Author

radekdoulik commented Mar 11, 2026

To consider: with the lazy approach, is the cache check overhead in execution phase ok? Is there better way how to cache the cookie? Also note that the unmanaged path is currently not deferring the cookie resolution to execution phase to avoid the cache check overhead.

Copy link
Contributor

Copilot AI left a comment

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 changes how the interpreter handles calli signature cookies on portable entry point platforms (notably WASM): instead of requiring the compiler to resolve the cookie up-front, it defers cookie resolution to execution time (and caches it), avoiding compile-time asserts and eliminating the need for the WASM generator’s hard-coded “missing cookie” pre-generation list.

Changes:

  • Interpreter compiler now encodes managed calli sites with a signature-token + runtime cookie cache slot (via a new CalliFlags::DeferredCookie).
  • Interpreter executor (interpexec.cpp) routes portable-entry-point targets that have a MethodDesc through CALL_INTERP_METHOD, and lazily resolves/caches cookies for portable entry points without a MethodDesc.
  • WASM build/gen cleanup removes the missingCookies list and removes the corresponding pre-generated interp-to-managed thunks/stubs.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/tasks/WasmAppBuilder/coreclr/ManagedToNativeGenerator.cs Removes the temporary missingCookies signature list from thunk/stub generation inputs.
src/coreclr/vm/wasm/callhelpers-interp-to-managed.cpp Removes previously pre-generated signature thunk helpers and their entries from g_wasmThunks.
src/coreclr/vm/precode_portable.hpp Adds PortableEntryPoint::TryGetMethodDesc API for non-asserting lookup.
src/coreclr/vm/precode_portable.cpp Implements TryGetMethodDesc (returns nullptr rather than asserting).
src/coreclr/vm/interpexec.cpp Adds runtime cookie resolution/caching path for deferred managed calli signatures on portable entry points.
src/coreclr/interpreter/inc/interpretershared.h Adds CalliFlags::DeferredCookie to signal runtime resolution.
src/coreclr/interpreter/compiler.h Extends EmitCalli to accept a deferredCookie parameter (defaulted).
src/coreclr/interpreter/compiler.cpp Emits deferred-cookie data items for managed calli on portable entry points; keeps eager cookies for unmanaged calli.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

Copilot AI review requested due to automatic review settings March 17, 2026 13:39
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

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

Copilot AI review requested due to automatic review settings March 18, 2026 05:00
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

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

Copilot AI review requested due to automatic review settings March 18, 2026 05:11
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants