Skip to content

JIT: Unify to instParamLookup and improve GVM test coverage#126947

Open
hez2010 wants to merge 2 commits intodotnet:mainfrom
hez2010:shared-gvm-devirt/1-tests-instparamlookup
Open

JIT: Unify to instParamLookup and improve GVM test coverage#126947
hez2010 wants to merge 2 commits intodotnet:mainfrom
hez2010:shared-gvm-devirt/1-tests-instparamlookup

Conversation

@hez2010
Copy link
Copy Markdown
Contributor

@hez2010 hez2010 commented Apr 15, 2026

Extracted from #123323. This PR is the first step in splitting the shared GVM devirtualization work.

It does two things:

  • expands the generic virtual method test coverage so the later enablement PRs have good coverage
  • refactors devirtualization a bit to replace multiple ad-hoc flags in CORINFO_DEVIRTUALIZATION_INFO with a single instParamLookup

Contributes to #112596

/cc: @jakobbotsch

Copilot AI review requested due to automatic review settings April 15, 2026 12:57
@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 Apr 15, 2026
@dotnet-policy-service dotnet-policy-service bot added the community-contribution Indicates that the PR has been added by a community member label Apr 15, 2026
@dotnet-policy-service
Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
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

Refactors CoreCLR devirtualization metadata to use a unified instParamLookup and expands JIT test coverage for generic virtual method (GVM) scenarios to support follow-on GVM devirtualization work.

Changes:

  • Add a new GVM-focused runtime lookup/delegate test to broaden devirtualization coverage.
  • Replace CORINFO_DEVIRTUALIZATION_INFO ad-hoc flags with instParamLookup, and update JIT devirtualization logic to consume it.
  • Update SuperPMI and the managed JitInterface type definitions/serialization to match the new CORINFO_DEVIRTUALIZATION_INFO shape (plus bump the JIT/EE versioning GUID).

Reviewed changes

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

Show a summary per file
File Description
src/tests/JIT/Generics/VirtualMethods/generic_virtual_methods.cs Adds additional GVM/runtime-lookup-related test coverage.
src/coreclr/vm/jitinterface.cpp Initializes/produces instParamLookup for devirtualization results (replacing older flags).
src/coreclr/jit/importercalls.cpp Plumbs instParamLookup through devirtualization + guarded devirtualization candidate tracking and inserts instantiation args when required.
src/coreclr/jit/morph.cpp Simplifies lookup-tree helpers to take CORINFO_LOOKUP directly.
src/coreclr/jit/compiler.h Updates declarations for the new lookup-tree helper signatures and GDV candidate plumbing.
src/coreclr/inc/corinfo.h Updates CORINFO_DEVIRTUALIZATION_INFO to carry instParamLookup instead of legacy flags; documents “no lookup needed” sentinel.
src/coreclr/inc/jiteeversionguid.h Bumps the JIT/EE version GUID for the interface change.
src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs Mirrors the CORINFO_DEVIRTUALIZATION_INFO layout change in managed definitions.
src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs Updates managed resolveVirtualMethod implementation to populate instParamLookup and method-context behavior.
src/coreclr/tools/superpmi/superpmi-shared/agnostic.h Updates SuperPMI record structs to include instParamLookup.
src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp Records/restores/dumps instParamLookup in SuperPMI method contexts.

@@ -8601,8 +8601,9 @@ bool CEEInfo::resolveVirtualMethodHelper(CORINFO_DEVIRTUALIZATION_INFO * info)
info->detail = CORINFO_DEVIRTUALIZATION_UNKNOWN;
memset(&info->resolvedTokenDevirtualizedMethod, 0, sizeof(info->resolvedTokenDevirtualizedMethod));
memset(&info->resolvedTokenDevirtualizedUnboxedMethod, 0, sizeof(info->resolvedTokenDevirtualizedUnboxedMethod));
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

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

info->instParamLookup.lookupKind.runtimeLookupKind is left uninitialized here (only needsRuntimeLookup is set). Even when needsRuntimeLookup is false, this can leak uninitialized data into diagnostics/SuperPMI recordings and make results non-deterministic. Initialize the whole instParamLookup (e.g., zero it) or explicitly set runtimeLookupKind to a defined value before returning.

Suggested change
memset(&info->resolvedTokenDevirtualizedUnboxedMethod, 0, sizeof(info->resolvedTokenDevirtualizedUnboxedMethod));
memset(&info->resolvedTokenDevirtualizedUnboxedMethod, 0, sizeof(info->resolvedTokenDevirtualizedUnboxedMethod));
memset(&info->instParamLookup, 0, sizeof(info->instParamLookup));

Copilot uses AI. Check for mistakes.
Comment on lines +9003 to +9012
GenTree* instParam = getLookupTree(&dvInfo.instParamLookup, GTF_ICON_METHOD_HDL, compileTimeHandle);

if (instParam == nullptr)
{
// If we're inlining, impLookupToTree can return nullptr after recording a fatal observation.
JITDUMP("Failed to produce the lookup for devirtualized call, sorry.\n");
return;
}

call->gtArgs.InsertInstParam(this, instParam);
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

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

The local name instParam is reused for two different concepts in the same method (CORINFO_METHOD_HANDLE instParam earlier, then GenTree* instParam here). This shadowing is easy to misread and can lead to mistakes during future edits. Rename one/both (e.g., instParamHnd vs instParamNode) to keep the handle and tree clearly distinct.

Suggested change
GenTree* instParam = getLookupTree(&dvInfo.instParamLookup, GTF_ICON_METHOD_HDL, compileTimeHandle);
if (instParam == nullptr)
{
// If we're inlining, impLookupToTree can return nullptr after recording a fatal observation.
JITDUMP("Failed to produce the lookup for devirtualized call, sorry.\n");
return;
}
call->gtArgs.InsertInstParam(this, instParam);
GenTree* instParamNode = getLookupTree(&dvInfo.instParamLookup, GTF_ICON_METHOD_HDL, compileTimeHandle);
if (instParamNode == nullptr)
{
// If we're inlining, impLookupToTree can return nullptr after recording a fatal observation.
JITDUMP("Failed to produce the lookup for devirtualized call, sorry.\n");
return;
}
call->gtArgs.InsertInstParam(this, instParamNode);

Copilot uses AI. Check for mistakes.
@hez2010
Copy link
Copy Markdown
Contributor Author

hez2010 commented Apr 16, 2026

Test failure seems unrelated.

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 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.

2 participants