Skip to content
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

Fix reflection invoke file format issue for generic methods #83438

Merged
merged 5 commits into from
Apr 4, 2023

Conversation

MichalStrehovsky
Copy link
Member

The file format that mapped reflection metadata to runtime artifacts had a limitation that required generic methods to be always instantiated over concrete types - we could not place canonical method bodies there. The limitation stemmed from the fact that the mapping table was placing a generic dictionary in it.

This switches the table to use NameAndSignature + an array of instantiation arguments.

The rest of this change is just deleting code that was working around the problem. The fixes in NativeLayoutVertexNode and NodeFactory.NativeLayout are fixing analysis holes that were exposed by our ability to be more lazy.

Also saves 0.4% on BasicWebApi, which is always nice.

Cc @dotnet/ilc-contrib

The file format that mapped reflection metadata to runtime artifacts had a limitation that required generic methods to be always instantiated over concrete types - we could not place canonical method bodies there. The limitation stemmed from the fact that the mapping table was placing a generic dictionary in it.

This switches the table to use NameAndSignature + an array of instantiation arguments.

The rest of this change is just deleting code that was working around the problem. The fixes in NativeLayoutVertexNode and NodeFactory.NativeLayout are fixing analysis holes that were exposed by our ability to be more lazy.

Also saves 0.4% on BasicWebApi, which is always nice.
@ghost
Copy link

ghost commented Mar 15, 2023

Tagging subscribers to this area: @agocke, @MichalStrehovsky, @jkotas
See info in area-owners.md if you want to be subscribed.

Issue Details

The file format that mapped reflection metadata to runtime artifacts had a limitation that required generic methods to be always instantiated over concrete types - we could not place canonical method bodies there. The limitation stemmed from the fact that the mapping table was placing a generic dictionary in it.

This switches the table to use NameAndSignature + an array of instantiation arguments.

The rest of this change is just deleting code that was working around the problem. The fixes in NativeLayoutVertexNode and NodeFactory.NativeLayout are fixing analysis holes that were exposed by our ability to be more lazy.

Also saves 0.4% on BasicWebApi, which is always nice.

Cc @dotnet/ilc-contrib

Author: MichalStrehovsky
Assignees: -
Labels:

area-NativeAOT-coreclr

Milestone: -

@MichalStrehovsky
Copy link
Member Author

/azp run runtime-extra-platforms

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@MichalStrehovsky
Copy link
Member Author

/azp run runtime-extra-platforms

@azure-pipelines
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.

Thanks!

@jkotas
Copy link
Member

jkotas commented Mar 17, 2023

Linq tests need to be looked at:

[FAIL] System.Linq.Tests.MaxTests.Max_AllTypes
System.NotSupportedException : 'System.Linq.Tests.MaxTests.Max_AllTypes[System.Byte](System.Collections.Generic.IEnumerable`1[System.Byte],System.Byte)' is missing native code. MethodInfo.MakeGenericMethod() is not compatible with AOT compilation. Inspect and fix AOT related warnings that were generated when the app was published. For more information see https://aka.ms/nativeaot-compatibility

@MichalStrehovsky
Copy link
Member Author

I had a chance to sleep on this a couple time and I have one question that I can't make my mind on:

Currently, if reflection analysis/RD.XML/whatever comes up with the idea that we need Foo<string>, we'll generate MethodTable and everything for Foo<string>. After this change, we would only generate the type loader template to be be able to create it when needed.

The question is whether I went too far with turning all analysis to happen with canonical forms. Whether it would be enough to take the part of this change that allows canonical forms of generic methods (like we already allow for canonical forms of types), but don't force the entire analysis to happen on top of Canon. Leave the option to force concrete instantiations open.

@jkotas
Copy link
Member

jkotas commented Mar 17, 2023

If I understand correctly, these are benefits of each option:

  • No observable functional difference between two options
  • Analysis based on cannon:
    • Compiler is faster
    • Binaries are smaller
  • Analysis based on exact instantiations:
    • Less dependency on type builder when creating generic instantiations via reflection, more of them are saved into image

Is this right?

@MichalStrehovsky
Copy link
Member Author

Yep. And it can be used to work around type loader bugs.

@jkotas
Copy link
Member

jkotas commented Mar 17, 2023

"Analysis based on cannon" option looks better to me (ie what you have there right now).

I would not optimize for having easier workarounds for type loader bugs. We can use #81741 for that once it becomes available.

@MichalStrehovsky
Copy link
Member Author

Linq tests need to be looked at:

Oh, not a regression, this is an improvement. Min_AllTypes<T> is constrained to where T : INumber<T> and we previously couldn't create a suitable instantiation, so the method wasn't reflection-visible at all. We now create __Canon instantiation but we need a lot more than that. RD.XML it is.

Not being reflection visible at all might be a separate bug...

@MichalStrehovsky
Copy link
Member Author

/azp run runtime-extra-platforms

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@MichalStrehovsky MichalStrehovsky deleted the canonentries branch April 4, 2023 03:37
@ghost ghost locked as resolved and limited conversation to collaborators May 4, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants