Skip to content

[browser][coreCLR] Support interpreter code resolution on portable entrypoint platforms#127370

Open
pavelsavara wants to merge 4 commits intodotnet:mainfrom
pavelsavara:browser_EP_coreclr_prep2
Open

[browser][coreCLR] Support interpreter code resolution on portable entrypoint platforms#127370
pavelsavara wants to merge 4 commits intodotnet:mainfrom
pavelsavara:browser_EP_coreclr_prep2

Conversation

@pavelsavara
Copy link
Copy Markdown
Member

@pavelsavara pavelsavara commented Apr 24, 2026

Summary

Generalizes GetInterpreterCodeFromInterpreterPrecodeIfPresent (renamed to GetInterpreterCodeFromEntryPointIfPresent) to resolve interpreter bytecode addresses on platforms that use FEATURE_PORTABLE_ENTRYPOINTS (e.g., browser WASM) where InterpreterPrecode does not exist.

Motivation

The sampling profiler does not work on WASM because the EventPipe code paths that resolve instruction pointers (IPs) to method information assume the traditional InterpreterPrecode mechanism. On WASM, CoreCLR uses portable entrypoints (FEATURE_PORTABLE_ENTRYPOINTS) instead of interpreter precodes, so the existing code silently returns wrong or zero addresses, causing the profiler to fail to attribute samples to managed methods.

Split from #126324 for smaller reviews

Changes

Renamed function with new signature

  • GetInterpreterCodeFromInterpreterPrecodeIfPresent(TADDR)GetInterpreterCodeFromEntryPointIfPresent(TADDR, MethodDesc*)
  • The new pMethodDesc parameter (defaulting to NULL) enables resolution on portable entrypoint platforms via MethodDesc::GetInterpreterCode().

New portable entrypoint code path (precode.cpp)

Added #elif defined(FEATURE_INTERPRETER) && defined(FEATURE_PORTABLE_ENTRYPOINTS) branch:

  • When pMethodDesc is provided, calls pMethodDesc->GetInterpreterCode() to get the InterpByteCodeStart pointer directly from the MethodDesc, bypassing the precode entirely.
  • Falls through to returning the original entry point when pMethodDesc is NULL or no interpreter code exists.

Portable entrypoint handling in prestub.cpp

Added #ifdef FEATURE_PORTABLE_ENTRYPOINTS branch in JitCompileCodeLockedEventWrapper to use PortableEntryPoint::GetInterpreterData(pCode) instead of InterpreterPrecode::FromEntryPoint(pCode) when extracting the InterpByteCodeStart for ETW method-jitted events.

Caller updates (DAC/debugger/ETW)

All callers updated to pass the new MethodDesc* parameter where available:

  • daccess.cppGetMethodVarInfo, GetMethodNativeMap, RawGetMethodName
  • dacdbiimpl.cppGetNativeCodeInfoForAddr
  • request.cppCopyNativeCodeVersionToReJitData, GetMethodDescData, GetTieredVersions
  • functioninfo.cppCreateDJIsForMethodDesc
  • eventtrace.cppMethodAndStartAddressToEECodeInfoPointer (passes NULL when a specific code address was provided, pMethodDesc otherwise)
  • method.hppGetCodeForInterpreterOrJitted

@pavelsavara pavelsavara added this to the 11.0.0 milestone Apr 24, 2026
@pavelsavara pavelsavara self-assigned this Apr 24, 2026
Copilot AI review requested due to automatic review settings April 24, 2026 08:49
@dotnet-policy-service
Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @steveisok, @tommcdon, @dotnet/dotnet-diag
See info in area-owners.md if you want to be subscribed.

Copy link
Copy Markdown
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 fixes EventPipe/ETW instruction-pointer (IP) to managed-method resolution for interpreted methods on WASM, where CoreCLR uses FEATURE_PORTABLE_ENTRYPOINTS instead of interpreter precodes. This enables the sampling profiler to correctly attribute samples to interpreted managed methods.

Changes:

  • Update MethodDesc::JitCompileCodeLockedEventWrapper to derive the interpreted-method “native start address” from PortableEntryPoint interpreter data when FEATURE_PORTABLE_ENTRYPOINTS is enabled.
  • Update MethodAndStartAddressToEECodeInfoPointer to fall back to MethodDesc::GetInterpreterCode() (returning the InterpByteCodeStart pointer) when no explicit start address is supplied on portable-entrypoint interpreter builds.

Reviewed changes

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

File Description
src/coreclr/vm/prestub.cpp Uses PortableEntryPoint::GetInterpreterData to compute the method start address for interpreted-method ETW events under portable entrypoints.
src/coreclr/vm/eventtrace.cpp Adds a portable-entrypoints interpreter fallback so method events can resolve InterpByteCodeStart when no explicit start address is provided.

Comment thread src/coreclr/vm/eventtrace.cpp Outdated
Comment thread src/coreclr/vm/prestub.cpp
@pavelsavara pavelsavara changed the title [browser] Fix IP resolution for interpreted methods on WASM [browser][coreCLR] Fix IP resolution for interpreted methods on WASM Apr 24, 2026
Copilot AI review requested due to automatic review settings April 24, 2026 08:57
Copy link
Copy Markdown
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 2 out of 2 changed files in this pull request and generated 1 comment.

Comment thread src/coreclr/vm/eventtrace.cpp Outdated
@pavelsavara pavelsavara marked this pull request as ready for review April 24, 2026 11:46
Comment thread src/coreclr/vm/eventtrace.cpp Outdated
pavelsavara and others added 3 commits April 27, 2026 12:11
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
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.

Comment thread src/coreclr/vm/precode.h
@pavelsavara pavelsavara changed the title [browser][coreCLR] Fix IP resolution for interpreted methods on WASM [browser][coreCLR] Support interpreter code resolution on portable entrypoint platforms Apr 27, 2026
@pavelsavara pavelsavara requested a review from jkotas April 27, 2026 17:45
Comment on lines +4420 to +4422
start = GetInterpreterCodeFromEntryPointIfPresent(start, pNativeCodeStartAddress ? NULL : pMethodDesc);

return start;
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.

Suggested change
start = GetInterpreterCodeFromEntryPointIfPresent(start, pNativeCodeStartAddress ? NULL : pMethodDesc);
return start;
return GetInterpreterCodeFromEntryPointIfPresent(start, pNativeCodeStartAddress ? NULL : pMethodDesc);

#endif // !FEATURE_PORTABLE_ENTRYPOINTS

TADDR GetInterpreterCodeFromInterpreterPrecodeIfPresent(TADDR codePointerMaybeInterpreterStub)
TADDR GetInterpreterCodeFromEntryPointIfPresent(TADDR entryPoint, MethodDesc* pMethodDesc)
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.

We should not need to pass in MethodDesc as an extra argument. You can get the methoddesc from the portable entrypoint by calling PortableEntryPoint::GetMethodDesc

} CONTRACTL_END;

#if defined(FEATURE_INTERPRETER) && !defined(FEATURE_PORTABLE_ENTRYPOINTS)
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.

Suggested change
#if defined(FEATURE_INTERPRETER) && !defined(FEATURE_PORTABLE_ENTRYPOINTS)
#ifdef FEATURE_INTERPRETER
#ifdef FEATURE_PORTABLE_ENTRYPOINTS
....
#else
....
#endif // FEATURE_PORTABLE_ENTRYPOINTS
#endif // FEATURE_INTERPRETER

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.

3 participants