Skip to content

[APX] Add Jmpabs support. - #131826

Open
DeepakRajendrakumaran wants to merge 18 commits into
dotnet:mainfrom
DeepakRajendrakumaran:jmpabs
Open

DeepakRajendrakumaran wants to merge 18 commits into
dotnet:mainfrom
DeepakRajendrakumaran:jmpabs

Conversation

@DeepakRajendrakumaran

@DeepakRajendrakumaran DeepakRajendrakumaran commented Aug 4, 2026 •

Copy link
Copy Markdown
Contributor

Add JMPABS (APX) Support for Virtual Call Stubs on AMD64

Summary

This PR adds support for the JMPABS instruction (part of Intel's APX - Advanced Performance Extensions) to virtual call stubs on AMD64, reducing stub size and improving instruction fetch efficiency.

Background

APX introduces the JMPABS instruction (D5 00 A1 + 8-byte address), which performs a 64-bit absolute jump. JMPABS provides performance benefits over the traditional mov rax, imm64; jmp rax sequence:

Virtual call stubs are small code sequences generated at runtime for dispatching interface and virtual method calls. Currently, these stubs use a two-instruction sequence (mov rax, target; jmp rax) to perform 64-bit absolute jumps.

Changes

Virtual Call Stub Infrastructure

Stub Generation Helpers (src/coreclr/vm/amd64/cgenamd64.cpp, cgencpu.h)

  • Added emitJmpAbsJump() helper function to emit raw JMPABS instructions (11 bytes)
  • Modified emitBackToBackJump() to use JMPABS encoding when available, with fallback to legacy encoding
  • Extend AMD64 virtual call short dispatch stubs to support an APX encoding path (jne rel32; nop; jmpabs imm64) and use it when APX is available.
  • Added IsJmpAbsAvailable() CPU capability detection function
  • Removed dead code: EncodeLoadAndJumpThunk() (obsolete thunk generation helper)
  • Fixed DispatchStubShort_offsetof_failDisplBase macro referencing wrong struct type (DispatchStubLong → DispatchStubShort)

Testing

  1. JIT Emitter Unit Tests: Ran unit tests to verify JMPABS instruction encoding in the JIT emitter
  2. Library Tests: Ran library tests with APX enabled/disabled to verify stub changes cause no failures on non-APX hardware
  3. Runtime Tests: Ran src/tests with and without APX to validate stub changes on non-APX hardware

Issue

Fixes #131817

JIT Emitter

src/coreclr/jit/emitxarch.cpp

  • Added JMPABS instruction encoding support in the emitter
  • Added unit test for JMPABS encoding
  • Note: JMPABS is not currently used anywhere in the JIT itself

Edit - the emitter changes have been reveretd based on feedback from @jkotas

Opens

1. Static Stub Size with NOP Padding

Current approach: To maintain consistent stub size and simplify stub management, this PR uses NOP padding in the APX encoding path:

emitBackToBackJump (used in jump stubs): Both encodings are 12 bytes

Legacy: mov rax, imm64; jmp rax (12 bytes)
APX: jmpabs imm64 (11 bytes) + nop (1 byte) = 12 bytes
DispatchStubShort (used in dispatch stubs): Both encodings are 18 bytes

Legacy: jne rel32 (6 bytes) + mov rax, imm64; jmp rax (12 bytes) = 18 bytes
APX: jne rel32 (6 bytes) + nop (1 byte) + jmpabs imm64 (11 bytes) = 18 bytes

2. APX Availability Detection

JMPABS availability is determined at runtime via IsJmpAbsAvailable(), which checks HasInstructionSet(InstructionSet_APX) from the JIT's CPU capability flags. Is runtime-only detection sufficient, or do we need additional compile-time or toolchain checks for crossgen/ReadyToRun scenarios?

3. DispatchStubLong JMPABS Support

DispatchStubLong could benefit from JMPABS encoding, but the instruction's 3-byte prefix shifts the 64-bit immediate from offset +2 (legacy mov rax, imm64) to offset +3 (JMPABS). This offset change may break the 8-byte alignment requirement.Should we defer this optimization?

Copilot AI lite review requested due to automatic review settings August 4, 2026 18:27
@DeepakRajendrakumaran DeepakRajendrakumaran changed the title [APX] Add Jmpabs support. [WIP] [APX] Add Jmpabs support. Aug 4, 2026
@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 Aug 4, 2026
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 5 pipeline(s).
11 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 dotnet-policy-service Bot added the community-contribution Indicates that the PR has been added by a community member label Aug 4, 2026

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

Adds initial AMD64 APX JMPABS support in CoreCLR, wiring it into VM virtual-call stub emission and adding emitter support/tests in RyuJIT.

Changes:

  • Extend AMD64 virtual call short dispatch stubs to support an APX encoding path (jne rel32; nop; jmpabs imm64) and use it when APX is available.
  • Add VM-side capability detection (IsJmpAbsAvailable) plus a raw emitJmpAbsJump helper, and route emitBackToBackJump through JMPABS when available.
  • Introduce INS_jmpabs in the JIT instruction set and add emitter unit-test coverage for encoding.

Reviewed changes

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

Show a summary per file
File Description
src/coreclr/vm/amd64/virtualcallstubcpu.hpp Adds APX/legacy union encoding for DispatchStubShort, updates fail/impl target accessors, and adjusts short-stub reachability logic.
src/coreclr/vm/amd64/cgencpu.h Replaces removed thunk helper with IsJmpAbsAvailable declaration and adds emitJmpAbsJump API.
src/coreclr/vm/amd64/cgenamd64.cpp Implements APX availability detection and emits JMPABS for back-to-back jump stubs (with legacy fallback).
src/coreclr/jit/instrsxarch.h Adds INS_jmpabs as an APX instruction.
src/coreclr/jit/emitxarch.cpp Teaches the emitter to size/output INS_jmpabs (REX2 + opcode + imm64).
src/coreclr/jit/codegenxarch.cpp Adds an emitter unit-test emission site for INS_jmpabs.

Comment thread src/coreclr/vm/amd64/cgencpu.h Outdated
Comment thread src/coreclr/vm/amd64/cgenamd64.cpp
Comment thread src/coreclr/vm/amd64/virtualcallstubcpu.hpp Outdated
Comment thread src/coreclr/jit/emitxarch.cpp Outdated
Comment thread src/coreclr/vm/amd64/virtualcallstubcpu.hpp Outdated
@jkotas jkotas added the apx Related to the Intel Advanced Performance Extensions (APX) label Aug 4, 2026
Copilot AI review requested due to automatic review settings August 4, 2026 22:19

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

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

Suppressed comments (2)

src/coreclr/jit/emitxarch.cpp:17260

  • The new INS_jmpabs support in this function conflicts with the existing immed/reloc assumptions immediately below: noway_assert(size < EA_8BYTE || ((int)val == val && !id->idIsCnsReloc())) and the idIsCnsReloc block currently only allow 32-bit immediates and relocations for push. As a result, valid jmpabs uses (64-bit targets and/or relocations) will hit debug asserts. Please special-case INS_jmpabs in those checks.
    emitAttr    size      = id->idOpSize();
    ssize_t     val       = emitGetInsSC(id);
    bool        valInByte = ((signed char)val == (target_ssize_t)val);
    // We would to update GC info correctly
    assert(!IsSSEInstruction(ins));

src/coreclr/vm/amd64/virtualcallstubcpu.hpp:129

  • DispatchHolder/LookupHolder now call IsJmpAbsAvailable() and emitJmpAbsJump(), but this header doesn't include cgencpu.h or otherwise declare these functions. That makes the header fragile and can break compilation depending on include order (and virtualcallstub.h includes this directly). Add forward declarations here (or include cgencpu.h) so the header is self-contained.
/*DispatchStubShort*********************************************************************************
This is the logical continuation of DispatchStub for the case when the failure target is within
a rel32 jump (DISPL). Uses a union to handle both legacy and APX encodings. */
struct DispatchStubShort
{

Copilot AI review requested due to automatic review settings August 6, 2026 18:15
Comment thread src/coreclr/vm/amd64/virtualcallstubcpu.hpp Outdated

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.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Note

This error may be related to your runner configuration. You can now configure runners for Copilot code review separately from Copilot cloud agent by creating a copilot-code-review.yml file with your setup steps. Read the docs for details.

@DeepakRajendrakumaran
DeepakRajendrakumaran marked this pull request as ready for review August 6, 2026 18:59
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 3 pipeline(s).
13 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

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.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Note

This error may be related to your runner configuration. You can now configure runners for Copilot code review separately from Copilot cloud agent by creating a copilot-code-review.yml file with your setup steps. Read the docs for details.

@DeepakRajendrakumaran DeepakRajendrakumaran changed the title [WIP] [APX] Add Jmpabs support. [APX] Add Jmpabs support. Aug 6, 2026
Copilot AI review requested due to automatic review settings August 28, 2026 16:26
Comment thread src/coreclr/vm/amd64/cgenamd64.cpp Outdated

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

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

Comment on lines +137 to +141
LIMITED_METHOD_CONTRACT;
// JMPABS encoding starts with 0x0F 0x85 (jne near)
// Legacy encoding starts with 0x48 0xB8 (mov rax, imm64)
return _bytes[0] == 0x0F && _bytes[1] == 0x85;
}
Copilot AI review requested due to automatic review settings September 4, 2026 19:09
Comment thread src/coreclr/vm/amd64/cgenamd64.cpp Outdated
Comment on lines +363 to +364
0xA1 == pbCode[2] &&
0x90 == pbCode[11])

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
0xA1 == pbCode[2] &&
0x90 == pbCode[11])
0xA1 == pbCode[2])

