-
Notifications
You must be signed in to change notification settings - Fork 206
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
ResourceManager not working in reflection-free mode #1327
Comments
Reflection free mode doesn't have access to manifest resources, so there's no chance of it working. We disable framework resource strings in reflection free mode, which is how it works for framework code: runtimelab/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets Line 45 in b4c3760
Non-framework code will have to define feature switches like framework code does. I don't have high hopes of resource manager working in reflection free mode ever (even if we add type-level reflection and manifest resources). Resource manager reads custom attributes and that's just full unavoidable reflection. |
@MichalStrehovsky Can I speculate about that one issue a bit more. Issue which I hit was when loading satellite assemblies. Let's say we have WinForms application without localization, but who use resources. All I want for reflection-free method is that it assumes that no satellite assemblies present (as current limitation) and just go and continue working as usual. Then next location were I expect issues would be Anyway, let me ask, is it possible to disable this codepath entirely using new Do you aware about any work/plans/experiments to have AOT-friendly resources management? Xamarin/MAUI seems to be solved that by using just only string resources in RESX files. |
There's a difference between AOT friendly and reflection-free-mode friendly. I don't think there's going to be a concentrated effort for reflection-free-friendly anytime soon. We can make it so that the reflection-free-mode can say "there are no custom attributes on anything" (instead of throwing), but that's the extent of it. The current reflection free mode is very restrictive and I don't think we should invest in it much further. We need to replace System.Private.DisabledReflection with the real reflection stack that has certain codepaths stubbed out so that this effort is sustainable. S.P.DisabledReflection is a tech demo more than anything else. |
I'm more then happy with opt-out mode, and reflection-free is not a goal in itself. I use it just to push some things to extreme. For example currently it drop size of WinForms app from 33Mb to 13Mb, which I believe interesting property. So I continue flying like a sparrow, chipping here and there. Thanks for your support. |
Make sure to enable trimming for WinForms .dlls. I suspect that this large drop is caused by reflection-free mode enabling trimming for WinForms .dlls as a side-effect. You should be able to get most of it by just enabling trimming for WinForms .dlls. |
I start with following setup in project file
Then once I see your comment I start playing around and add following
And only Reflection-Free mode drop size by 20Mb. Am I miss some other flag which I should turn on? |
It's easiest to see by investigating the RSP file passed to the compiler with one and the other project settings. If you see any |
That's patch between RSP files. Reflection - 33Mb, No Reflection -13Mb. 224d223
< -r:packages\runtime.win-x64.microsoft.dotnet.ilcompiler\6.0.0-rc.1.21370.1\sdk\System.Private.Reflection.Core.dll
234d232
< --initassembly:System.Private.StackTraceMetadata
236c234
< --initassembly:System.Private.Reflection.Execution
---
> --initassembly:System.Private.DisabledReflection
238a237,239
> --appcontextswitch:Switch.System.Reflection.Assembly.SimulatedLocationInBaseDirectory=true
> --appcontextswitch:Switch.System.Reflection.Disabled.DoNotThrowForNames=true
> --appcontextswitch:Switch.System.Reflection.Disabled.DoNotThrowForAssembly=true
239a241
> --appcontextswitch:System.Diagnostics.Tracing.EventSource.IsSupported=false
241a244
> --appcontextswitch:System.Resources.UseSystemResourceKeys=true
251a255
> --feature:System.Diagnostics.Tracing.EventSource.IsSupported=false
253a258
> --feature:System.Resources.UseSystemResourceKeys=true
261d265
< --scanreflection
263a268,269
> --disablereflection
> --feature:System.Collections.Generic.DefaultComparers=false Only one
|
Interesting. I'll have to see what's going on. Such big size diff is not expected. No reflection 13 MB, and with reflection ~19 MB would be more in line with my expectations. |
Maybe you can re-open? It seems to be it can be fruitful in some sense. |
The specific line of ResourceManager will work when dotnet/runtime#67193 is done because we will have metadata about assemblies and types. Maybe at that time we can revisit making it work with reflection-free mode, but as of now it's beyond saving. |
I'm interesting more in your findings about size. More-usable reflection-free mode is more then fine for me. If I want it to work, some leg work on me. |
Now that I can use PerfView I compare two applications Reflection 33MbReflection-free 13MbFirst two lines in |
The PerfView view might be assuming .NET Native name mangling and such.
The size of the metadata blob is better visible in the *.map file generated by ILCompiler. You can decrease the size of the metadata blob by adding Also, is there a difference in stack trace data setting between no-reflection and reflection? I see that |
So still something left which takes 13Mb. When I compare using |
Ah, the embedded resources are pretty big at 6.6 MB. The bad news is that these are the thing ResourceManager reads, so the fact we're stripping them is currently breaking the app, but we don't know that because the reflection that gets to that data is broken in the first place. The only reason why we can strip it right now is that in reflection-free mode there's no API to get to that data. Reflection-free size will grow by at least 6.6 MB once we fix that. Then you're looking at a size difference of 19.6 MB (13 MB + 6.6 MB) vs 26 MB and that difference doesn't look so terrible. Basically once we do dotnet/runtime#67193, size of the WinForms app will be somewhere between 19.6 and 26 MB. |
Thanks, at least now it make sense that reflection-free is not a free lunch. |
It might be worthwhile to look into the 6.6 MB of data though - I assume this is all from Windows.Forms, not from BCL. We drop pretty much all resources from the BCL when I assume some of the resources in Windows.Forms are resource strings for exception messages - we could drop them with similar annotations. But 6.6 MB is a lot to be just the exception messages - it's possible there's more stuff, but because of the nature of resources, none of it can be trimmed even if it's unused. |
I have easier target to trim WinForms app. If I make a switch to |
I try to run simplest reading from resources using codegen from Resx files.
With this configuration
It fails at this line
runtimelab/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Resources/ManifestBasedResourceGroveler.CoreRT.cs
Line 21 in b4c3760
with
NotImplementedException
.My massage skills fails at this point.
The text was updated successfully, but these errors were encountered: