-
Notifications
You must be signed in to change notification settings - Fork 540
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
Avoid using br.s when generating managed UCO lookup tables #9969
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
I know it is not related to this PR, but should we also cleanup - remove these lines: android/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets Lines 349 to 351 in 4a8dd1e
As they are not relevant anymore? Line:
already sets AndroidEnableMarshalMethods=true for non-NativeAOT runtimes
|
grendello
approved these changes
Mar 26, 2025
@ivanpovazan that should definitely be changed. I think we should do it in a separate PR though. |
jonathanpeppers
pushed a commit
that referenced
this pull request
Mar 27, 2025
…9969) Context: 8d739f4 Context: #9962 Context: https://ecma-international.org/wp-content/uploads/ECMA-335_6th_edition_june_2012.pdf `ManagedMarshalMethodsLookupGenerator` (8d739f4) generates IL of a switch statement [^0] which looks like this: .method public hidebysig static native int '<JI>GetFunctionPointer' ( int32 methodIndex ) cil managed { // Method begins at RVA 0xac270 // Header size: 1 // Code size: 59 (0x3b) .maxstack 8 IL_0000: ldarg methodIndex IL_0004: switch (IL_001b, IL_0022, IL_0029, IL_0030) IL_0019: br.s IL_0037 IL_001b: ldftn void Android.App.Application::n_OnCreate_mm_wrapper(native int, native int) IL_0021: ret IL_0022: ldftn void Android.App.Application::n_OnLowMemory_mm_wrapper(native int, native int) IL_0028: ret IL_0029: ldftn void Android.App.Application::n_OnTrimMemory_I_mm_wrapper(native int, native int, int32) IL_002f: ret IL_0030: ldftn void Android.App.Application::n_OnConfigurationChanged_Landroid_content_res_Configuration__mm_wrapper(native int, native int, native int) IL_0036: ret IL_0037: nop IL_0038: ldc.i4.m1 IL_0039: conv.i IL_003a: ret } // end of method Application::'<JI>GetFunctionPointer' If the `switch` instruction doesn't jump to any of the target offsets, it continues on the next instruction. This instruction used to be a `br.s` [^1] which would jump over all the individual cases to the default case. When the switch gets too large (19 cases), the `br.s` becomes insufficient, as the offset for `br.s` is a signed 8-bit value. The code can be simplified by removing the branching operation completely and simply return from the default case. The newly generated code will look like this: .method public hidebysig static native int '<JI>GetFunctionPointer' ( int32 methodIndex ) cil managed { // Method begins at RVA 0xac1a8 // Header size: 1 // Code size: 56 (0x38) .maxstack 8 IL_0000: ldarg methodIndex IL_0004: switch (IL_001c, IL_0023, IL_002a, IL_0031) IL_0019: ldc.i4.m1 IL_001a: conv.i IL_001b: ret IL_001c: ldftn void Android.App.Application::n_OnCreate_mm_wrapper(native int, native int) IL_0022: ret IL_0023: ldftn void Android.App.Application::n_OnLowMemory_mm_wrapper(native int, native int) IL_0029: ret IL_002a: ldftn void Android.App.Application::n_OnTrimMemory_I_mm_wrapper(native int, native int, int32) IL_0030: ret IL_0031: ldftn void Android.App.Application::n_OnConfigurationChanged_Landroid_content_res_Configuration__mm_wrapper(native int, native int, native int) IL_0037: ret } // end of method Application::'<JI>GetFunctionPointer' [^0]: IL `switch` is in ECMA-335 §III.3.66, page 392 (page numbers) or page 418 (Go to page…) [^1]: IL `br.s` is in ECMA-335 §III.3.15, page 338 (page numbers) or page 364 (Go to page…)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Contributes to #9962
The
ManagedMarshalMethodsLookupGenerator
generates IL of a switch statement which looks like this:If the
switch
instruction doesn't jump to any of the target offsets, it continues on the next instruction. This instruction used to be abr.s
which would jump over all the individual cases to the default case. When the switch got too large (19 cases), thebr.s
became insufficient (the offset forbr.s
is a signed 8-bit number).The code can be simplified by removing the branching operation completely and simply return from the default case. The newly generated code will look like this: