Skip to content

[NativeAOT] Reflection Invoke refactoring - #73131

Merged
jkotas merged 22 commits into
dotnet:mainfrom
jkotas:byreflike-reflection
Aug 2, 2022
Merged

[NativeAOT] Reflection Invoke refactoring#73131
jkotas merged 22 commits into
dotnet:mainfrom
jkotas:byreflike-reflection

Conversation

@jkotas

@jkotasjkotas commented Jul 31, 2022

Copy link
Copy Markdown
Member
  • Refactored reflection Invoke in NativeAOT to be similar to how it is done in CoreCLR.
  • All argument validation and coercion is done via static code now. This makes the reflection invoke stubs much smaller and the AOT compiler side a lot simpler.
  • The invoke stub is minimal now and just takes the arguments for the methods to invoke as "Span of byrefs". The two notable differences with CoreCLR are:
    • The invoke stub takes the function pointer to call as an argument to allow sharing of the stubs between methods with the same signature. CoreCLR has the thunks non-sharable currently. We have discussed sharing them among methods with the same signature like it is done here.
    • The return value is returned as byref. CoreCLR thunk does boxing of the return value as part of the stub. Again, we have discussed to do it this way in CoreCLR too, we just did not have time to do it yet.

Fixes#72548

@ghostghost assigned jkotasJul 31, 2022
- Refactored reflection Invoke in NativeAOT to be similar to how it is done in CoreCLR.
- All argument validation and coercion is done via static code now. This makes the reflection invoke stubs much smaller and the AOT compiler side a lot simpler.
- The invoke stub is minimal now and just takes the arguments for the methods to invoke as "Span of byrefs". The two notable differences with CoreCLR are:
- The invoke stub takes the function pointer to call as an argument to allow sharing of the stubs between methods with the same signature. CoreCLR has the thunks non-sharable currently. We have discussed sharing them among methods with the same signature like it is done here.
- The return value is returned as byref. CoreCLR thunk does boxing of the return value as part of the stub. Again, we have discussed to do it this way in CoreCLR too, we just did not have time to do it yet.
Fixesdotnet#72548
@jkotas
jkotasforce-pushed the byreflike-reflection branch from 0bef061 to b08f4eeCompareJuly 31, 2022 20:30
@jkotas

Copy link
Copy Markdown
MemberAuthor

Some perf numbers

NativeAOT - currentNativeAOT - this PRCoreCLR - net6.0CoreCLR - net7.0
Invoke static method with no arguments22ns11ns34ns8.2ns
Invoke instance method with int and string arguments67ns34ns96ns38ns

The extra fixed overhead that is observable in invoke static method with no arguments is due extra "Invoker" layer in native AOT. I am going to delete that layer in subsequent PRs.

@jkotas
jkotas marked this pull request as ready for review August 1, 2022 17:25
@jkotas

Copy link
Copy Markdown
MemberAuthor

cc @steveharter @dotnet/area-system-reflection

@jkotas

Copy link
Copy Markdown
MemberAuthor

/azp run runtime-extra-platforms

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jkotas

Copy link
Copy Markdown
MemberAuthor

/azp run runtime-extra-platforms

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jkotas

Copy link
Copy Markdown
MemberAuthor

@MichalStrehovsky @dotnet/ilc-contrib This is ready for review.

@jkotas

Copy link
Copy Markdown
MemberAuthor

/azp run runtime-extra-platforms

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jkotas

Copy link
Copy Markdown
MemberAuthor

/azp run runtime-extra-platforms

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@MichalStrehovskyMichalStrehovsky left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Very nice!

jkotasand others added 4 commits August 1, 2022 22:54
Co-authored-by: Michal Strehovský <MichalStrehovsky@users.noreply.github.com>
@AaronRobinsonMSFT

Copy link
Copy Markdown
Member

@jkotas I think this broke the API compat for AOT.

 LibraryImportGenerator -> ...\runtime\artifacts\bin\LibraryImportGenerator\Release\netstandard2.0\Microsoft.Interop.LibraryImportGenerator.dll
System.Private.CoreLib -> ...\runtime\artifacts\bin\System.Private.CoreLib\ref\Release\net7.0\System.Private.CoreLib.dll
...\.nuget\packages\microsoft.dotnet.apicompat\7.0.0-beta.22372.1\build\Microsoft.DotNet.ApiCompat.targets(95,5): error : Compat issues with assembly System.Private
.CoreLib: [...\runtime\src\coreclr\nativeaot\System.Private.CoreLib\src\System.Private.CoreLib.csproj]
...\.nuget\packages\microsoft.dotnet.apicompat\7.0.0-beta.22372.1\build\Microsoft.DotNet.ApiCompat.targets(95,5): error : TypesMustExist : Type 'System.Reflection.D ynamicInvokeInfo' does not exist in the reference but it does exist in the implementation. [...\runtime\src\coreclr\nativeaot\System.Private.CoreLib\src\System.Private.CoreLib.cs proj]
...\.nuget\packages\microsoft.dotnet.apicompat\7.0.0-beta.22372.1\build\Microsoft.DotNet.ApiCompat.targets(95,5): error : [...\runtime\src\coreclr\nativeaot\System. Private.CoreLib\src\System.Private.CoreLib.csproj]
...\.nuget\packages\microsoft.dotnet.apicompat\7.0.0-beta.22372.1\build\Microsoft.DotNet.ApiCompat.targets(95,5): error : *** Invalid/Unused baseline differences ** * [...\runtime\src\coreclr\nativeaot\System.Private.CoreLib\src\System.Private.CoreLib.csproj]
...\.nuget\packages\microsoft.dotnet.apicompat\7.0.0-beta.22372.1\build\Microsoft.DotNet.ApiCompat.targets(95,5): error : TypesMustExist : Type 'System.InvokeUtils' does not exist in the reference but it does exist in the implementation. [...\runtime\src\coreclr\nativeaot\System.Private.CoreLib\src\System.Private.CoreLib.csproj]
...\.nuget\packages\microsoft.dotnet.apicompat\7.0.0-beta.22372.1\build\Microsoft.DotNet.ApiCompat.targets(95,5): error : TypesMustExist : Type 'System.Reflection.D elegateDynamicInvokeInfo' does not exist in the reference but it does exist in the implementation. [...\runtime\src\coreclr\nativeaot\System.Private.CoreLib\src\System.Private.Co reLib.csproj]
...\.nuget\packages\microsoft.dotnet.apicompat\7.0.0-beta.22372.1\build\Microsoft.DotNet.ApiCompat.targets(112,5): error : MatchingRefApiCompat failed - The referen ce assembly doesn't match all the APIs in the implementation for '...\runtime\artifacts\bin\coreclr\windows.x64.Release\aotsdk\System.Private.CoreLib.dll'. To address either fix errors in the reference assembly (referenced as implementation in compat errors for this reverse compat check), add the issues to the baseline file '...\runtime\src\coreclr\nativ eaot\System.Private.CoreLib\src\MatchingRefApiCompatBaseline.txt' or disable this check by setting RunMatchingRefApiCompat=false in this project. [...\runtime\src\coreclr\nativea ot\System.Private.CoreLib\src\System.Private.CoreLib.csproj]

@jkotas

Copy link
Copy Markdown
MemberAuthor

@akoeplinger It looks like your #72143 was not updated to account for my changes. Could you please fix it up?

@akoeplinger

akoeplinger commented Aug 2, 2022

Copy link
Copy Markdown
Member

Yep, I did merge main into my PR branch but looks like it was a few minutes before your PR went it.

akoeplinger added a commit to akoeplinger/runtime that referenced this pull request Aug 2, 2022
Fixed build break caused by merging dotnet#73131 and dotnet#73131 around the same time.
@akoeplinger

Copy link
Copy Markdown
Member

Opened a PR with the fix: #73248

akoeplinger added a commit that referenced this pull request Aug 2, 2022
Fixed build break caused by merging #73131 and #73131 around the same time.
@ghostghost locked as resolved and limited conversation to collaborators Sep 1, 2022
Sign up for freeto 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.

Cannot box a ByRef-like (ref struct) when using a CreateDelegate method on method that accepts a ByRef-like parameter.

4 participants

@jkotas@AaronRobinsonMSFT@akoeplinger@MichalStrehovsky