Repository navigation
NativeAOT: GVM analysis only runs on canonical form for shared instantiations #130752
Description
Activity
- addeduntriagedNew issue has not been triaged by the area ownerNew issue has not been triaged by the area owner
on Jul 15, 2026 - addedarea-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMICLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
on Jul 15, 2026 dotnet-policy-service commented
on Jul 15, 2026 ContributorMore actionsTagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
See info in area-owners.md if you want to be subscribed.The problem is not that the scanner doesn't scan it, but the GVM analysis (that runs irrespective of IL scanner since we need the analysis for debug builds too - it predicts all generic virtual method bodies we need, given the types that are allocated) is running only on __Canon. This was deliberate to limit compile time and sizes. We could have a mode where we analyze concrete things, but it would have to be opt in. That's one way the devirtualization could be solved. It will deoptimize the other things. It's not my preference. We actually used to do that before and it was making Avalonia 50% bigger than needed (dotnet/runtimelab#537).
The other option is using RyuJIT-as-a-scanner so that this is not even considered a GVM call. That's tracked in #83021.
- changed the title
[-]NativeAOT: IL scanner does not scan shared instantiaiton of GVMs[/-][+]NativeAOT: GVM analysis only runs on canonical form for shared instantiations[/+]on Jul 15, 2026 The problem is not that the scanner doesn't scan it, but the GVM analysis (that runs irrespective of IL scanner since we need the analysis for debug builds too - it predicts all generic virtual method bodies we need, given the types that are allocated) is running only on __Canon.
Thanks for clarifying. I have updated the title of issue.
- added and removedarea-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMICLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
on Jul 15, 2026 - removeduntriagedNew issue has not been triaged by the area ownerNew issue has not been triaged by the area owner
on Jul 15, 2026 dotnet-policy-service commented
on Jul 15, 2026 ContributorMore actionsTagging subscribers to this area: @agocke, @dotnet/ilc-contrib
See info in area-owners.md if you want to be subscribed.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsNo status
The whole program analysis of GVMs currently assumes the call will be lazy and will go through the type loader. If we enable devirtualization for shared generic virtual methods, the following test will fail:
We don't expect
Atom[,]to exist during scanning because GVM analysis only ever seesFrob<__Canon>(we deliberately ignore theFrob<Atom>call and consider it justFrob<__Canon>). We do this for two reasons - compile speed, and size. GVMs expand very aggressively and not precomputing all the types that we could build lazily saves us both.We could in theory have a mode that does the full analysis and analyzes
Frob<Atom>that then forces bothAtom[,]andAtom[,,]to exists, but we don't have it yet.The GVM devirt under NativeAOT has been limited to struct instantiations only for now. We could allow reference types if the other analysis mode is added.
This is one of the things where RyuJIT-as-IL-scanner would help because then we would do this devirt during scanning already and GVM analysis never gets in the picture (it's not considered a GVM call in the first place).
Originally posted by @MichalStrehovsky in #130202 (comment).