Skip to content

ARM64: Display method names for indirect calls in JitDisasm output#126000

Open
Copilot wants to merge 6 commits intomainfrom
copilot/jit-release-jitdisasm-function-names-arm64
Open

ARM64: Display method names for indirect calls in JitDisasm output#126000
Copilot wants to merge 6 commits intomainfrom
copilot/jit-release-jitdisasm-function-names-arm64

Conversation

Copy link
Contributor

Copilot AI commented Mar 23, 2026

Description

ARM64 JitDisasm output for indirect calls (blr/br_tail) was missing method name annotations. On x64, indirect calls render as call [addr] ; MethodName, but on ARM64 the equivalent blr x2 had no function name comment.

The method handle is already stored in idMemCookie for all call types. The IF_BR_1B display case in emitDispInsHelp simply never read it.

Before:

            blr     x2

After:

            blr     x2      // code for IndirectCallAnnotation:VirtualCallee():int

Changes

  • src/coreclr/jit/emitarm64.cpp: In the IF_BR_1B case of emitDispInsHelp, call emitDispCommentForHandle with GTF_ICON_FTN_ADDR to display the method name — matching the format used by movz/movk constant annotations in checked builds and the convention used by other architectures.
Original prompt

This section details on the original issue you should resolve

<issue_title>JIT: Release JitDisasm does not include function names for calls on arm64</issue_title>
<issue_description>E.g. I see

; Assembly listing for method vb_playground.M1:Main() (FullOpts)
; Emitting BLENDED_CODE for arm64 on Apple
; FullOpts code
; optimized code
; fp based frame
; partially interruptible
; No PGO data
; 0 inlinees with PGO data; 2 single block inlinees; 0 inlinees without PGO data

G_M000_IG01:                ;; offset=0x0000
            stp     fp, lr, [sp, #-0x10]!
            mov     fp, sp

G_M000_IG02:                ;; offset=0x0008
            movz    x0, #0x2570
            movk    x0, #0x99F LSL dotnet/runtime#16
            movk    x0, dotnet/runtime#1 LSL dotnet/runtime#32
            bl      CORINFO_HELP_NEWSFAST
            mov     w1, dotnet/runtime#3
            movz    x2, #0x7C00
            movk    x2, dotnet/runtime#590 LSL dotnet/runtime#16
            movk    x2, dotnet/runtime#1 LSL dotnet/runtime#32
            ldr     x2, [x2]
            blr     x2

G_M000_IG03:                ;; offset=0x0030
            ldp     fp, lr, [sp], #0x10
            ret     lr

; Total bytes of code 56

when using JitDisasm on preview3. I would expect a comment with the function name for x2 (IIRC that was the primary reason we did work to store debug info in this case)

cc @dotnet/jit-contrib </issue_description>

<agent_instructions>Please improve JitDisasm for arm64 for Release. Most (if not all) managed-to-managed calls are indirect, but on x64 we render them as call [Foo] while on arm64 we do what is described in the issue with no function name. Please write a small FILECHECK test for arm64 specifically.</agent_instructions>

Comments on the Issue (you are @copilot in this section)


💬 Send tasks to Copilot coding agent from Slack and Teams to turn conversations into code. Copilot posts an update in your thread when it's finished.

@github-actions github-actions bot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Mar 24, 2026
@dotnet-policy-service
Copy link
Contributor

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

Copilot AI and others added 2 commits March 24, 2026 00:30
…ail)

In the IF_BR_1B case of emitDispInsHelp, after displaying the register,
check if idMemCookie is set and display the method name as a comment.
This matches x64 behavior where indirect calls show the target method name.

Also add a small FileCheck test for ARM64 specifically.

Co-authored-by: EgorBo <523221+EgorBo@users.noreply.github.com>
Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/b2a47cb3-cb3d-4479-a881-733d20b8576b
Copilot AI changed the title [WIP] Fix JIT release to include function names for calls on arm64 ARM64: Display method names for indirect calls in JitDisasm output Mar 24, 2026
Copilot AI requested a review from EgorBo March 24, 2026 00:37
@EgorBo EgorBo marked this pull request as ready for review March 24, 2026 01:08
Copilot AI review requested due to automatic review settings March 24, 2026 01:08
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 updates ARM64 JitDisasm output so indirect calls (blr / br_tail) include a method-name annotation comment, matching the existing behavior on other architectures. It also adds an ARM64 FileCheck-based JIT test to prevent regressions.

