-
Notifications
You must be signed in to change notification settings - Fork 564
[Mono.Android] remove System.Reflection usage in UncaughtExceptionHandler #3991
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
[Mono.Android] remove System.Reflection usage in UncaughtExceptionHandler #3991
Conversation
…dler Context: https://github.com/mono/mono/blob/42c5ccc298c9b1b5f78781f5db4dab51ebacb522/mcs/class/corlib/Assembly/AssemblyInfo.cs#L84-L93 If we lived in a world where `mscorlib.dll` has `InternalsVisibleTo` for `Mono.Android`, we can remove some System.Reflection that gets called on startup. We need to be able to call these methods directly: * `System.Diagnostics.Debugger.Mono_UnhandledException` * `AppDomain.CurrentDomain.DoUnhandledException` The only other change is that some files need: using LogLevel = Android.Runtime.LogLevel; There is an `internal` `System.LogLevel` that we need to disambiguate. NOTE: this won't fully work until the change in Mono lands. ~~ Results ~~ I tested the Xamarin.Forms integration project, using a Debug build on a HAXM x86 emulator on Windows. The reason I looked into this, is I initially saw a log message like: 12-03 14:28:11.969 27129 27129 I monodroid-timing: Runtime.register: registered type 'Android.Runtime.UncaughtExceptionHandler, Mono.Android' 12-03 14:28:11.969 27129 27129 I monodroid-timing: Runtime.register: end time; elapsed: 0s:79::609300 After the change, it is more like: 12-04 09:13:32.944 9758 9758 I monodroid-timing: Runtime.register: registered type 'Android.Runtime.UncaughtExceptionHandler, Mono.Android' 12-04 09:13:32.944 9758 9758 I monodroid-timing: Runtime.register: end time; elapsed: 0s:73::727800 However, if I look at the total `Runtime.init` time: Before: 12-03 14:27:48.494 26903 26903 I monodroid-timing: Runtime.init: end, total time; elapsed: 0s:601::443900 12-03 14:27:54.356 26963 26963 I monodroid-timing: Runtime.init: end, total time; elapsed: 0s:587::495400 12-03 14:28:00.263 27021 27021 I monodroid-timing: Runtime.init: end, total time; elapsed: 0s:586::147100 12-03 14:28:06.135 27074 27074 I monodroid-timing: Runtime.init: end, total time; elapsed: 0s:593::639100 12-03 14:28:11.988 27129 27129 I monodroid-timing: Runtime.init: end, total time; elapsed: 0s:571::194900 After: 12-04 09:13:15.386 9587 9587 I monodroid-timing: Runtime.init: end, total time; elapsed: 0s:584::909700 12-04 09:13:21.179 9644 9644 I monodroid-timing: Runtime.init: end, total time; elapsed: 0s:506::64600 12-04 09:13:27.148 9699 9699 I monodroid-timing: Runtime.init: end, total time; elapsed: 0s:560::98500 12-04 09:13:32.963 9758 9758 I monodroid-timing: Runtime.init: end, total time; elapsed: 0s:504::939400 12-04 09:13:38.887 9814 9814 I monodroid-timing: Runtime.init: end, total time; elapsed: 0s:531::234100 And then the total activity time: Before: 12-03 14:27:51.450 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s727ms 12-03 14:27:57.310 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s723ms 12-03 14:28:03.216 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s703ms 12-03 14:28:09.054 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s679ms 12-03 14:28:14.953 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s711ms After: 12-04 09:13:18.248 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s608ms 12-04 09:13:24.087 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s570ms 12-04 09:13:29.997 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s566ms 12-04 09:13:35.805 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s498ms 12-04 09:13:41.670 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s475ms It seems like this might be saving us as much as ~250ms to the total startup on a HAXM emulator in Debug mode?
Context: dotnet/android#3991 In Xamarin.Android, we have a bit of System.Reflection usage on startup: https://github.com/xamarin/xamarin-android/blob/bbbe2ed36e6eeb7cce0905dcbfdaeaa30754070f/src/Mono.Android/Android.Runtime/UncaughtExceptionHandler.cs#L47-L67 These methods are in `mscorlib.dll` and `internal`. If we had `[assembly: InternalsVisibleTo ("Mono.Android")]` we could avoid the System.Reflection. This is already done for `Xamarin.iOS`, `Xamarin.Mac`, etc. so hopefully it's OK to add one more? We could then, just call these methods directly: * `System.Diagnostics.Debugger.Mono_UnhandledException` * `AppDomain.CurrentDomain.DoUnhandledException` The results are possibly a 100-250ms improvement to startup: Before: 12-03 14:27:51.450 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s727ms 12-03 14:27:57.310 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s723ms 12-03 14:28:03.216 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s703ms 12-03 14:28:09.054 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s679ms 12-03 14:28:14.953 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s711ms After: 12-04 09:13:18.248 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s608ms 12-04 09:13:24.087 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s570ms 12-04 09:13:29.997 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s566ms 12-04 09:13:35.805 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s498ms 12-04 09:13:41.670 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s475ms This was the Xamarin.Forms integration project in xamarin-android. Running a `Debug` build on a HAXM x86 emulator on Windows. https://github.com/xamarin/xamarin-android/tree/master/tests/Xamarin.Forms-Performance-Integration
* [corlib] add InternalsVisibleTo for Mono.Android Context: dotnet/android#3991 In Xamarin.Android, we have a bit of System.Reflection usage on startup: https://github.com/xamarin/xamarin-android/blob/bbbe2ed36e6eeb7cce0905dcbfdaeaa30754070f/src/Mono.Android/Android.Runtime/UncaughtExceptionHandler.cs#L47-L67 These methods are in `mscorlib.dll` and `internal`. If we had `[assembly: InternalsVisibleTo ("Mono.Android")]` we could avoid the System.Reflection. This is already done for `Xamarin.iOS`, `Xamarin.Mac`, etc. so hopefully it's OK to add one more? We could then, just call these methods directly: * `System.Diagnostics.Debugger.Mono_UnhandledException` * `AppDomain.CurrentDomain.DoUnhandledException` The results are possibly a 100-250ms improvement to startup: Before: 12-03 14:27:51.450 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s727ms 12-03 14:27:57.310 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s723ms 12-03 14:28:03.216 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s703ms 12-03 14:28:09.054 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s679ms 12-03 14:28:14.953 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s711ms After: 12-04 09:13:18.248 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s608ms 12-04 09:13:24.087 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s570ms 12-04 09:13:29.997 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s566ms 12-04 09:13:35.805 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s498ms 12-04 09:13:41.670 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s475ms This was the Xamarin.Forms integration project in xamarin-android. Running a `Debug` build on a HAXM x86 emulator on Windows. https://github.com/xamarin/xamarin-android/tree/master/tests/Xamarin.Forms-Performance-Integration * Bump API snapshot submodule
Context: dotnet/android#3991 In Xamarin.Android, we have a bit of System.Reflection usage on startup: https://github.com/xamarin/xamarin-android/blob/bbbe2ed36e6eeb7cce0905dcbfdaeaa30754070f/src/Mono.Android/Android.Runtime/UncaughtExceptionHandler.cs#L47-L67 These methods are in `mscorlib.dll` and `internal`. If we had `[assembly: InternalsVisibleTo ("Mono.Android")]` we could avoid the System.Reflection. This is already done for `Xamarin.iOS`, `Xamarin.Mac`, etc. so hopefully it's OK to add one more? We could then, just call these methods directly: * `System.Diagnostics.Debugger.Mono_UnhandledException` * `AppDomain.CurrentDomain.DoUnhandledException` The results are possibly a 100-250ms improvement to startup: Before: 12-03 14:27:51.450 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s727ms 12-03 14:27:57.310 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s723ms 12-03 14:28:03.216 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s703ms 12-03 14:28:09.054 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s679ms 12-03 14:28:14.953 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s711ms After: 12-04 09:13:18.248 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s608ms 12-04 09:13:24.087 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s570ms 12-04 09:13:29.997 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s566ms 12-04 09:13:35.805 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s498ms 12-04 09:13:41.670 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s475ms This was the Xamarin.Forms integration project in xamarin-android. Running a `Debug` build on a HAXM x86 emulator on Windows. https://github.com/xamarin/xamarin-android/tree/master/tests/Xamarin.Forms-Performance-Integration
* [corlib] add InternalsVisibleTo for Mono.Android Context: dotnet/android#3991 In Xamarin.Android, we have a bit of System.Reflection usage on startup: https://github.com/xamarin/xamarin-android/blob/bbbe2ed36e6eeb7cce0905dcbfdaeaa30754070f/src/Mono.Android/Android.Runtime/UncaughtExceptionHandler.cs#L47-L67 These methods are in `mscorlib.dll` and `internal`. If we had `[assembly: InternalsVisibleTo ("Mono.Android")]` we could avoid the System.Reflection. This is already done for `Xamarin.iOS`, `Xamarin.Mac`, etc. so hopefully it's OK to add one more? We could then, just call these methods directly: * `System.Diagnostics.Debugger.Mono_UnhandledException` * `AppDomain.CurrentDomain.DoUnhandledException` The results are possibly a 100-250ms improvement to startup: Before: 12-03 14:27:51.450 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s727ms 12-03 14:27:57.310 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s723ms 12-03 14:28:03.216 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s703ms 12-03 14:28:09.054 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s679ms 12-03 14:28:14.953 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s711ms After: 12-04 09:13:18.248 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s608ms 12-04 09:13:24.087 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s570ms 12-04 09:13:29.997 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s566ms 12-04 09:13:35.805 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s498ms 12-04 09:13:41.670 1876 1898 I ActivityManager: Displayed Xamarin.Forms_Performance_Integration/xamarin.forms.performance.integration.MainActivity: +3s475ms This was the Xamarin.Forms integration project in xamarin-android. Running a `Debug` build on a HAXM x86 emulator on Windows. https://github.com/xamarin/xamarin-android/tree/master/tests/Xamarin.Forms-Performance-Integration * Bump API snapshot submodule
We may be able to live in such a world in the short-term (d16-6) timeframe. I'm dubious about us continuing to live in such a world in the .NET 5 timeframe. It's entirely plausible that in .NET 5 "everybody" will be using the same assemblies, and those assemblies might not have It's thus potentially dubious. Furthermore, the Reflection usage only occurs when there's an actual unhandled exception, when |
I am now wondering how I saw a speedup. I ran a script to time this, but I wonder if I could have messed something up? The change landed in mono-2019-12, so I can retest when we are on it.
This came up here: mono/mono#18040 (comment) My thought was a build-time error would be better than a runtime error (and only on unhandled exception!). It could slightly help us migrate to .NET 5. |
|
Closing in favor of: #4302 |
Context: https://github.com/mono/mono/blob/42c5ccc298c9b1b5f78781f5db4dab51ebacb522/mcs/class/corlib/Assembly/AssemblyInfo.cs#L84-L93
If we lived in a world where
mscorlib.dllhasInternalsVisibleTofor
Mono.Android, we can remove some System.Reflection that getscalled on startup.
We need to be able to call these methods directly:
System.Diagnostics.Debugger.Mono_UnhandledExceptionAppDomain.CurrentDomain.DoUnhandledExceptionThe only other change is that some files need:
There is an
internalSystem.LogLevelthat we need to disambiguate.NOTE: this won't fully work until the change in Mono lands.
Results
I tested the Xamarin.Forms integration project, using a Debug build on
a HAXM x86 emulator on Windows.
The reason I looked into this, is I initially saw a log message like:
After the change, it is more like:
However, if I look at the total
Runtime.inittime:And then the total activity time:
It seems like this might be saving us as much as ~250ms to the total
startup on a HAXM emulator in Debug mode?