No need to check for the padding nop

Comment thread src/coreclr/vm/amd64/cgenamd64.cpp Outdated
LIMITED_METHOD_CONTRACT;
PTR_BYTE pbCode = PTR_BYTE(pCode);

// Check for JMPABS encoding (APX): D5 00 A1 [8 bytes] 90

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
// Check for JMPABS encoding (APX): D5 00 A1 [8 bytes] 90
// Check for JMPABS encoding (APX)

No need to duplicate the bytes in the comment

Comment thread src/coreclr/vm/amd64/cgenamd64.cpp Outdated
return true;
}

// Check for legacy encoding: 48 B8 [8 bytes] FF E0

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
// Check for legacy encoding: 48 B8 [8 bytes] FF E0
// Check for legacy encoding: mov rax, imm64; jmp rax

Comment thread src/coreclr/inc/dacvars.h Outdated
DEFINE_DACVAR(BOOL, CodeVersionManager__s_HasNonDefaultILVersions, CodeVersionManager::s_HasNonDefaultILVersions)
#endif // FEATURE_CODE_VERSIONING
#ifdef TARGET_AMD64
// Selects the encoding used by the AMD64 runtime-generated stubs (APX JMPABS vs. mov rax/jmp rax).

@jkotas jkotas Sep 21, 2026 •

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
// Selects the encoding used by the AMD64 runtime-generated stubs (APX JMPABS vs. mov rax/jmp rax).
// Selects the encoding used by the AMD64 runtime-generated stubs (APX jmpabs vs. mov rax/jmp rax).

Use consistent casing for asm instructions in comments (either all upper case or all lower case - I do not have a preference). Comments that combine different casing on a single line or within single method do not look good.

(fix all places in the PR)

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.

Comment on lines +236 to +238
// Padding aligns _implTarget as in DispatchStubShort. The APX form needs no mov rax and uses a
// second jmpabs for the fail path, so both arms are padded to 35 bytes: the stub grows 40 -> 48,
// which is free because these are allocated with CODE_SIZE_ALIGN (16) and 40 already took 48.
shortStubRW->_failDispl = (DISPL) displ;
shortStubRW->_implTarget = (size_t) implTarget;
CONSISTENCY_CHECK((PCODE)&shortStubRX->_failDispl + sizeof(DISPL) + shortStubRX->_failDispl == failTarget);
#if defined(TARGET_AMD64)

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.

This is Amd64 specific file. It does not need TARGET_AMD64 ifdef

longStub->_failTarget = failTarget;
*longStubRW = dispatchLongInit;

#if defined(TARGET_AMD64)

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.

Same here

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.

This branch has not been deployed

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

Labels

apx Related to the Intel Advanced Performance Extensions (APX) area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI community-contribution Indicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[x64\[APX]Add support in JIT for jmpabs and use jmpabs where possible.

4 participants