Merge pull request #3040 from xmcclure/debugger-step-recursive
[mono.git] / mono / mini / mini-runtime.c
index a887fc67fe35a0cf3a1b54504398be23050603b6..6f4082905c5687bf4679fffe2550815663475880 100644 (file)
@@ -63,6 +63,7 @@
 #include <mono/utils/dtrace.h>
 #include <mono/utils/mono-signal-handler.h>
 #include <mono/utils/mono-threads.h>
+#include <mono/utils/mono-threads-coop.h>
 #include <mono/utils/checked-build.h>
 #include <mono/io-layer/io-layer.h>
 
@@ -837,20 +838,20 @@ mono_set_lmf_addr (gpointer lmf_addr)
 }
 
 /*
- * mono_jit_thread_attach: called by native->managed wrappers
+ * mono_jit_thread_attach:
  *
- * In non-coop mode:
- *  - @dummy: is NULL
- *  - @return: the original domain which needs to be restored, or NULL.
+ * Called by Xamarin.Mac and other products. Attach thread to runtime if
+ * needed and switch to @domain.
  *
- * In coop mode:
- *  - @dummy: contains the original domain
- *  - @return: a cookie containing current MonoThreadInfo*.
+ * @return the original domain which needs to be restored, or NULL.
  */
-gpointer
-mono_jit_thread_attach (MonoDomain *domain, gpointer *dummy)
+MonoDomain*
+mono_jit_thread_attach (MonoDomain *domain)
 {
        MonoDomain *orig;
+       gboolean attached;
+
+       g_assert (!mono_threads_is_coop_enabled ());
 
        if (!domain) {
                /* Happens when called from AOTed code which is only used in the root domain. */
@@ -859,92 +860,38 @@ mono_jit_thread_attach (MonoDomain *domain, gpointer *dummy)
 
        g_assert (domain);
 
-       /* On coop, when we detached, we moved the thread from  RUNNING->BLOCKING.  If we try to
-        * reattach we do a BLOCKING->RUNNING transition.  If the thread is fresh,
-        * mono_thread_attach() will do a STARTING->RUNNING transition so we're only responsible
-        * for making the cookie. */
-       gboolean fresh_thread = FALSE;
-       {
-               MonoThreadInfo *info;
-
-               info = mono_thread_info_current_unchecked ();
-               fresh_thread = !info || !mono_thread_info_is_live (info);
-       }
-       {
-               gboolean attached;
-
 #ifdef MONO_HAVE_FAST_TLS
-               attached = MONO_FAST_TLS_GET (mono_lmf_addr) != NULL;
+       attached = MONO_FAST_TLS_GET (mono_lmf_addr) != NULL;
 #else
-               attached = mono_native_tls_get_value (mono_jit_tls_id) != NULL;
+       attached = mono_native_tls_get_value (mono_jit_tls_id) != NULL;
 #endif
 
-               if (!attached) {
-                       mono_thread_attach (domain);
+       if (!attached) {
+               mono_thread_attach (domain);
 
-                       // #678164
-                       mono_thread_set_state (mono_thread_internal_current (), ThreadState_Background);
-               }
+               // #678164
+               mono_thread_set_state (mono_thread_internal_current (), ThreadState_Background);
+       }
 
-               orig = mono_domain_get ();
-               if (orig != domain)
-                       mono_domain_set (domain, TRUE);
+       orig = mono_domain_get ();
+       if (orig != domain)
+               mono_domain_set (domain, TRUE);
 
-       }
-       if (!mono_threads_is_coop_enabled ()) {
-               return orig != domain ? orig : NULL;
-       } else {
-               if (fresh_thread) {
-                       *dummy = NULL;
-                       /* mono_thread_attach put the thread in RUNNING mode from STARTING, but we need to
-                        * return the right cookie. */
-                       return mono_threads_enter_gc_unsafe_region_cookie (mono_thread_info_current ());
-               } else {
-                       *dummy = orig;
-                       /* thread state (BLOCKING|RUNNING) -> RUNNING */
-                       return mono_threads_enter_gc_unsafe_region (dummy);
-               }
-       }
+       return orig != domain ? orig : NULL;
 }
 
 /*
- * mono_jit_thread_detach: called by native->managed wrappers
- *
- * In non-coop mode:
- *  - @cookie: the original domain which needs to be restored, or NULL.
- *  - @dummy: is NULL
+ * mono_jit_set_domain:
  *
- * In coop mode:
- *  - @cookie: contains current MonoThreadInfo* if it was in BLOCKING mode, NULL otherwise
- *  - @dummy: contains the original domain
+ * Set domain to @domain if @domain is not null
  */
 void
-mono_jit_thread_detach (gpointer cookie, gpointer *dummy)
+mono_jit_set_domain (MonoDomain *domain)
 {
-       MonoDomain *domain, *orig;
-
-       if (!mono_threads_is_coop_enabled ()) {
-               orig = (MonoDomain*) cookie;
+       g_assert (!mono_threads_is_coop_enabled ());
 
-               if (orig)
-                       mono_domain_set (orig, TRUE);
-       } else {
-               orig = (MonoDomain*) *dummy;
-
-               domain = mono_domain_get ();
-               g_assert (domain);
-
-               /* it won't do anything if cookie is NULL
-                * thread state RUNNING -> (RUNNING|BLOCKING) */
-               mono_threads_exit_gc_unsafe_region (cookie, dummy);
-
-               if (orig != domain) {
-                       if (!orig)
-                               mono_domain_unset ();
-                       else
-                               mono_domain_set (orig, TRUE);
-               }
-       }
+       if (domain)
+               mono_domain_set (domain, TRUE);
 }
 
 /**
@@ -1557,8 +1504,8 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code,
                break;
        case MONO_PATCH_INFO_LDSTR:
                target =
-                       mono_ldstr (domain, patch_info->data.token->image,
-                                               mono_metadata_token_index (patch_info->data.token->token));
+                       mono_ldstr_checked (domain, patch_info->data.token->image,
+                                           mono_metadata_token_index (patch_info->data.token->token), error);
                break;
        case MONO_PATCH_INFO_TYPE_FROM_HANDLE: {
                gpointer handle;
@@ -2821,9 +2768,13 @@ MONO_SIG_HANDLER_FUNC (, mono_sigill_signal_handler)
        MonoException *exc;
        MONO_SIG_HANDLER_GET_CONTEXT;
 
+       MONO_ENTER_GC_UNSAFE_UNBALANCED;
+
        exc = mono_get_exception_execution_engine ("SIGILL");
 
        mono_arch_handle_exception (ctx, exc);
+
+       MONO_EXIT_GC_UNSAFE_UNBALANCED;
 }
 
 #if defined(MONO_ARCH_USE_SIGACTION) || defined(HOST_WIN32)
@@ -2944,27 +2895,25 @@ MONO_SIG_HANDLER_FUNC (, mono_sigint_signal_handler)
  * Returns: a pointer to the newly created code
  */
 static gpointer
-mono_jit_create_remoting_trampoline (MonoDomain *domain, MonoMethod *method, MonoRemotingTarget target)
+mono_jit_create_remoting_trampoline (MonoDomain *domain, MonoMethod *method, MonoRemotingTarget target, MonoError *error)
 {
-       MonoError error;
        MonoMethod *nm;
        guint8 *addr = NULL;
 
+       mono_error_init (error);
+
        if ((method->flags & METHOD_ATTRIBUTE_VIRTUAL) && mono_method_signature (method)->generic_param_count) {
                return mono_create_specific_trampoline (method, MONO_TRAMPOLINE_GENERIC_VIRTUAL_REMOTING,
                        domain, NULL);
        }
 
        if ((method->flags & METHOD_ATTRIBUTE_ABSTRACT) ||
-           (mono_method_signature (method)->hasthis && (mono_class_is_marshalbyref (method->klass) || method->klass == mono_defaults.object_class))) {
+           (mono_method_signature (method)->hasthis && (mono_class_is_marshalbyref (method->klass) || method->klass == mono_defaults.object_class)))
                nm = mono_marshal_get_remoting_invoke_for_target (method, target);
-               addr = (guint8 *)mono_compile_method_checked (nm, &error);
-               mono_error_raise_exception (&error); /* FIXME don't raise here */
-       } else
-       {
-               addr = (guint8 *)mono_compile_method_checked (method, &error);
-               mono_error_raise_exception (&error); /* FIXME don't raise here */
-       }
+       else
+               nm = method;
+       addr = (guint8 *)mono_compile_method_checked (nm, error);
+       return_val_if_nok (error, NULL);
        return mono_get_addr_from_ftnptr (addr);
 }
 #endif
@@ -3782,8 +3731,8 @@ register_icalls (void)
        register_icall (mono_trace_enter_method, "mono_trace_enter_method", NULL, TRUE);
        register_icall (mono_trace_leave_method, "mono_trace_leave_method", NULL, TRUE);
        register_icall (mono_get_lmf_addr, "mono_get_lmf_addr", "ptr", TRUE);
-       register_icall (mono_jit_thread_attach, "mono_jit_thread_attach", "ptr ptr ptr", TRUE);
-       register_icall (mono_jit_thread_detach, "mono_jit_thread_detach", "void ptr ptr", TRUE);
+       register_icall (mono_jit_thread_attach, "mono_jit_thread_attach", "ptr ptr", TRUE);
+       register_icall (mono_jit_set_domain, "mono_jit_set_domain", "void ptr", TRUE);
        register_icall (mono_domain_get, "mono_domain_get", "ptr", TRUE);
 
        register_icall (mono_llvm_throw_exception, "mono_llvm_throw_exception", "void object", TRUE);
@@ -3946,14 +3895,14 @@ register_icalls (void)
 #endif
 
        /* other jit icalls */
-       register_icall (mono_delegate_ctor, "mono_delegate_ctor", "void object object ptr", FALSE);
+       register_icall (ves_icall_mono_delegate_ctor, "ves_icall_mono_delegate_ctor", "void object object ptr", FALSE);
        register_icall (mono_class_static_field_address , "mono_class_static_field_address",
                                 "ptr ptr ptr", FALSE);
        register_icall (mono_ldtoken_wrapper, "mono_ldtoken_wrapper", "ptr ptr ptr ptr", FALSE);
        register_icall (mono_ldtoken_wrapper_generic_shared, "mono_ldtoken_wrapper_generic_shared",
                "ptr ptr ptr ptr", FALSE);
        register_icall (mono_get_special_static_data, "mono_get_special_static_data", "ptr int", FALSE);
-       register_icall (mono_ldstr, "mono_ldstr", "object ptr ptr int32", FALSE);
+       register_icall (ves_icall_mono_ldstr, "ves_icall_mono_ldstr", "object ptr ptr int32", FALSE);
        register_icall (mono_helper_stelem_ref_check, "mono_helper_stelem_ref_check", "void object object", FALSE);
        register_icall (ves_icall_object_new, "ves_icall_object_new", "object ptr ptr", FALSE);
        register_icall (ves_icall_object_new_specific, "ves_icall_object_new_specific", "object ptr", FALSE);
@@ -4007,6 +3956,7 @@ register_icalls (void)
        register_icall (mono_llvmonly_init_delegate_virtual, "mono_llvmonly_init_delegate_virtual", "void object object ptr", TRUE);
        register_icall (mono_get_assembly_object, "mono_get_assembly_object", "object ptr", TRUE);
        register_icall (mono_get_method_object, "mono_get_method_object", "object ptr", TRUE);
+       register_icall (mono_throw_method_access, "mono_throw_method_access", "void ptr ptr", FALSE);
 
        register_icall_with_wrapper (mono_monitor_enter, "mono_monitor_enter", "void obj");
        register_icall_with_wrapper (mono_monitor_enter_v4, "mono_monitor_enter_v4", "void obj ptr");