Extract the code to emit a memory barrier. Add a memory_barrier_kind field to MonoIns...
[mono.git] / mono / mini / mini-darwin.c
index 0b2ff12e7c63428599468f43101720491e956bcb..8e6f93f3befaf60937dffb997fc48d68c413f643 100644 (file)
@@ -43,6 +43,7 @@
 #include <mono/metadata/verify-internals.h>
 #include <mono/metadata/mempool-internals.h>
 #include <mono/metadata/attach.h>
+#include <mono/metadata/gc-internal.h>
 #include <mono/utils/mono-math.h>
 #include <mono/utils/mono-compiler.h>
 #include <mono/utils/mono-counters.h>
@@ -65,6 +66,7 @@
 #include <mach/task.h>
 #include <pthread.h>
 #include <dlfcn.h>
+#include <AvailabilityMacros.h>
 
 /*
  * This code disables the CrashReporter of MacOS X by installing
@@ -179,12 +181,19 @@ macosx_register_exception_handler ()
                                            mach_exception_port,
                                            EXCEPTION_DEFAULT,
                                            MACHINE_THREAD_STATE) == KERN_SUCCESS);
+
+       mono_gc_register_mach_exception_thread (thread);
 }
 
+/* This is #define'd by Boehm GC to _GC_dlopen. */
+#undef dlopen
+
 void
 mono_runtime_install_handlers (void)
 {
+#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_5
        macosx_register_exception_handler ();
+#endif
        mono_runtime_posix_install_handlers ();
 
        /* Snow Leopard has a horrible bug: http://openradar.appspot.com/7209349
@@ -206,34 +215,7 @@ mono_runtime_install_handlers (void)
 pid_t
 mono_runtime_syscall_fork ()
 {
-#if defined(__i386__)
-       /* Apple's fork syscall returns a regpair in EAX:EDX.
-        *  EAX == pid of caller always
-        *  EDX == 0 for parent, 1 for child
-        */             
-       register_t eax;
-       register_t edx;
-       pid_t pid;
-
-       __asm__  __volatile__ (
-               "mov $0x2, %%eax;"
-               "int $0x80;"
-               "mov %%eax, %0;"
-               "mov %%edx, %1;"
-               : "=m" (eax), "=m" (edx));
-
-       if (edx == 0) {
-               pid = eax;
-       } else if (edx == 1) {
-               pid = 0;
-       } else {
-               g_assert_not_reached ();
-       }
-
-       return pid;
-#else
-       g_assert_not_reached ();
-#endif
+       return (pid_t) fork ();
 }
 
 gboolean
@@ -269,3 +251,45 @@ mono_gdb_render_native_backtraces ()
 
        return TRUE;
 }
+
+gboolean
+mono_thread_state_init_from_handle (MonoThreadUnwindState *tctx, MonoNativeThreadId thread_id, MonoNativeThreadHandle thread_handle)
+{
+       kern_return_t ret;
+       mach_msg_type_number_t num_state;
+       thread_state_t state;
+       ucontext_t ctx;
+       mcontext_t mctx;
+       guint32 domain_key, jit_key;
+       MonoJitTlsData *jit_tls;
+       void *domain;
+
+       state = (thread_state_t) alloca (mono_mach_arch_get_thread_state_size ());
+       mctx = (mcontext_t) alloca (mono_mach_arch_get_mcontext_size ());
+
+       ret = mono_mach_arch_get_thread_state (thread_handle, state, &num_state);
+       if (ret != KERN_SUCCESS)
+               return FALSE;
+
+       mono_mach_arch_thread_state_to_mcontext (state, mctx);
+       ctx.uc_mcontext = mctx;
+
+       mono_sigctx_to_monoctx (&ctx, &tctx->ctx);
+
+       domain_key = mono_domain_get_tls_offset ();
+       jit_key = mono_pthread_key_for_tls (mono_get_jit_tls_key ());
+       jit_tls = mono_mach_arch_get_tls_value_from_thread (thread_id, jit_key);
+       domain = mono_mach_arch_get_tls_value_from_thread (thread_id, domain_key);
+
+       /*Thread already started to cleanup, can no longer capture unwind state*/
+       if (!jit_tls)
+               return FALSE;
+       g_assert (domain);
+
+       tctx->unwind_data [MONO_UNWIND_DATA_DOMAIN] = domain;
+       tctx->unwind_data [MONO_UNWIND_DATA_LMF] = jit_tls ? jit_tls->lmf : NULL;
+       tctx->unwind_data [MONO_UNWIND_DATA_JIT_TLS] = jit_tls;
+       tctx->valid = TRUE;
+
+       return TRUE;
+}