more c*****y windows issues.
[mono.git] / mono / mini / tramp-ppc.c
index 24fc71b6e9a2594bb190c45ba8dac2c27eba1995..92d58759d3a6b50340b700feb64c5df47cd61483 100644 (file)
@@ -51,7 +51,7 @@ get_unbox_trampoline (MonoMethod *m, gpointer addr)
        guint8 *code, *start;
        int this_pos = 3;
 
-       if (!m->signature->ret->byref && MONO_TYPE_ISSTRUCT (m->signature->ret))
+       if (!mono_method_signature (m)->ret->byref && MONO_TYPE_ISSTRUCT (mono_method_signature (m)->ret))
                this_pos = 4;
            
        start = code = g_malloc (20);
@@ -101,6 +101,7 @@ ppc_magic_trampoline (MonoMethod *method, guint32 *code, char *sp)
 {
        char *o = NULL;
        gpointer addr;
+        MonoJitInfo *ji, *target_ji;
        int reg, offset = 0;
 
        addr = mono_compile_method(method);
@@ -111,6 +112,12 @@ ppc_magic_trampoline (MonoMethod *method, guint32 *code, char *sp)
                return addr;
        }
 
+       /* We can't trampoline across domains */
+       ji = mono_jit_info_table_find (mono_domain_get (), code);
+       target_ji = mono_jit_info_table_find (mono_domain_get (), addr);
+       if (!mono_method_same_domain (ji, target_ji))
+               return addr;
+
        /* Locate the address of the method-specific trampoline. The call using
        the vtable slot that took the processing flow to 'arch_create_jit_trampoline' 
        looks something like this:
@@ -146,7 +153,13 @@ ppc_magic_trampoline (MonoMethod *method, guint32 *code, char *sp)
        
        /* Sanity check: instruction must be 'blrl' */
        g_assert(*code == 0x4e800021);
-       
+
+       /* the thunk-less direct call sequence: lis/ori/mtlr/blrl */
+       if ((code [-1] >> 26) == 31 && (code [-2] >> 26) == 24 && (code [-3] >> 26) == 15) {
+               ppc_patch ((char*)code, addr);
+               return addr;
+       }
+
        /* OK, we're now at the 'blrl' instruction. Now walk backwards
        till we get to a 'mtlr rA' */
        for(; --code;) {
@@ -185,11 +198,12 @@ ppc_magic_trampoline (MonoMethod *method, guint32 *code, char *sp)
           we won't have an object, but the actual pointer to the 
           valuetype as the this argument
         */
-       if (method->klass->valuetype)
+       if (method->klass->valuetype && !mono_aot_is_got_entry (code, o))
                addr = get_unbox_trampoline (method, addr);
 
        o += offset;
-       *((gpointer *)o) = addr;
+       if (mono_aot_is_got_entry (code, o) || mono_domain_owns_vtable_slot (mono_domain_get (), o))
+               *((gpointer *)o) = addr;
        return addr;
 }