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

[NativeAOT] Reflection Invoke refactoring #73131

Merged
merged 22 commits into from
Aug 2, 2022

Conversation

jkotas
Copy link
Member

@jkotas jkotas commented Jul 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.

Fixes #72548

- 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 dotnet#72548
@jkotas
Copy link
Member Author

jkotas commented Jul 31, 2022

Some perf numbers

  NativeAOT - current NativeAOT - this PR CoreCLR - net6.0 CoreCLR - net7.0
Invoke static method with no arguments 22ns 11ns 34ns 8.2ns
Invoke instance method with int and string arguments 67ns 34ns 96ns 38ns

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
Member Author

jkotas commented Aug 1, 2022

cc @steveharter @dotnet/area-system-reflection

@jkotas
Copy link
Member Author

jkotas commented Aug 1, 2022

/azp run runtime-extra-platforms

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@jkotas
Copy link
Member Author

jkotas commented Aug 1, 2022

/azp run runtime-extra-platforms

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@jkotas
Copy link
Member Author

jkotas commented Aug 1, 2022

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

@jkotas
Copy link
Member Author

jkotas commented Aug 1, 2022

/azp run runtime-extra-platforms

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@jkotas
Copy link
Member Author

jkotas commented Aug 2, 2022

/azp run runtime-extra-platforms

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

Copy link
Member

@MichalStrehovsky MichalStrehovsky left a comment

Choose a reason for hiding this comment

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

Very nice!

jkotas and others added 4 commits August 1, 2022 22:54
Co-authored-by: Michal Strehovský <MichalStrehovsky@users.noreply.github.com>
@AaronRobinsonMSFT
Copy link
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
Member Author

jkotas commented Aug 2, 2022

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

@akoeplinger
Copy link
Member

akoeplinger commented Aug 2, 2022

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
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.
@ghost ghost locked as resolved and limited conversation to collaborators Sep 1, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
4 participants