-
Notifications
You must be signed in to change notification settings - Fork 5.3k
JIT: Devirtualize non-shared GVMs in R2R #123183
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch |
There was a problem hiding this 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 enables devirtualization of non-shared Generic Virtual Methods (GVMs) in ReadyToRun (R2R) compilation by recording the compile-time method handle before embedding it into a lookup, allowing it to be used for devirtualization later. Shared GVMs remain unsupported due to lacking a proper generic context.
Changes:
- Added
IsConstructedproperty toInstantiationto determine if all type parameters are concrete types - Removed the early rejection of GVM devirtualization in R2R compilation
- Enhanced devirtualization logic to properly handle generic method instantiations
- Extended JIT's devirtualization candidate detection to support R2R virtual function pointers
- Updated JIT-EE interface version GUID to reflect the API change
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/coreclr/tools/Common/TypeSystem/Common/Instantiation.cs | Adds IsConstructed property to check if instantiation contains only concrete types (no generic parameters) |
| src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs | Removes CORINFO_DEVIRTUALIZATION_FAILED_GENERIC_VIRTUAL enum value as GVM devirtualization is now supported |
| src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs | Removes early rejection check for generic virtual method devirtualization |
| src/coreclr/tools/Common/Compiler/DevirtualizationManager.cs | Enhances logic to instantiate generic methods and adds check to block shared GVMs |
| src/coreclr/jit/importer.cpp | Records compile-time method handle for R2R virtual function pointer helper calls |
| src/coreclr/jit/gentree.h | Adds compileTimeMethodHandle union field and extends IsGenericVirtual to include R2R helper |
| src/coreclr/jit/gentree.cpp | Adds R2R-specific logic to extract method handle for devirtualization candidates |
| src/coreclr/jit/compiler.cpp | Removes error message case for the deleted enum value |
| src/coreclr/inc/jiteeversionguid.h | Updates JIT-EE version identifier GUID for interface change |
| src/coreclr/inc/corinfo.h | Removes CORINFO_DEVIRTUALIZATION_FAILED_GENERIC_VIRTUAL enum value |
|
It hit a weird assertion: aren't the two |
|
It seems that the failure only happens when specifying |
3589e2f to
9efb3c1
Compare
|
It turns out to be a verification-only issue. We need to use the method definition for comparison during verification instead. |
615ddb9 to
8ab7342
Compare
|
Tests are passing. Please take a look. @MichalStrehovsky |
8ab7342 to
1113997
Compare
MichalStrehovsky
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cc @davidwrighton for the JitInterface.cpp change, Cc @jakobbotsch for the RyuJIT change
| MethodDesc slotDefiningMethodDecl = MetadataVirtualMethodAlgorithm.FindSlotDefiningMethodForVirtualMethod(declMethod); | ||
| // We need to bring the original instantiation back so that we can still try devirtualizing | ||
| // when the method is a generic virtual method | ||
| if (originalDeclMethod.HasInstantiation) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you move this right under the impl = implType.FindVirtualFunctionTargetMethodOnObjectType(declMethod); line as if (impl != null && originalDeclMethod.HasInstantiation) to reduce the diff in this PR and nesting?
The fact that FindVirtualFunctionTargetMethodOnObjectType will strip the method instantiation is a nuisance. I'd like to fix these (there's a couple more resolution APIs that annoying do this) at some point. But let's not perturb the git history for this wart.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FindVirtualFunctionTargetMethodOnObjectType doesn't strip method instantiation. ResolveInterfaceMethodTargetWithVariance and FindMethodOnTypeWithMatchingTypicalMethod do.
|
@MichalStrehovsky |
Implement the support for GVM devirtualization in managed type system.
It shares the same issue in #122023 where we are still not able to devirt shared GVMs due to lacking a proper generic context, so let's do the non-shared case first.
NativeAOT still not supported yet as it requires some work in the JIT to stop spilling the helper call for fat pointers.
Contributes to #112596
/cc: @MichalStrehovsky @jakobbotsch