Skip to content

Conversation

davidwrighton
Copy link
Member

@davidwrighton davidwrighton commented Oct 7, 2025

Reduce the number of type loads triggered by complex generic constraints. Experiments show about a 20% reduction in startup time on a proxy of the AWS lambda scenario.

The fixes are:

  1. When a method/type has constraints, do not load the constraint types directly if they are generic interfaces. Instead, do accessibility checking and the constraint validation on the signature of the constraint instead.
  2. When a type is loaded, enhance the special marker type optimization in the interface map to allow Interfaces which require implementation of other interfaces to use the special marker type. Notably, use the special marker type so that if a generic interface's first type parameter is used as all of the generic type parameters of a required interface we use the special marker type to indicate that the type is loaded.
    • This also forces us to have a somewhat more complicated implementation of casting, since the previous model of special marker types could not experience an equivalent interface match
  3. When resolving a default interface method, attempt to avoid loading all the interface types associated with a type. Do so by changing the iteration of interfaces to check to see if the approximate interface could possibly have an implementation
  4. When resolving a static virtual method, attempt to avoid loading all the types of the MethodImpl records. Do so by doing a Method name check before loading the type.

In addition, fix a test so that it still throws when loading an invalid type. This required adding a path which forced the interface type to be loaded.

As part of testing this work, the lack of generic variable type safety checks was noticed in crossgen2, and the following changes were made

  • Add support for doing circularity checks on type and method generic parameters to the TypeValidationChecker in crossgen2
  • Add support for doing variance safety checks to the type loader in crossgen2

And in the runtime

  • Remove the circularity of type variables checks happening in generic method load, as it is redundant
  • Put all of the variance safety checks in the runtime under the SkipTypeValidation flag as crossgen2 can now do it reliably

Related to the work in #120407

…erly

- Reduce the set of constraints that need to be loaded for Bounds and cast checking

TODO:
There is a path in InitTypeContext which I have #ifdef'd out as I don't understand the comment
The accessibility checking needs full loading now, as we don't have a scheme to just look at all the typedefs in a signature, and instead need to do a load of the full type and work from there. This could be revisited.
This is DRAFT as we now have an unused state WhichConstraintsToLoad::TypeOrMethodVarsOnly which we never use. (It could be used for the Bounds algorithm, but that isn't actually used without doing the more expensive logic which does access validation)
@davidwrighton
Copy link
Member Author

Should address issues in #120406

Copy link
Contributor

Tagging subscribers to this area: @mangod9
See info in area-owners.md if you want to be subscribed.

- Currently it only handles interfaces defined on valuetypes
- Change it to work for interfaces that are required implementation of other interfaces
  - (In that case, if the interface is generic, the special instantiation type is the first type parameter of the interface, not anything else.)

This change removes some safety checks that I can't find the rationale for. This may cause some entertaining failures in CI
- Tweak the logic so that it will attempt to avoid loading types if they are cannot have implementations of the method we're looking for
- This test was no longer actually forcing the type which is supposed to throw a TypeLoadException to load within the test
- Tweak the test to actually force the offending type to be loaded
@davidwrighton davidwrighton changed the title [DRAFT] Reduce constraint load Reduce types loaded on startup significantly Oct 8, 2025
@davidwrighton davidwrighton marked this pull request as ready for review October 8, 2025 23:52
Copy link
Contributor

@Copilot 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

This PR reduces type loading during startup by optimizing generic constraint handling and interface map operations. It achieves approximately 20% reduction in startup time for AWS lambda scenarios by deferring unnecessary type loads and using more efficient type checking algorithms.

Key changes:

  • Introduces selective constraint loading to avoid loading generic interface constraints when not needed
  • Optimizes interface map special marker types to work with interfaces, not just value types
  • Implements lazy evaluation strategies for default interface method resolution and static virtual method resolution

Reviewed Changes

Copilot reviewed 13 out of 14 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/tests/Loader/classloader/generics/ByRefLike/InvalidCSharpNegative.il Adds GetInterfaces() call to force interface type loading in test
src/coreclr/vm/typehandle.cpp Updates constraint loading calls to use selective loading approach
src/coreclr/vm/typedesc.h Defines WhichConstraintsToLoad enum and updates TypeVarTypeDesc constraint API
src/coreclr/vm/typedesc.cpp Implements selective constraint loading with interface-aware logic
src/coreclr/vm/typectxt.cpp Updates type context initialization to handle constraint loading changes
src/coreclr/vm/siginfo.cpp Enhances special marker type handling for generic interface instantiation
src/coreclr/vm/runtimehandles.cpp Updates constraint retrieval for reflection API
src/coreclr/vm/methodtablebuilder.cpp Extends special marker optimization to interfaces and adds early exit optimizations
src/coreclr/vm/methodtable.inl Updates interface implementation checking for new special instantiation logic
src/coreclr/vm/methodtable.h Adds GetSpecialInstantiationType method and interface equivalence checking
src/coreclr/vm/methodtable.cpp Implements lazy interface loading, accessibility checking, and optimized method resolution
src/coreclr/vm/genmeth.cpp Updates constraint loading calls and removes unnecessary constraint loads
src/coreclr/vm/comdelegate.cpp Updates delegate constraint checking to use selective loading

@jkotas
Copy link
Member

jkotas commented Oct 9, 2025

/azp run runtime-coreclr outerloop

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

Copy link
Member

@jkotas jkotas left a comment

Choose a reason for hiding this comment

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

The test failure looks related

… parameters to the TypeValidationChecker in crossgen2

- Add support for doing variance safety checks to the type loader in crossgen2
- Remove the circularity of type variables checks happening in generic method load, as it is redundant
- Put all of the variance safety checks in the runtime under the SkipTypeValidation flag as crossgen2 can now do it reliably
- Add test for constraints with function pointers in them
@davidwrighton
Copy link
Member Author

/azp run runtime-coreclr outerloop

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

Copy link
Member

@jkotas jkotas left a comment

Choose a reason for hiding this comment

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

crossgen2 test still failing

@jkotas
Copy link
Member

jkotas commented Oct 11, 2025

/azp run runtime-nativeaot-outerloop

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@jkotas
Copy link
Member

jkotas commented Oct 13, 2025

@EgorBot scenario-awslambda -arm -intel

Copy link
Member

@jkotas jkotas left a comment

Choose a reason for hiding this comment

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

LGTM once the tests are passing

@davidwrighton
Copy link
Member Author

/azp run runtime-interpreter

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@davidwrighton
Copy link
Member Author

/azp run runtime-coreclr outerloop

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@davidwrighton davidwrighton merged commit 56484c9 into dotnet:main Oct 14, 2025
159 of 169 checks passed
@davidwrighton
Copy link
Member Author

/backport to release/10.0

Copy link
Contributor

Started backporting to release/10.0: https://github.com/dotnet/runtime/actions/runs/18504146328

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