[interp] avoid exception checkpoint when in thread is in GC Safe state
Usually the interpreter operates in GC Unsafe state. There is an exception however, and that is when it executes a `managed-to-native` wrapper in cooperative (or hybrid) suspend.
The wrapper does essentially:
1. enter GC Safe state via `mono_threads_enter_gc_safe_region_unbalanced`
2. call native function
3. exit GC state via `mono_threads_exit_gc_safe_region_unbalanced`
Usually upon return of a native function call, the interpreter would check for thread interruption and, if applicable, throw an exception. That, however, would mess with the GC state as the interpreter operates in GC Safe state at this moment.
Note that ignoring thread interruption at that point shouldn't be a problem, because after 3. the `managed-to-native` wrapper will check for thread interruption anyway.
Contributes to https://github.com/mono/mono/issues/16819
Commit migrated from https://github.com/mono/mono/commit/
e27159174a017efb3ebc66c9c66fc1785c4bd930
frame->ip = ip;
sp = do_icall_wrapper (frame, csignature, opcode, sp, target_ip, save_last_error);
- EXCEPTION_CHECKPOINT;
+ if (mono_thread_is_gc_unsafe_mode ()) /* do not enter EH in GC Safe state */
+ EXCEPTION_CHECKPOINT;
CHECK_RESUME_STATE (context);
ip += 4;
MINT_IN_BREAK;
MINT_IN_CASE(MINT_ICALL_PPPPPP_P)
frame->ip = ip;
sp = do_icall_wrapper (frame, NULL, *ip, sp, frame->imethod->data_items [ip [1]], FALSE);
- EXCEPTION_CHECKPOINT;
+ if (mono_thread_is_gc_unsafe_mode ()) /* do not enter EH in GC Safe state */
+ EXCEPTION_CHECKPOINT;
CHECK_RESUME_STATE (context);
ip += 2;
MINT_IN_BREAK;