Do TLS using pthreads if __thread keyword not supported.
[mono.git] / mono / metadata / object.c
index 908f8b97ea887310a424093e2d3a2c1a01fceb1d..33f261b513a938faeb9cb7f9e59b1d85212243de 100644 (file)
@@ -141,6 +141,9 @@ static GHashTable *blocked_thread_hash;
 /* Main thread */
 static MonoThread *main_thread;
 
+/* Functions supplied by the runtime */
+static MonoRuntimeCallbacks callbacks;
+
 /**
  * mono_thread_set_main:
  * @thread: thread to set as the main thread
@@ -467,13 +470,18 @@ static MonoTrampoline arch_create_jit_trampoline = default_trampoline;
 static MonoJumpTrampoline arch_create_jump_trampoline = default_jump_trampoline;
 static MonoRemotingTrampoline arch_create_remoting_trampoline = default_remoting_trampoline;
 static MonoDelegateTrampoline arch_create_delegate_trampoline = default_delegate_trampoline;
-static MonoVTableTrampoline arch_create_vtable_trampoline;
 static MonoImtThunkBuilder imt_thunk_builder = NULL;
 #define ARCH_USE_IMT (imt_thunk_builder != NULL)
 #if (MONO_IMT_SIZE > 32)
 #error "MONO_IMT_SIZE cannot be larger than 32"
 #endif
 
+void
+mono_install_callbacks (MonoRuntimeCallbacks *cbs)
+{
+       memcpy (&callbacks, cbs, sizeof (*cbs));
+}
+
 void
 mono_install_trampoline (MonoTrampoline func) 
 {
@@ -498,12 +506,6 @@ mono_install_delegate_trampoline (MonoDelegateTrampoline func)
        arch_create_delegate_trampoline = func? func: default_delegate_trampoline;
 }
 
-void
-mono_install_vtable_trampoline (MonoVTableTrampoline func) 
-{
-       arch_create_vtable_trampoline = func;
-}
-
 void
 mono_install_imt_thunk_builder (MonoImtThunkBuilder func) {
        imt_thunk_builder = func;
@@ -976,6 +978,14 @@ mono_install_imt_trampoline (gpointer tramp_code)
        imt_trampoline = tramp_code;
 }
 
+static gpointer vtable_trampoline = NULL;
+
+void
+mono_install_vtable_trampoline (gpointer tramp_code)
+{
+       vtable_trampoline = tramp_code;
+}
+
 #define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
 #define mix(a,b,c) { \
        a -= c;  a ^= rot(c, 4);  c += b; \
@@ -1580,7 +1590,6 @@ mono_method_add_generic_virtual_invocation (MonoDomain *domain, MonoVTable *vtab
        MonoImtBuilderEntry *entries;
        int i;
        GPtrArray *sorted;
-       gpointer vtable_trampoline = NULL;
 
        mono_domain_lock (domain);
        if (!domain->generic_virtual_cases)
@@ -1615,9 +1624,6 @@ mono_method_add_generic_virtual_invocation (MonoDomain *domain, MonoVTable *vtab
        if (++gvc->count == THUNK_THRESHOLD) {
                gpointer *old_thunk = *vtable_slot;
 
-               if (arch_create_vtable_trampoline)
-                       vtable_trampoline = arch_create_vtable_trampoline (vtable);
-
                if ((gpointer)vtable_slot < (gpointer)vtable)
                        /* Force the rebuild of the thunk at the next call */
                        *vtable_slot = imt_trampoline;
@@ -1908,8 +1914,7 @@ mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *class)
        }
 
        /* Initialize vtable */
-       if (arch_create_vtable_trampoline) {
-               gpointer vtable_trampoline = arch_create_vtable_trampoline (vt);
+       if (vtable_trampoline) {
                // This also covers the AOT case
                for (i = 0; i < class->vtable_size; ++i) {
                        vt->vtable [i] = vtable_trampoline;
@@ -1921,7 +1926,7 @@ mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *class)
                        MonoMethod *cm;
 
                        if ((cm = class->vtable [i]))
-                               vt->vtable [i] = arch_create_jit_trampoline (cm);
+                               vt->vtable [i] = vtable_trampoline? vtable_trampoline: arch_create_jit_trampoline (cm);
                }
        }
 
@@ -5708,49 +5713,24 @@ mono_store_remote_field_new (MonoObject *this, MonoClass *klass, MonoClassField
  * mono_create_ftnptr:
  *
  *   Given a function address, create a function descriptor for it.
- * This is only needed on IA64 and PPC64.
+ * This is only needed on some platforms.
  */
 gpointer
 mono_create_ftnptr (MonoDomain *domain, gpointer addr)
 {
-#ifdef __ia64__
-       gpointer *desc;
-
-       desc = mono_domain_code_reserve (domain, 2 * sizeof (gpointer));
-
-       desc [0] = addr;
-       desc [1] = NULL;
-
-       return desc;
-#elif defined(__ppc64__) || defined(__powerpc64__)
-       gpointer *desc;
-
-       desc = mono_domain_code_reserve (domain, 3 * sizeof (gpointer));
-
-       desc [0] = addr;
-       desc [1] = NULL;
-       desc [2] = NULL;
-
-       return desc;
-#else
-       return addr;
-#endif
+       return callbacks.create_ftnptr (domain, addr);
 }
 
 /*
  * mono_get_addr_from_ftnptr:
  *
  *   Given a pointer to a function descriptor, return the function address.
- * This is only needed on IA64 and PPC64.
+ * This is only needed on some platforms.
  */
 gpointer
 mono_get_addr_from_ftnptr (gpointer descr)
 {
-#if defined(__ia64__) || defined(__ppc64__) || defined(__powerpc64__)
-       return *(gpointer*)descr;
-#else
-       return descr;
-#endif
+       return callbacks.get_addr_from_ftnptr (descr);
 }      
 
 #if 0