-
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
Investigate getting rid of reflection blocking #72570
Comments
Looked at this briefly. The first thing we need to do is set the Once that's addressed, I see a 1.5% size regression for a small app. It's not too bad, but we can do better. A lot of it seems to be native layout related. We have things we can do there to make things better. We should do that first before tackling this. With IlcTrimMetadata=false, the regression is like 15%, so we definitely need that mode to stick. If we backtrack on that for whatever reason, this is not feasible. |
Fixes dotnet#68660. This is a piece of logic that originates from .NET Native. We didn't have a hard stance on `Activator.CreateInstance<T>` at that time, so we took a conservative approach of always generating the default constructors for all types that have type handle. Since we now do static analysis and warn if `Activator` is used with something we couldn't analyze. We can trim more. I would delete the whole table and logic, but I'm not sure if we can't still hit a problem when `CreateInstance<T>` is used with a reflection blocked type - this would affect private reflection within CoreLib (we don't think about reflection when doing `new T()`, so this can happen). With reflection blocking even if dataflow figures out that `BlockedFromReflectionType..ctor` should be reflectable, we won't reflection enable it. We really should just get rid of reflection blocking (dotnet#72570). Then all of this can go away.
Fixes #68660. This is a piece of logic that originates from .NET Native. We didn't have a hard stance on `Activator.CreateInstance<T>` at that time, so we took a conservative approach of always generating the default constructors for all types that have type handle. Since we now do static analysis and warn if `Activator` is used with something we couldn't analyze. We can trim more. I would delete the whole table and logic, but I'm not sure if we can't still hit a problem when `CreateInstance<T>` is used with a reflection blocked type - this would affect private reflection within CoreLib (we don't think about reflection when doing `new T()`, so this can happen). With reflection blocking even if dataflow figures out that `BlockedFromReflectionType..ctor` should be reflectable, we won't reflection enable it. We really should just get rid of reflection blocking (#72570). Then all of this can go away.
Fixes dotnet#72570. Still need to delete workarounds that make things public in corelib but maybe this diff is large enough already? We were gradually getting less and less from reflection blocking: * We stopped blocking things outside corelib (.NET Native blocked all of BCL; we don't). * We trim reflection metadata and that allows us to have method bodies without metadata. With this, we should be able to get type definition-level reflection metadata for any MethodTable there is in the system. This is a ~30 kB size regression for BasicMinimalApis. It is pretty much a wash for Hello World, because all the BCL cruft to handle reflection blocked types costs as much as the benefit of blocking.
Fixes #72570. Still need to delete workarounds that make things public in corelib but maybe this diff is large enough already? We were gradually getting less and less from reflection blocking: * We stopped blocking things outside corelib (.NET Native blocked all of BCL; we don't). * We trim reflection metadata and that allows us to have method bodies without metadata. With this, we should be able to get type definition-level reflection metadata for any MethodTable there is in the system. This is a ~30 kB size regression for BasicMinimalApis. It is pretty much a wash for Hello World, because all the BCL cruft to handle reflection blocked types costs as much as the benefit of blocking.
NativeAOT has a significant amount of the runtime written in C#. Keeping reflection metadata for it results in a lot of garbage being generated by the compiler since nobody is ever going to reflect on these things (and if they do, preventing that sounds like a good thing). We have a concept of reflection blocking for that that we inherited from .NET Native.
But now that IlcTrimMetadata=true is the default, there's little size incentive in keeping this - we should measure the impact. If it's not significant, we should stop doing reflection blocking.
We currently disable reflection blocking in the libs test because they do reflect on CoreLib's implementation details to test them. But it also means we're not running the tests in the configuration that the users will run. It could mask issues such as private reflection being done by the libraries themselves (not just by library tests).
The text was updated successfully, but these errors were encountered: