Remove the setup_jit_tls_data () call from mini_init (), it is done later by mono_thr...
[mono.git] / mono / mini / mini-trampolines.c
index 147073ba800a1409cb928588a0b7708dbc83bbfd..fe11fe04b55a4d7846a2ff91c8672cb0680c3761 100644 (file)
@@ -1,4 +1,8 @@
-
+/*
+ * (C) 2003 Ximian, Inc.
+ * (C) 2003-2011 Novell, Inc.
+ * Copyright 2011 Xamarin, Inc (http://www.xamarin.com)
+ */
 #include <config.h>
 #include <glib.h>
 
@@ -45,7 +49,7 @@ get_unbox_trampoline (MonoMethod *m, gpointer addr, gboolean need_rgctx_tramp)
        }
 }
 
-#ifdef MONO_ARCH_HAVE_STATIC_RGCTX_TRAMPOLINE
+#ifdef MONO_ARCH_GSHARED_SUPPORTED
 
 typedef struct {
        MonoMethod *m;
@@ -142,11 +146,11 @@ mono_create_static_rgctx_trampoline (MonoMethod *m, gpointer addr)
 gpointer
 mono_create_static_rgctx_trampoline (MonoMethod *m, gpointer addr)
 {
-       /* 
-        * This shouldn't happen as all arches which support generic sharing support
-        * static rgctx trampolines as well.
-        */
-       g_assert_not_reached ();
+       /* 
+        * This shouldn't happen as all arches which support generic sharing support
+        * static rgctx trampolines as well.
+        */
+       g_assert_not_reached ();
 }
 #endif
 
@@ -156,6 +160,15 @@ mono_create_static_rgctx_trampoline (MonoMethod *m, gpointer addr)
  * Either IMPL_METHOD or AOT_ADDR will be set on return.
  */
 static gpointer*
+#ifdef __GNUC__
+/*
+ * This works against problems when compiling with gcc 4.6 on arm. The 'then' part of
+ * this line gets executed, even when the condition is false:
+ *             if (impl && mono_method_needs_static_rgctx_invoke (impl, FALSE))
+ *                     *need_rgctx_tramp = TRUE;
+ */
+__attribute__ ((noinline))
+#endif
 mono_convert_imt_slot_to_vtable_slot (gpointer* slot, mgreg_t *regs, guint8 *code, MonoMethod *method, MonoMethod **impl_method, gboolean *need_rgctx_tramp, gboolean *variance_used, gpointer *aot_addr)
 {
        MonoObject *this_argument = mono_arch_get_this_arg_from_call (regs, code);
@@ -279,7 +292,7 @@ common_call_trampoline (mgreg_t *regs, guint8 *code, MonoMethod *m, guint8* tram
        MonoMethod *declaring = NULL;
        MonoMethod *generic_virtual = NULL, *variant_iface = NULL;
        int context_used;
-       gboolean virtual, proxy = FALSE, variance_used = FALSE;
+       gboolean virtual, variance_used = FALSE;
        gpointer *orig_vtable_slot, *vtable_slot_to_patch = NULL;
        MonoJitInfo *ji = NULL;
 
@@ -305,7 +318,6 @@ common_call_trampoline (mgreg_t *regs, guint8 *code, MonoMethod *m, guint8* tram
 
                if (this_arg->vtable->klass == mono_defaults.transparent_proxy_class) {
                        /* Use the slow path for now */
-                       proxy = TRUE;
                    m = mono_object_get_virtual_method (this_arg, m);
                        vtable_slot_to_patch = NULL;
                } else {
@@ -407,8 +419,10 @@ common_call_trampoline (mgreg_t *regs, guint8 *code, MonoMethod *m, guint8* tram
                        g_assert (this_argument->vtable->klass->inited);
                        //mono_class_init (this_argument->vtable->klass);
 
-                       if (!vtable_slot)
+                       if (!vtable_slot) {
+                               mono_class_setup_supertypes (this_argument->vtable->klass);
                                klass = this_argument->vtable->klass->supertypes [m->klass->idepth - 1];
+                       }
 #else
                        NOT_IMPLEMENTED;
 #endif
@@ -458,16 +472,8 @@ common_call_trampoline (mgreg_t *regs, guint8 *code, MonoMethod *m, guint8* tram
        }
 
        if (m->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED) {
-               MonoJitInfo *ji;
-
-               if (code)
-                       ji = mini_jit_info_table_find (mono_domain_get (), (char*)code, NULL);
-               else
-                       ji = NULL;
-
-               /* Avoid recursion */
-               if (!(ji && ji->method->wrapper_type == MONO_WRAPPER_SYNCHRONIZED))
-                       m = mono_marshal_get_synchronized_wrapper (m);
+               m = mono_marshal_get_synchronized_wrapper (m);
+               need_rgctx_tramp = FALSE;
        }
 
        /* Calls made through delegates on platforms without delegate trampolines */
@@ -553,9 +559,13 @@ common_call_trampoline (mgreg_t *regs, guint8 *code, MonoMethod *m, guint8* tram
                        {
                                MonoJitInfo *target_ji = 
                                        mono_jit_info_table_find (mono_domain_get (), mono_get_addr_from_ftnptr (compiled_method));
+                               if (!target_ji)
+                                       target_ji = mono_jit_info_table_find (mono_get_root_domain (), mono_get_addr_from_ftnptr (compiled_method));
 
                                if (!ji)
                                        ji = mono_jit_info_table_find (mono_domain_get (), (char*)code);
+                               if (!ji)
+                                       ji = mono_jit_info_table_find (mono_get_root_domain (), (char*)code);
 
                                if (mono_method_same_domain (ji, target_ji))
                                        mono_arch_patch_callsite (ji->code_start, code, addr);
@@ -909,7 +919,10 @@ mono_delegate_trampoline (mgreg_t *regs, guint8 *code, gpointer *tramp_data, gui
                        mono_error_raise_exception (&err);
 
                callvirt = !delegate->target && sig->hasthis;
-               if (delegate->target && method->flags & METHOD_ATTRIBUTE_VIRTUAL && method->klass->flags & TYPE_ATTRIBUTE_ABSTRACT) {
+               if (delegate->target && 
+                       method->flags & METHOD_ATTRIBUTE_VIRTUAL && 
+                       method->flags & METHOD_ATTRIBUTE_ABSTRACT &&
+                       method->klass->flags & TYPE_ATTRIBUTE_ABSTRACT) {
                        method = mono_object_get_virtual_method (delegate->target, method);
                        enable_caching = FALSE;
                }
@@ -973,7 +986,7 @@ mono_handler_block_guard_trampoline (mgreg_t *regs, guint8 *code, gpointer *tram
 {
        MonoContext ctx;
        MonoException *exc;
-       MonoJitTlsData *jit_tls = TlsGetValue (mono_jit_tls_id);
+       MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id);
        gpointer resume_ip = jit_tls->handler_block_return_address;
 
        memcpy (&ctx, &jit_tls->handler_block_context, sizeof (MonoContext));
@@ -993,7 +1006,7 @@ mono_handler_block_guard_trampoline (mgreg_t *regs, guint8 *code, gpointer *tram
                if (!restore_context)
                        restore_context = mono_get_restore_context ();
 
-               mono_handle_exception (&ctx, exc, NULL, FALSE);
+               mono_handle_exception (&ctx, exc);
                restore_context (&ctx);
        }
 
@@ -1234,8 +1247,9 @@ mono_create_jump_trampoline (MonoDomain *domain, MonoMethod *method, gboolean ad
         * We cannot recover the correct type of a shared generic
         * method from its native code address, so we use the
         * trampoline instead.
+        * For synchronized methods, the trampoline adds the wrapper.
         */
-       if (code && !ji->has_generic_jit_info)
+       if (code && !ji->has_generic_jit_info && !(method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED))
                return code;
 
        mono_domain_lock (domain);
@@ -1310,7 +1324,7 @@ mono_create_jit_trampoline_from_token (MonoImage *image, guint32 token)
        MonoDomain *domain = mono_domain_get ();
        guint8 *buf, *start;
 
-       buf = start = mono_domain_code_reserve (domain, 2 * sizeof (gpointer));
+       buf = start = mono_domain_alloc0 (domain, 2 * sizeof (gpointer));
 
        *(gpointer*)(gpointer)buf = image;
        buf += sizeof (gpointer);
@@ -1324,10 +1338,9 @@ mono_create_jit_trampoline_from_token (MonoImage *image, guint32 token)
 }      
 
 gpointer
-mono_create_delegate_trampoline (MonoClass *klass)
+mono_create_delegate_trampoline (MonoDomain *domain, MonoClass *klass)
 {
 #ifdef MONO_ARCH_HAVE_CREATE_DELEGATE_TRAMPOLINE
-       MonoDomain *domain = mono_domain_get ();
        gpointer ptr;
        guint32 code_size = 0;
        gpointer *tramp_data;
@@ -1348,7 +1361,7 @@ mono_create_delegate_trampoline (MonoClass *klass)
        tramp_data [1] = mono_arch_get_delegate_invoke_impl (mono_method_signature (invoke), TRUE);
        tramp_data [2] = mono_arch_get_delegate_invoke_impl (mono_method_signature (invoke), FALSE);
 
-       ptr = mono_create_specific_trampoline (tramp_data, MONO_TRAMPOLINE_DELEGATE, mono_domain_get (), &code_size);
+       ptr = mono_create_specific_trampoline (tramp_data, MONO_TRAMPOLINE_DELEGATE, domain, &code_size);
        g_assert (code_size);
 
        /* store trampoline address */
@@ -1417,7 +1430,6 @@ gpointer
 mono_create_monitor_enter_trampoline (void)
 {
        static gpointer code;
-       MonoTrampInfo *info;
 
        if (mono_aot_only) {
                if (!code)
@@ -1429,6 +1441,8 @@ mono_create_monitor_enter_trampoline (void)
        mono_trampolines_lock ();
 
        if (!code) {
+               MonoTrampInfo *info;
+
                code = mono_arch_create_monitor_enter_trampoline (&info, FALSE);
                if (info) {
                        mono_save_trampoline_xdebug_info (info);
@@ -1451,7 +1465,6 @@ gpointer
 mono_create_monitor_exit_trampoline (void)
 {
        static gpointer code;
-       MonoTrampInfo *info;
 
        if (mono_aot_only) {
                if (!code)
@@ -1463,6 +1476,8 @@ mono_create_monitor_exit_trampoline (void)
        mono_trampolines_lock ();
 
        if (!code) {
+               MonoTrampInfo *info;
+
                code = mono_arch_create_monitor_exit_trampoline (&info, FALSE);
                if (info) {
                        mono_save_trampoline_xdebug_info (info);