mono_magic_trampoline (mgreg_t *regs, guint8 *code, gpointer arg, guint8* tramp)
{
gpointer res;
+ MonoError error;
- MONO_ENTER_GC_UNSAFE_UNBALANCED;
+ MONO_REQ_GC_UNSAFE_MODE;
- MonoError error;
+ g_assert (mono_thread_is_gc_unsafe_mode ());
trampoline_calls ++;
res = common_call_trampoline (regs, code, (MonoMethod *)arg, NULL, NULL, &error);
- mono_error_set_pending_exception (&error);
-
- mono_interruption_checkpoint_from_trampoline ();
-
- MONO_EXIT_GC_UNSAFE_UNBALANCED;
+ if (!is_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
return res;
}
{
return state_name (state);
}
+
+gboolean
+mono_thread_is_gc_unsafe_mode (void)
+{
+ MonoThreadInfo *cur = mono_thread_info_current ();
+
+ if (!cur)
+ return FALSE;
+
+ switch (mono_thread_info_current_state (cur)) {
+ case STATE_RUNNING:
+ case STATE_ASYNC_SUSPEND_REQUESTED:
+ case STATE_SELF_SUSPEND_REQUESTED:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
int mono_thread_info_suspend_count (THREAD_INFO_TYPE *info);
int mono_thread_info_current_state (THREAD_INFO_TYPE *info);
const char* mono_thread_state_name (int state);
+gboolean mono_thread_is_gc_unsafe_mode (void);
gboolean mono_thread_info_in_critical_location (THREAD_INFO_TYPE *info);
gboolean mono_thread_info_begin_suspend (THREAD_INFO_TYPE *info);