Changes:

  • ARM64: For IF_BR_1B instruction display, print the method name from idMemCookie as a // comment for indirect calls.
  • Tests: Add a new ARM64 disasm FileCheck test validating blr lines include the target method name annotation.

Reviewed changes

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

File Description
src/coreclr/jit/emitarm64.cpp Adds method-name comment emission for IF_BR_1B (indirect branch/call register format) when idMemCookie is present.
src/tests/JIT/opt/Calls/IndirectCallAnnotation.csproj New JIT disasm/FileCheck-enabled test project configuration.
src/tests/JIT/opt/Calls/IndirectCallAnnotation.cs New test that forces a virtual call and checks ARM64 disasm contains the callee method name on the blr instruction line.

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Comment on lines +13563 to +13567
if (id->idDebugOnlyInfo()->idMemCookie != 0)
{
methodName = m_compiler->eeGetMethodFullName((CORINFO_METHOD_HANDLE)id->idDebugOnlyInfo()->idMemCookie);
printf(" // %s", methodName);
}
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't we use emitDispCommentForHandle?

Normal checked disassembly displays this not on the blr, but on the constant:

G_M27646_IG02:  ;; offset=0x001C
            add     x0, fp, #24	// [V00 loc0]
            movz    x1, #0xD8D8      // code for Program:MutateImplicitByRef(ImpByRef):System.Threading.Tasks.Task`1[long]
            movk    x1, #0xCA44 LSL #16
            movk    x1, #0x7FFA LSL #32
            ldr     x1, [x1]
            blr     x1

I think this should do the same. (Honestly I think this regressed at some point, I am quite sure this used to work in release.)

Copy link
Member

Choose a reason for hiding this comment

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

tbh, my impression it never worked. only in crossgen2 for arm64

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Switched to emitDispCommentForHandle(0, id->idDebugOnlyInfo()->idMemCookie, GTF_ICON_FTN_ADDR) in 43bdb17. This produces // code for MethodName matching the format used by the movz/movk constant annotations in checked builds.

Comment on lines +7 to +25
public class IndirectCallAnnotation
{
[MethodImpl(MethodImplOptions.NoInlining)]
public virtual int VirtualCallee() => 42;

[MethodImpl(MethodImplOptions.NoInlining)]
static int Caller(IndirectCallAnnotation obj)
{
// Verify that the indirect call target is annotated with the method name.
// ARM64: blr {{.*}}VirtualCallee()
return obj.VirtualCallee();
}

[Fact]
public static int TestEntryPoint()
{
return Caller(new IndirectCallAnnotation()) == 42 ? 100 : 0;
}
}
Copy link
Member

Choose a reason for hiding this comment

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

This test probably isn't that interesting, won't it run in checked? This was only broken in release

Copy link
Member

Choose a reason for hiding this comment

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

ah, we don't run these in Release? we probably should, but then I agree it's useless

Copy link
Member

Choose a reason for hiding this comment

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

To be honest I am not sure, we might?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed the test in 43bdb17.

@EgorBo
Copy link
Member

EgorBo commented Mar 24, 2026

@copilot address the feedback.

Use emitDispCommentForHandle instead of directly calling eeGetMethodFullName
and printf, matching the pattern used by movz/movk constant annotations.

Remove the FileCheck test since it would only run in checked mode where
the method name already appears on the movz/movk constant instructions.

Co-authored-by: EgorBo <523221+EgorBo@users.noreply.github.com>
Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/84a22a2e-9c3e-40ef-ab3b-97113c002f92
Copy link
Contributor Author

Copilot AI commented Mar 24, 2026

@copilot address the feedback.

Addressed in 43bdb17 — switched to emitDispCommentForHandle and removed the test.

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

Labels

area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

JIT: Release JitDisasm does not include function names for calls on arm64

4 participants