dotnet / dotnet/macios

Improve the native-managed transitions in the trimmable static registrar

Open
#26,077 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
C#
Stars
2.9k
Forks
576
Avg merge
2d 13h
Merged PRs (30d)
96

Description

This is a rather vague issue, and mostly a collection of my thoughts.

The current goal is to end up with two (and a half?) registrars:

* The dynamic registrar (for fast builds).
* The trimmable static registrar (for small apps).
* Potentially also a mix of these two (a partial static registrar mode, where parts of the trimmable static registrar output is precomputed).

This means that we'll be able to remove the current (managed) static registrar code. Note that there's a lot of code reuse between the registrars, so there's a lot of code from the (managed) static registrars that can't be removed because it's used by the trimmable static registrar.

Additionally we're removing the MonoVM runtime, and we'll only use CoreCLR+NativeAOT. This means we can remove any mono-specific code, but most importantly it means it'll be easier to improve the native-managed transitions in the CoreCLR support code (`coreclr-bridge.m`). This code was written to be as compatible as possible with the existing mono-specific code, basically imitating the mono embedding API. As such it's not nearly as performant as it could be (at the time - in the .NET 5 time frame - maintainability was more important).

The current native-managed transitions for the dynamic registrar:

* The entry point is written in assembly code, where we collect all the registers and then call a generic C method.
* This C method (`xamarin_invoke_trampoline`) will process all the register/stack inputs, and set everything up to transition into managed code.

It would be worth exploring moving this entire C method into managed code.

The current native-managed transitions for the trimmable static registrar:

* We generate Objective-C code that will do a lot of the processing before calling into managed code.

It would be worth exploring moving most of this processing into managed code as well. Technically it's likely possible to call managed code directly from the Objective-C class (the actual method implementation for each selector is the managed `[UnmanagedCallersOnly]` method), but this would probably require us to generate native assembly code and not Objective-C code.

The end result is that most of the processing that is currently done in native code will move to managed code. In some cases it might be beneficial to implement helper methods in native code so that we do chunky stuff and not chatty stuff (the canonical example being converting a native NSArray into a managed array - we don't want to call from managed to native for every element in the array).

One of the benefits of moving more code to managed is that the code will be visible to trimmers. In particular I believe the current `PreserveSmartEnumConversionsStep` code would not be needed, because the trimmers would see everything (there's likely other examples as well).

Preconditions to start working on this issue:

* [ ] Remove any Mono-related code from runtime/.
* [ ] Remove support for the managed-static-registrar and static-registrar modes (not necessarily the code itself, that's a simplification that can be done together with this work whenever it makes sense).

Other thoughts:
* To make it easier to make performance measurements, it might be a good idea to keep the old code and make it opt-in/opt-out (based on an MSBuild property), so that we can test both. This would also work as a fallback in case the new code is buggy and we can direct people to use the old code temporarily.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by reading runtime/coreclr-bridge.m and tracing xamarin_invoke_trampoline for the dynamic registrar, then inspect the generated Objective-C path for the trimmable static registrar. Review PreserveSmartEnumConversionsStep and the listed Mono and registrar-mode prerequisites. Done means a measured, working transition toward managed processing with the obsolete modes and Mono-related runtime code addressed.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp, objective-c
Domain
performance, tooling
Issue type
Refactor
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.