-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
PublishAot affects non-AOT behavior #81803
Comments
Tagging subscribers to this area: @dotnet/area-system-reflection-emit Issue DetailsDescriptionAdding Reproduction StepsExpression<Func<int, int, int, int>> e = (_, _, _) => 1;
e.Compile(); <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PublishAot>true</PublishAot>
</PropertyGroup>
</Project>
Expected behaviorNo exceptions Actual behavior
Regression?No response Known WorkaroundsNo response ConfigurationSDK: 8.0.100-preview.1.23107.12 Other informationNo response
|
This is intentional so that people don't get unpleasant surprise after they debug their app, they're ready to publish, and it doesn't work. What's the scenario where a working Ref.Emit would be needed during inner dev loop, but got broken on publish? Cc @eerhardt |
Tagging subscribers to this area: @agocke, @MichalStrehovsky, @jkotas Issue DetailsDescriptionAdding Reproduction StepsExpression<Func<int, int, int, int>> e = (_, _, _) => 1;
e.Compile(); <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PublishAot>true</PublishAot>
</PropertyGroup>
</Project>
Expected behaviorNo exceptions Actual behavior
Regression?No response Known WorkaroundsNo response ConfigurationSDK: 8.0.100-preview.1.23107.12 Other informationNo response
|
This was fixed with #80759. Linq.Expressions should still work, even though PublishAot=true. It just doesn't use Ref.Emit in that case, it falls back to the interpreter mode, like it will for the published app. @AndriySvyryd - can you try a newer build? |
I was just using this specific case to illustrate that Currently it's possible to do this by removing |
This is intentional, as @MichalStrehovsky says above. We want the app running during
My understanding is that EF Core doesn't use Ref.Emit directly, but instead uses System.Linq.Expressions. If this is the case, Linq.Expressions will opt to not use Ref.Emit, but instead use an interpreted mode. So it will still work correctly with |
Correct. As long as there are no other intentional functional differences than the ones mentioned above it should be fine.
I still get it with SDK |
How do you guarantee that the test execution of the app performed all operations that the app needs to perform dynamically? One of principles is to avoid designs that require trial and error: https://github.com/dotnet/designs/blob/main/accepted/2020/form-factors.md#technical-roadmap . |
Of course, we can't guarantee that. We discover the user's DbContext and the statically known LINQ queries. But we also plan to provide a hook that would allow the users to explicitly call the dynamic queries and we'll generate code for the exercised combinations. Truly dynamic models and queries won't be supported. We are investigating whether we can provide an analyzer that would find the unsupported queries to avoid trial and error. Also, if the user runs their tests with |
Given that this is by design, I'm going to close this issue. If there are more specific concerns, we can address them in a separate issue. |
The specific issue described in the first comment still reproes in 8.0.100-preview.3.23151.5 even though @eerhardt said in #81803 (comment) that is should have been fixed |
Looks like I missed a couple places in System.Linq.Expressions to respect IsDynamicCodeSupported in #80759. In this case: runtime/src/libraries/System.Linq.Expressions/src/System/Dynamic/Utils/DelegateHelpers.cs Lines 34 to 41 in 967250c
According to runtime/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets Lines 246 to 249 in 8d2ddc4
It looks like Re-opening to fix these places in System.Linq.Expressions. |
Tagging subscribers to this area: @cston Issue DetailsDescriptionAdding Reproduction StepsExpression<Func<int, int, int, int>> e = (_, _, _) => 1;
e.Compile(); <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PublishAot>true</PublishAot>
</PropertyGroup>
</Project>
Expected behaviorNo exceptions Actual behavior
Regression?No response Known WorkaroundsNo response ConfigurationSDK: 8.0.100-preview.1.23107.12 Other informationNo response
|
@MichalStrehovsky - in trying to fix this issue (main...eerhardt:runtime:Fix81803), I hit a snag: runtime/src/libraries/System.Linq.Expressions/src/System/Dynamic/Utils/DelegateHelpers.cs Lines 24 to 29 in f59a3f5
When running on CoreCLR, this type/method doesn't exist. Is there a way to simulate what |
We would need Ref.Emit on CoreCLR to emulate it, so it's better to not take this codepath and leave the existing Ref.Emit one since it's ref.emit either way. In Native AOT, this relies on the fact that the AOT compiler will generate extra thunks for each delegate type in the app to support this. I understand it's a bit of a pickle because we don't want ref.emit to work. We might need some sort of backdoor ref-emit. What I mean is that we would add a private API from CoreLib that we reflection-discover like the above |
I'm not a Runtime Expert, but in Xamarin the same problem exsists. Project Property for that |
* CanEmitObjectArrayDelegate * CanCreateArbitraryDelegates These properties are all set to `false` when running on NativeAOT, so have them respect RuntimeFeature.IsDynamicCodeSupported. Fix dotnet#81803
…8539) * Respect IsDynamicCodeSupported in more places in Linq.Expressions * CanEmitObjectArrayDelegate * CanCreateArbitraryDelegates These properties are all set to `false` when running on NativeAOT, so have them respect RuntimeFeature.IsDynamicCodeSupported. However, CanEmitObjectArrayDelegate needs a work around because DynamicDelegateAugments.CreateObjectArrayDelegate does not exist in CoreClr's System.Private.CoreLib. Allow System.Linq.Expressions to create an object[] delegate using Ref.Emit even though RuntimeFeature.IsDynamicCodeSupported is set to false (ex. using a feature switch). To enable this, add an internal method in CoreLib that temporarily allows the current thread to skip the RuntimeFeature check and allows DynamicMethod instances to be created. When System.Linq.Expressions needs to generate one of these delegates, it calls the internal method through Reflection and continues to use Ref.Emit to generate the delegate. Fix #81803
Description
Adding
<PublishAot>true</PublishAot>
breaks dynamic code even when running the JIT versionReproduction Steps
dotnet run
Expected behavior
No exceptions
Actual behavior
Regression?
No response
Known Workarounds
No response
Configuration
SDK: 8.0.100-preview.1.23107.12
Other information
No response
The text was updated successfully, but these errors were encountered: