Skip to content

[r2r] Include generic type instantiations from GenericLookupSignature for discovery of virtual methods#129882

Open
BrzVlad wants to merge 2 commits into
dotnet:mainfrom
BrzVlad:feature-r2r-type-from-gendict
Open

[r2r] Include generic type instantiations from GenericLookupSignature for discovery of virtual methods#129882
BrzVlad wants to merge 2 commits into
dotnet:mainfrom
BrzVlad:feature-r2r-type-from-gendict

Conversation

@BrzVlad

@BrzVlad BrzVlad commented Jun 26, 2026

Copy link
Copy Markdown
Member

Normally, we detect the usage of a type in the application via the TypeFixupSignature and then we use this type to determine which virtual methods on the type need compilation (via supporting GVMDependenciesNode and VirtualMethodUseNode).

Consider the following scenario:

public class TestA<T, U>
{
    public virtual void TestMethod(T item) => Console.WriteLine($"{item} / {typeof(U)}");
}

public class TestB<T, U>
{
    public TestA<T, U> TestCreate() => new TestA<T, U>();
}

TestB<string, int> obj = new TestB<string, int>();
obj.TestCreate().TestMethod("hello");

When compiling TestB<Canon,int32>.TestCreate we need to create an instance of TestA<T,int32>. Because we are compiling a shared version we need to embed a call to a generic lookup helper in order to obtain the actual T. This is done with a GenericLookupSignature fixup, which contains the type TestA<Canon,int32> that needs resolving. When creating this node, we add the InheritedVirtualMethodsNode as a dependency which facilitates discovery of virtual methods on this type.

Fixes perf on linq sorting, ex: LinqBenchmarks.Order00LinqMethodX (~20x improvement)

BrzVlad added 2 commits June 25, 2026 21:26
… for discovery of virtual methods

Normally, we detect the usage of a type in the application via the TypeFixupSignature and then we use this type to determine which virtual methods on the type need compilation (via supporting GVMDependenciesNode and VirtualMethodUseNode).

Consider the following scenario:

```
public class TestA<T, U>
{
    public virtual void TestMethod(T item) => Console.WriteLine($"{item} / {typeof(U)}");
}

public class TestB<T, U>
{
    public TestA<T, U> TestCreate() => new TestA<T, U>();
}

TestB<string, int> obj = new TestB<string, int>();
obj.TestCreate().TestMethod("hello");
```

When compiling `TestB<Canon,int32>.TestCreate` we need to create an instance of `TestA<T,int32>`. Because we are compiling a shared version we need to embed a call to a generic lookup helper in order to obtain the actual T. This is done with a GenericLookupSignature fixup, which contains the type `TestA<Canon,int32>` that needs resolving. When creating this node, we add the InheritedVirtualMethodsNode as a dependency which facilitates discovery of virtual methods on this type.
Copilot AI review requested due to automatic review settings June 26, 2026 05:51

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 updates ReadyToRun dependency analysis so that when a type handle is obtained via a GenericLookupSignature (generic dictionary lookup), the compiler still records the type usage needed to discover and compile inherited virtual methods for that instantiated type. It also adds a focused regression test covering the scenario.

Changes:

  • Add InheritedVirtualMethods dependency tracking for GenericLookupSignature when _fixupKind == ReadyToRunFixupKind.TypeHandle.
  • Add a new VirtualMethodGenerics test case that reaches a generic type instantiation only via a GenericLookupSignature fixup.
  • Extend R2RTestSuites with a new [Fact] that validates the relevant virtual method is compiled.

Reviewed changes

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

File Description
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/GenericLookupSignature.cs Adds dependency analysis to record generic-lookup type usage for virtual dispatch discovery (mirrors TypeFixupSignature’s behavior for this scenario).
src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCases/VirtualMethodGenerics/GenericLookup.cs New embedded test-case source driving a generic instantiation through a GenericLookupSignature-only path.
src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCases/R2RTestSuites.cs Adds an xUnit test validating TestA\2<__Canon,int>.TestMethod` is compiled as expected.

Comment on lines +141 to +144
// In shared generic code, newobj uses a generic dictionary lookup for the type handle
// rather than a direct READYTORUN_FIXUP_TypeHandle (TypeFixupSignature). Mirror the
// creation of InheritedVirtualMethodsNode as its done in TypeFixupSignature, so we
// scan the virtual methods on this type for dependency analysis.
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