Commit 2aff4e7
authored
[Mono.Android] Reduce Reflection & reduce startup overhead (#4302)
Reduce or remove reflection use around JNI method registration, and
rework how uncaught exceptions are handled.
Java.Interop provides an alternate mechanism to allow registering
Java native methods:
[the `[JniAddNativeMethodRegistrationAttribute]` custom attribute][0]
which can be placed on methods of a type to allow "manual"
insertion into the [`JNIEnv::RegisterNatives()`][2] process.
The `Java.Interop-Tests.dll` unit test assembly (130905e) uses this
alternate native method registration mechanism..
Unfortunately, `[JniAddNativeMethodRegistration]` is looked up via
Reflection, which isn't exactly "fast".
Given that `[JniAddNativeMethodRegistration]` is only used by one
assembly *in the world*, let's optimize the common case:
[dotnet/java-interop@b33d183d][3] made the
`[JniAddNativeMethodRegistration]` lookup *optional*. Disable the
custom attribute lookup *by default*, and allow it to be enabled by
setting the `$(_SkipJniAddNativeMethodRegistrationAttributeScan)`
MSBuild property to True. Yes, this property is "private". We'll
investigate more automatic and optimized ideas in the future.
Rework how Java-side unhandled exceptions are processed. Previously,
this was handled by the `Android.Runtime.UncaughtExceptionHandler`
class, which was constructed during process startup. A side effect
of this is that it required going through the (*normal* reflection-
based) JNI registration logic of `mono.android.Runtime.register()`,
contributing to startup for something that *ideally* would
Never Happen™. (Nobody likes unhandled exceptions.)
Changes this so that instead of a C#-side `UncaughtExceptionHandler`
type we instead have a Java-side
`mono.android.XamarinUncaughtExceptionHandler` type which is
created and provided to
`java.lang.Thread.setDefaultUncaughtExceptionHandler()` during
startup. `XamarinUncaughtExceptionHandler` doesn't do anything until
Java calls `XamarinUncaughtExceptionHandler.uncaughtException()`,
which in turn invokes `Runtime.propagateUncaughtException()`, which
in turn does what `UncaughtExceptionHandler` previously did: lookup
`AppDomain.DoUnhandledException()` via Reflection and invoke it, thus
raising the `AppDomain.UnhandledException` event.
In this manner all overheads associated with unhandled exceptions are
delayed until the exception happens, with minimal impact on startup.
Gains in startup time are quite nice:
* Device name: **Pixel 3 XL**
* Device architecture: **arm64-v8a**
* Number of test runs: **10**
* Test application: **Xamarin.Forms integration test**
| | **Native to managed** | **Runtime init** | **Displayed** | **Notes** |
|-----------------|------------------------|------------------|---------------|--------------------------------|
| **master** | 131.278 | 149.074 | 789.10 | preload enabled; 32-bit build |
| **this commit** | 49.446 | 66.989 | 764.30 | |
| **master** | 132.315 | 147.187 | 795.60 | preload disabled; 32-bit build |
| **this commit** | 48.876 | 63.822 | 754.30 | |
| **master** | 121.544 | 137.736 | 728.20 | preload enabled; 64-bit build |
| **this commit** | 45.350 | 61.464 | 699.50 | |
| **master** | 123.448 | 137.052 | 727.40 | preload disabled; 64-bit build |
| **this commit** | 44.765 | 58.047 | 689.00 | |
* Device name: **Pixel 3 XL**
* Device architecture: **arm64-v8a**
* Number of test runs: **10**
* Test application: Xamarin.Forms "Hello World" app with one label
| | **Native to managed** | **Runtime init** | **Displayed** | **Notes** |
|-----------------|------------------------|------------------|---------------|--------------------------------|
| **master** | 122.090 | 142.004 | 639.00 | preload enabled; 32-bit build |
| **this commit** | 44.370 | 63.803 | 586.10 | |
| **master** | 121.110 | 134.378 | 634.20 | preload disabled; 32-bit build |
| **this commit** | 45.085 | 57.992 | 580.40 | |
| **master** | 120.973 | 141.235 | 637.20 | preload enabled; 64-bit build |
| **this commit** | 44.767 | 63.846 | 578.50 | |
| **master** | 120.785 | 134.588 | 627.00 | preload disabled; 64-bit build |
| **this commit** | 44.859 | 57.590 | 575.40 | |
[0]: dotnet/java-interop@7d51163
[2]: https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#RegisterNatives
[3]: dotnet/java-interop@b33d1831 parent ad5af12 commit 2aff4e7
File tree
23 files changed
+179
-110
lines changed- Documentation/release-notes
- src
- Mono.Android
- Android.Runtime
- Java.Interop
- Test
- Xamarin.Android.Build.Tasks
- Tasks
- Tests/Xamarin.Android.Build.Tests
- Utilities
- Utilities
- java-runtime/java/mono/android
- monodroid/jni
- tests
- Runtime-AppBundle
- Runtime-MultiDex
23 files changed
+179
-110
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
15 | 15 | | |
16 | 16 | | |
17 | 17 | | |
18 | | - | |
19 | | - | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
20 | 30 | | |
21 | 31 | | |
22 | 32 | | |
| |||
67 | 77 | | |
68 | 78 | | |
69 | 79 | | |
70 | | - | |
71 | | - | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
72 | 86 | | |
73 | 87 | | |
74 | 88 | | |
75 | 89 | | |
76 | 90 | | |
77 | 91 | | |
78 | 92 | | |
79 | | - | |
| 93 | + | |
80 | 94 | | |
81 | 95 | | |
| 96 | + | |
82 | 97 | | |
83 | 98 | | |
84 | 99 | | |
| |||
219 | 234 | | |
220 | 235 | | |
221 | 236 | | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
222 | 243 | | |
223 | 244 | | |
224 | 245 | | |
| |||
347 | 368 | | |
348 | 369 | | |
349 | 370 | | |
350 | | - | |
| 371 | + | |
| 372 | + | |
351 | 373 | | |
352 | 374 | | |
353 | 375 | | |
354 | 376 | | |
355 | 377 | | |
356 | | - | |
| 378 | + | |
| 379 | + | |
357 | 380 | | |
358 | 381 | | |
359 | 382 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
33 | 33 | | |
34 | 34 | | |
35 | 35 | | |
| 36 | + | |
36 | 37 | | |
37 | 38 | | |
38 | 39 | | |
| |||
54 | 55 | | |
55 | 56 | | |
56 | 57 | | |
57 | | - | |
58 | 58 | | |
59 | 59 | | |
60 | 60 | | |
| |||
173 | 173 | | |
174 | 174 | | |
175 | 175 | | |
176 | | - | |
| 176 | + | |
177 | 177 | | |
178 | 178 | | |
179 | 179 | | |
| |||
183 | 183 | | |
184 | 184 | | |
185 | 185 | | |
186 | | - | |
187 | | - | |
188 | | - | |
189 | | - | |
190 | | - | |
191 | | - | |
192 | 186 | | |
193 | 187 | | |
194 | 188 | | |
| |||
204 | 198 | | |
205 | 199 | | |
206 | 200 | | |
207 | | - | |
208 | | - | |
209 | | - | |
210 | | - | |
211 | | - | |
212 | | - | |
213 | | - | |
214 | 201 | | |
215 | 202 | | |
216 | 203 | | |
| |||
249 | 236 | | |
250 | 237 | | |
251 | 238 | | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
252 | 264 | | |
253 | 265 | | |
254 | | - | |
| 266 | + | |
255 | 267 | | |
256 | 268 | | |
257 | | - | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
258 | 275 | | |
259 | 276 | | |
260 | | - | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
261 | 292 | | |
262 | 293 | | |
263 | 294 | | |
| |||
Lines changed: 0 additions & 69 deletions
This file was deleted.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
10 | | - | |
| 10 | + | |
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
| |||
73 | 73 | | |
74 | 74 | | |
75 | 75 | | |
76 | | - | |
| 76 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
23 | 23 | | |
24 | 24 | | |
25 | 25 | | |
26 | | - | |
| 26 | + | |
27 | 27 | | |
28 | 28 | | |
29 | 29 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
234 | 234 | | |
235 | 235 | | |
236 | 236 | | |
237 | | - | |
238 | 237 | | |
239 | 238 | | |
240 | 239 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
| 25 | + | |
25 | 26 | | |
26 | 27 | | |
27 | 28 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
77 | 77 | | |
78 | 78 | | |
79 | 79 | | |
| 80 | + | |
| 81 | + | |
80 | 82 | | |
81 | 83 | | |
82 | 84 | | |
| |||
400 | 402 | | |
401 | 403 | | |
402 | 404 | | |
403 | | - | |
| 405 | + | |
404 | 406 | | |
405 | 407 | | |
| 408 | + | |
406 | 409 | | |
407 | 410 | | |
408 | 411 | | |
Lines changed: 2 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
249 | 249 | | |
250 | 250 | | |
251 | 251 | | |
| 252 | + | |
252 | 253 | | |
253 | 254 | | |
254 | 255 | | |
| |||
285 | 286 | | |
286 | 287 | | |
287 | 288 | | |
| 289 | + | |
288 | 290 | | |
289 | 291 | | |
290 | 292 | | |
| |||
0 commit comments