Skip to content

[clr-interp] Add support for logging interpreter IR ranges to perf map#129989

Open
BrzVlad wants to merge 1 commit into
dotnet:mainfrom
BrzVlad:feature-interp-perfmap
Open

[clr-interp] Add support for logging interpreter IR ranges to perf map#129989
BrzVlad wants to merge 1 commit into
dotnet:mainfrom
BrzVlad:feature-interp-perfmap

Conversation

@BrzVlad

@BrzVlad BrzVlad commented Jun 29, 2026

Copy link
Copy Markdown
Member

Tested that it works correctly when passing the following env vars to the runtime:

export DOTNET_PerfMapEnabled=1
export DOTNET_PerfMapStubGranularity=2

The interpreter entries from the perf map could be used to profile as described in https://gist.github.com/BrzVlad/80c1b1f61b024f251b60f39c5dedc9d3

Tested that it works correctly when passing the following env vars to the runtime:
```
export DOTNET_PerfMapEnabled=1
export DOTNET_PerfMapStubGranularity=2
```
Copilot AI review requested due to automatic review settings June 29, 2026 17:55
@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.

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.

Pull request overview

This PR extends CoreCLR’s perf-map logging to include interpreter-generated IR ranges, so profiler tools can symbolize interpreter frames similarly to JIT-compiled methods.

Changes:

  • Add PerfMap::LogInterpreterMethod(...) API (guarded by FEATURE_INTERPRETER) and implement logging of interpreter IR ranges.
  • Update MethodDesc::JitCompileCodeLockedEventWrapper to log interpreter IR ranges instead of logging the interpreter entrypoint as a JIT-compiled method.

Reviewed changes

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

File Description
src/coreclr/vm/prestub.cpp Adds interpreter-specific perfmap logging in the JIT/compile wrapper.
src/coreclr/vm/perfmap.h Declares the new interpreter logging entrypoint on PerfMap.
src/coreclr/vm/perfmap.cpp Implements interpreter IR range logging to the perfmap output.

Comment thread src/coreclr/vm/prestub.cpp
Comment on lines +441 to +454
SString name;
pMethod->GetFullMethodInfo(name);

SString line;
line.Printf(FMT_CODE_ADDR " %x [Interpreter] %s\n", irAddress, irSize, name.GetUTF8());

{
CrstHolder ch(&(s_csPerfMap));

if (s_Current != nullptr)
{
s_Current->WriteLine(line);
}
}
@BrzVlad

BrzVlad commented Jun 29, 2026

Copy link
Copy Markdown
Member Author

Example usage: ~/profile.sh x27 ./corerun gettype.dll. The automated register fetching via script-find-ip-reg.sh is not very reliable, it worked fine with checked build but no longer with release (maybe due to the computed goto change). Copilot can easily tweak the script or detect the real register from the disassembly however. EDIT: Updated the script to a new mechanism based on load + br.

Normal perf output (non-descriptive InterpMethodExec)

    79.36%  corerun         libcoreclr.so          [.] InterpExecMethod(InterpreterFrame*, InterpMethodContextFrame*, InterpThreadContext*, ExceptionClauseArgs*)
     4.89%  corerun         libc.so.6              [.] __memset_zva64
     4.74%  corerun         libcoreclr.so          [.] FrameDataAllocator::PopInfo(InterpMethodContextFrame*)
     2.10%  corerun         ld-linux-aarch64.so.1  [.] _dl_tlsdesc_dynamic
     1.99%  corerun         libcoreclr.so          [.] memset@plt
     1.32%  corerun         libcoreclr.so          [.] InterpreterStub
     1.08%  corerun         libcoreclr.so          [.] ErectWriteBarrier(Object**, Object*)
     0.60%  corerun         libcoreclr.so          [.] ExecuteInterpretedMethod

Parsed interp execution:

Samples       %  Method
 -------     ---  ------
    2590   22.4%  [Interpreter] void [System.Private.CoreLib] System.SpanHelpers::Memmove(uint8&,uint8&,native uint)
    1070    9.2%  [Interpreter] object [System.Private.CoreLib] System.Runtime.CompilerServices.CastHelpers::Box(valuetype System.Runtime.CompilerServices.MethodTable*,uint8&)
     860    7.4%  [Interpreter] instance bool [System.Linq] System.Linq.Enumerable+RepeatIterator`1[System.Int32]::MoveNext()
     729    6.3%  [Interpreter] void [gettype] ConsumerExtensions::Consume(class [System.Runtime]System.Collections.IEnumerable,class Consumer)
     685    5.9%  [Interpreter] !!0& [System.Private.CoreLib] System.Runtime.CompilerServices.Unsafe::Add(!!0&,int32)
     588    5.1%  [Interpreter] object [System.Private.CoreLib] System.RuntimeTypeHandle::InternalAllocNoChecks(valuetype System.Runtime.CompilerServices.MethodTable*)
     551    4.8%  [Interpreter] !!0 [System.Private.CoreLib] System.Runtime.CompilerServices.Unsafe::ReadUnaligned(uint8&)
     535    4.6%  [Interpreter] !!0& [System.Private.CoreLib] System.Runtime.CompilerServices.Unsafe::Add(!!0&,native uint)
....
       1    0.0%  [Interpreter] instance void [gettype] Program::BenchRepeat()
       1    0.0%  [Interpreter] instance void [System.Private.CoreLib] System.Object::.ctor()

Total samples: 14576, in InterpExecMethod: 11568 (79.4%), resolved: 11370 (98.3%)

@BrzVlad BrzVlad requested a review from davidwrighton June 29, 2026 18:03
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.

2 participants