[marshal] Emit GC Safe transitions around foreign internal calls. (#11183)
* [threads] Make mono_add_internal_call external only
The runtime should use mono_add_internal_call_internal or
mono_add_internal_call_with_flags.
The thread suspend mechanism needs to know if an icall is added via the legacy
mono_add_internal_call API (which is not coop-aware, and so the registered
icalls must run in GC Safe mode), or if it is added by the runtime or by a
cooperative client (currently either the profiler or the System.Native PAL)
which knows to add GC transitions and safepoints and not to block indefinitely.
* [marshal] Factor out GCSafeTransitionBuilder
Make a local builder for creating the GC Safe transition calls for a method wraper.
* [sgen] Add coop GC transitions in mono_gc_toggleref_add
Also mark it external only. It's not used inside the runtime.
* [marshal] Emit GC Safe transitions around foreign icalls.
A foreign icall is added using mono_add_internal_call and that is not coop GC
aware. (The runtime uses mono_add_internal_call_with_flags or
mono_add_internal_call_internal)
Under hybrid suspend, foreign icalls will run in GC Safe mode and transition to
GC Unsafe only when the call back into the runtime or invoke managed code.
Fixes https://github.com/mono/mono/issues/11138
* [cxx] function type overloads for mono_add_internal_call_internal
and mono_add_internal_call_with_flags
* [runtime] Add new API call mono_dangerous_add_raw_internal_call
Under hybrid suspend, this adds an icall that is assumed to run in GC Unsafe
mode. As such it has additional requirements for correct operation: it must
not run loops without periodically polling the runtime, and it must not perform
blocking operations such as blocking I/O or taking locks without manually
switching to GC Safe mode.
13 files changed: