#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>
}
/*
- * 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. */
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);
}
/**
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)
* 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
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);
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");