-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Capability APIs for runtime code generation #25959
Comments
We have duplicate issues of this: https://github.com/dotnet/corefx/issues/13535 The preferred design for API availability checks in earlier discussions was to just add static
|
The IsSupported pattern would make this proposal look like this (with an IsSupported method for all entrypoint classes for reflection emit). What do folks think?
|
LGTM. I am not sure whether we need |
We could probably do without After a bit of digging, we could potentially need more IsSupported APIs to cover downstream usage refemit. For example, Regex and System.Composition have APIs that depend on it. Would we want some sort of support check on those as well? |
CC @davidfowl, who could hopefully use this in ASP.NET. |
Yes, I think having a property like |
We should walk through the flow chart on what this would look like for our DI container. Today we have a couple of different modes (https://github.com/aspnet/DependencyInjection/blob/943ffa1187399ad4c2af0d23641af9804eacd4e6/src/DI/ServiceProviderMode.cs#L6):
Here's what I'm thinking the flow control would be: // Set the default mode to runtime if there's no JIT Mode = RuntimeFeature.HasJit ? ServiceProviderMode.Dynamic : ServiceProviderMode.Runtime;
/cc @pakrym for DI |
@davidfowl, now that I think about it a bit more, is |
No we'd never want to use it if it was interpreted in this scenario unless it was faster than reflection. |
I want a way to figure out the fastest way to do reflection. Compiled expressions are faster than traditional MethodInfo.Invoke reflection A runtime way to figure out which to choose out of the two - basically are expressions going to be compiled or interpreted - is what I want. |
Ok, let's just go with |
I incorrectly thought |
@morganbr |
Ah, right you are. I just didn't find it in the contract sources due to magic in how System.Runtime is built. In that case, I'll go ahead and mark this ready for review. |
A few thoughts:
This needs a broader discussion. I'll invite @morganbr for the next one. |
@terrajobst , the point of HasJit is that some features, like compiled LINQ expressions may work on AoT, but they're slow. That might eventually be true of DynamicMethod/Assemblybuilder as well. In those cases, IsSupported would be true, but a library like ASP.NET or Json.NET would want to find out whether they make code faster than reflection (because there's a JIT) or slower (because they're interpreted). I'm open to putting HasJit on a different class. |
I wanted to use a flag like this to test whether |
The proposed API is for inclusion in the .NET Core platform. If somebody wants to build a package with API that does best effort approximation of this API for existing .NET Standard 2.0 platforms, that's fine but it should be different assembly and package name that does not unify with the .NET Core platform one. |
I'd rather have HasJit in .NET Standard, particularly since it's relevant in UAP. AssemblyBuilder/DynamicMethod are different and not part of this proposal. |
If we agree on a reasonable API, I am sure it will be included in .NET Standard 3.0. .NET Standard 2.0 is done. There is no way to add new APIs to it. |
Agreed. We'll just need to bring it to UAP as well as .NET Core (and perhaps some Xamarin flavors too). |
So is the api ready for review? |
This is related: dotnet/standard#832 I believe this feature needs a more comprehensive design. I'll follow-up. |
I've updated the proposal based on our meeting notes. I hope @morganbr doesn't mind it shows up as his :-) |
Heh, the update is fine (though I don't think there's actually a penalty for using compiled regex, it just uses the state machine). |
The existing design of the class is using string constants, is there any reason we are deviating from that and switching to bool properties instead? |
The string constants are meant for static discovery of runtime features. I believe these capabilities are inherently dynamic, so making them string constants feels wrong (note that the presence of the string constants presupposes the runtime must return |
Contributes to dotnet/corefx#29258 Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>
Contributes to dotnet/corefx#29258 Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>
Contributes to dotnet/corefx#29258 Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>
Are we going to backport the implementation of If we don't, any app that's targeting netcoreapp lower than 3.0 and using |
Hi @terrajobst, Thanks and happy holidays |
Anyone else who knows the answer is also welcome to reply :) |
@darkl We are not monitoring old closed issues, and your question is somewhat unrelated to what this issue about. If you would like to get answer to your question, open a new question issue in https://github.com/dotnet/runtime |
We believe we need to add reflection emit to .NET Standard.
We already have features in .NET Standard that imply support for dynamic code generation, for example
Assembly.Load(byte[])
,RegexOptions.Compiled
, andLambdaExpression.Compile()
.Today, developers have no way to test whether runtime code generation is actually supported -- the runtime might throw
PlatformNotSupported
. Furthermore, even if it is supported, it might be slower as the runtime is interpreting the code (for example, by walking the expressions trees or interpreting the IL). While that ensures that scenarios that depend on code generation just work, it makes it hard to support scenarios that use code generation as a performance optimization. In those cases, not using code generation is usually faster.Hence, we need an API that allows developers to check for the support of code generation as well as an API that allows developers to check using runtime code generation as a performance optimization is sensible.
API Proposal
The semantics are:
IsDynamicCodeSupported
returnstrue
. This doesn't tell developers whether the code is interpreted or compiled.IsDynamicCodeCompiled
returnstrue
.RuntimeFeature.IsSupported(string)
also returns the appropriate value when called with the strings"IsDynamicCodeSupported"
and"IsDynamicCodeCompiled"
.Affected features
Assembly.Load(byte[])
)DynamicMethod
(lightweight code generation, LCG)Scenarios
Failing early with
RuntimeFeature.IsDynamicCodeSupported
In some scenarios, performance isn't the primary goal but use to get stuff to work, for example, mocking. A mocking framework might provide an API like
Proxy.Create<TInterface>()
that returns you a type that implementsTInterface
. In this case, performance isn't the higher order and the only thing that matters is that the runtime supports generating code on the fly. Some environments, for example, iOS, disallow actual JITs. For that reason, the Xamarin team is considering providing an IL interpreter to make the scenarios work.The author of the mocking framework could just use reflection emit and rely on the implementation of it to throw
PlatformNotSupported
but a much better developer experience would be to check early & fail early with a descriptive error message. For example:Accelerating using
RuntimeFeature.IsDynamicCodeCompiled
In most cases, dynamically generating code is meant as a performance optimization. This
Similar areas include using expression trees to accelerate setting properties and calling constructors in IoC systems.
The text was updated successfully, but these errors were encountered: