2008-10-10 Mark Probst <mark.probst@gmail.com>
authorMark Probst <mark.probst@gmail.com>
Fri, 10 Oct 2008 21:36:34 +0000 (21:36 -0000)
committerMark Probst <mark.probst@gmail.com>
Fri, 10 Oct 2008 21:36:34 +0000 (21:36 -0000)
* object.c, class-internals.h: Also create remoting trampolines
for generic methods.  Pass the domain to the remoting trampoline
creation function, too.

2008-10-10  Mark Probst  <mark.probst@gmail.com>

* method-to-ir.c: Only do the fast virtual generic method call for
non-wrapper methods.

* mini.h, mini-trampolines.c: The new generic virtual remoting
trampoline handles virtual method calls via the vtable (as done by
the fast virtual generic method calls) to remoting proxies.

* mini.c (mono_jit_create_remoting_trampoline): For generic
methods reate a generic virtual remoting trampoline.

* mini-amd64.h: Enable fast virtual generic method calls again.

svn path=/trunk/mono/; revision=115493

mono/metadata/ChangeLog
mono/metadata/class-internals.h
mono/metadata/object.c
mono/mini/ChangeLog
mono/mini/method-to-ir.c
mono/mini/mini-amd64.h
mono/mini/mini-trampolines.c
mono/mini/mini.c
mono/mini/mini.h

index c69b9af804aeaaa6b14be55d5c8956f174f32ef3..303fd2134e8c910d06932b771b38b04f00d7e78b 100644 (file)
@@ -1,3 +1,9 @@
+2008-10-10  Mark Probst  <mark.probst@gmail.com>
+
+       * object.c, class-internals.h: Also create remoting trampolines
+       for generic methods.  Pass the domain to the remoting trampoline
+       creation function, too.
+
 2008-10-10  Zoltan Varga  <vargaz@gmail.com>
 
        * class.c (mono_class_init): Fix+re-enable the finalize optimization.
index 488aaabffe631bdbb3ff25a57258f5b3d97cc1ef..1d58b62d6bd8766d65c32c616e30b0941e183374 100644 (file)
@@ -734,7 +734,7 @@ extern MonoStats mono_stats MONO_INTERNAL;
 
 typedef gpointer (*MonoTrampoline)       (MonoMethod *method);
 typedef gpointer (*MonoJumpTrampoline)       (MonoDomain *domain, MonoMethod *method, gboolean add_sync_wrapper);
-typedef gpointer (*MonoRemotingTrampoline)       (MonoMethod *method, MonoRemotingTarget target);
+typedef gpointer (*MonoRemotingTrampoline)       (MonoDomain *domain, MonoMethod *method, MonoRemotingTarget target);
 typedef gpointer (*MonoDelegateTrampoline)       (MonoClass *klass);
 
 typedef gpointer (*MonoLookupDynamicToken) (MonoImage *image, guint32 token, gboolean valid_token, MonoClass **handle_class, MonoGenericContext *context);
index 4d6ed4a5d04d485072f370c81d9f8b869e8fa80d..9b44d4acc1eb4e06389c62d97402030c11aa0e4a 100644 (file)
@@ -446,7 +446,7 @@ default_jump_trampoline (MonoDomain *domain, MonoMethod *method, gboolean add_sy
 }
 
 static gpointer
-default_remoting_trampoline (MonoMethod *method, MonoRemotingTarget target)
+default_remoting_trampoline (MonoDomain *domain, MonoMethod *method, MonoRemotingTarget target)
 {
        g_error ("remoting not installed");
        return NULL;
@@ -1939,8 +1939,7 @@ mono_class_proxy_vtable (MonoDomain *domain, MonoRemoteClass *remote_class, Mono
                MonoMethod *cm;
                    
                if ((cm = class->vtable [i]))
-                       pvt->vtable [i] = mono_method_signature (cm)->generic_param_count
-                               ? cm : arch_create_remoting_trampoline (cm, target_type);
+                       pvt->vtable [i] = arch_create_remoting_trampoline (domain, cm, target_type);
                else
                        pvt->vtable [i] = NULL;
        }
@@ -1952,7 +1951,7 @@ mono_class_proxy_vtable (MonoDomain *domain, MonoRemoteClass *remote_class, Mono
                        gpointer iter = NULL;
                        while ((m = mono_class_get_methods (k, &iter)))
                                if (!pvt->vtable [m->slot])
-                                       pvt->vtable [m->slot] = mono_method_signature (m)->generic_param_count ? m : arch_create_remoting_trampoline (m, target_type);
+                                       pvt->vtable [m->slot] = arch_create_remoting_trampoline (domain, m, target_type);
                }
        }
 
@@ -1991,7 +1990,7 @@ mono_class_proxy_vtable (MonoDomain *domain, MonoRemoteClass *remote_class, Mono
                        iter = NULL;
                        j = 0;
                        while ((cm = mono_class_get_methods (interf, &iter)))
-                               pvt->vtable [slot + j++] = mono_method_signature (cm)->generic_param_count ? cm : arch_create_remoting_trampoline (cm, target_type);
+                               pvt->vtable [slot + j++] = arch_create_remoting_trampoline (domain, cm, target_type);
                        
                        slot += mono_class_num_methods (interf);
                }
index fd006fe41c46454cc39078babf50a06a59e02e8c..79882dee2ec7c18d4f547f8442559276af960e0d 100644 (file)
@@ -1,3 +1,17 @@
+2008-10-10  Mark Probst  <mark.probst@gmail.com>
+
+       * method-to-ir.c: Only do the fast virtual generic method call for
+       non-wrapper methods.
+
+       * mini.h, mini-trampolines.c: The new generic virtual remoting
+       trampoline handles virtual method calls via the vtable (as done by
+       the fast virtual generic method calls) to remoting proxies.
+
+       * mini.c (mono_jit_create_remoting_trampoline): For generic
+       methods reate a generic virtual remoting trampoline.
+
+       * mini-amd64.h: Enable fast virtual generic method calls again.
+
 2008-10-10  Mark Probst  <mark.probst@gmail.com>
 
        * mini-ppc.c: Use SP (r1), not frame_reg (which might be r31) to
index b5f836b857dd0133ac2a8afb1ca858819756c7c1..00c45e81e4eeae1e8d38b705b63905d5ab367357 100644 (file)
@@ -6011,7 +6011,8 @@ mono_method_to_ir2 (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_
                                INLINE_FAILURE;
 
 #if MONO_ARCH_HAVE_GENERALIZED_IMT_THUNK
-                               if (!(cmethod->klass->flags & TYPE_ATTRIBUTE_INTERFACE)) {
+                               if (!(cmethod->klass->flags & TYPE_ATTRIBUTE_INTERFACE) &&
+                                               cmethod->wrapper_type == MONO_WRAPPER_NONE) {
                                        g_assert (!imt_arg);
                                        if (context_used) {
                                                imt_arg = emit_get_rgctx_method (cfg, context_used,
index 0180f3dcb12d50b690a38c3868e1d5ce802f3fa2..7cb928700050738b572f4e2f82c6502a5d896ce5 100644 (file)
@@ -292,7 +292,7 @@ typedef struct {
 #define MONO_ARCH_HAVE_NOTIFY_PENDING_EXC 1
 #define MONO_ARCH_ENABLE_NORMALIZE_OPCODES 1
 #define MONO_ARCH_ENABLE_GLOBAL_RA 1
-/* #define MONO_ARCH_HAVE_GENERALIZED_IMT_THUNK 1 */
+#define MONO_ARCH_HAVE_GENERALIZED_IMT_THUNK 1
 
 #define MONO_ARCH_AOT_SUPPORTED 1
 
index 6f1ee762632679229fd38852cf4bd08c058733f6..aaa319cb6b38bbac1a88df933395d4ddc968fa5f 100644 (file)
@@ -365,6 +365,38 @@ mono_magic_trampoline (gssize *regs, guint8 *code, MonoMethod *m, guint8* tramp)
        return addr;
 }
 
+gpointer
+mono_generic_virtual_remoting_trampoline (gssize *regs, guint8 *code, MonoMethod *m, guint8 *tramp)
+{
+       MonoGenericContext context = { NULL, NULL };
+       MonoMethod *declaring;
+       gpointer addr;
+
+       g_assert (m->is_generic);
+
+       if (m->is_inflated)
+               declaring = mono_method_get_declaring_generic_method (m);
+       else
+               declaring = m;
+
+       if (m->klass->generic_class)
+               context.class_inst = m->klass->generic_class->context.class_inst;
+       else
+               g_assert (!m->klass->generic_container);
+
+       context.method_inst = (MonoGenericInst*)mono_arch_find_imt_method ((gpointer*)regs, code);
+
+       m = mono_class_inflate_generic_method (declaring, &context);
+       m = mono_marshal_get_remoting_invoke_with_check (m);
+
+       addr = mono_compile_method (m);
+       g_assert (addr);
+
+       mono_debugger_trampoline_compiled (m, addr);
+
+       return addr;
+}
+
 /*
  * mono_aot_trampoline:
  *
@@ -625,6 +657,8 @@ mono_get_trampoline_func (MonoTrampolineType tramp_type)
 #endif
        case MONO_TRAMPOLINE_RESTORE_STACK_PROT:
                return mono_altstack_restore_prot;
+       case MONO_TRAMPOLINE_GENERIC_VIRTUAL_REMOTING:
+               return mono_generic_virtual_remoting_trampoline;
        default:
                g_assert_not_reached ();
                return NULL;
@@ -652,6 +686,7 @@ mono_trampolines_init (void)
        mono_trampoline_code [MONO_TRAMPOLINE_DELEGATE] = mono_arch_create_trampoline_code (MONO_TRAMPOLINE_DELEGATE);
 #endif
        mono_trampoline_code [MONO_TRAMPOLINE_RESTORE_STACK_PROT] = mono_arch_create_trampoline_code (MONO_TRAMPOLINE_RESTORE_STACK_PROT);
+       mono_trampoline_code [MONO_TRAMPOLINE_GENERIC_VIRTUAL_REMOTING] = mono_arch_create_trampoline_code (MONO_TRAMPOLINE_GENERIC_VIRTUAL_REMOTING);
 }
 
 void
index 2973a3b73ce7d0548789164011e08989e4b02bc6..af2e62f3404ded67ca117f174ffb762e59601119 100644 (file)
@@ -14186,11 +14186,16 @@ setup_stat_profiler (void)
  * Returns: a pointer to the newly created code 
  */
 static gpointer
-mono_jit_create_remoting_trampoline (MonoMethod *method, MonoRemotingTarget target)
+mono_jit_create_remoting_trampoline (MonoDomain *domain, MonoMethod *method, MonoRemotingTarget target)
 {
        MonoMethod *nm;
        guint8 *addr = NULL;
 
+       if ((method->flags & METHOD_ATTRIBUTE_VIRTUAL) && mono_method_signature (method)->generic_param_count) {
+               return mono_arch_create_specific_trampoline (method, MONO_TRAMPOLINE_GENERIC_VIRTUAL_REMOTING,
+                       domain, NULL);
+       }
+
        if ((method->flags & METHOD_ATTRIBUTE_ABSTRACT) || 
            (mono_method_signature (method)->hasthis && (method->klass->marshalbyref || method->klass == mono_defaults.object_class))) {
                nm = mono_marshal_get_remoting_invoke_for_target (method, target);
index ebec6a04cc4efbdf23e89d012507b822db128809..21c353650755fb473924a60b99b14d4ba7a0ed72 100644 (file)
@@ -802,6 +802,7 @@ typedef enum {
        MONO_TRAMPOLINE_AOT_PLT,
        MONO_TRAMPOLINE_DELEGATE,
        MONO_TRAMPOLINE_RESTORE_STACK_PROT,
+       MONO_TRAMPOLINE_GENERIC_VIRTUAL_REMOTING,
        MONO_TRAMPOLINE_NUM
 } MonoTrampolineType;
 
@@ -1420,6 +1421,7 @@ MonoVTable*       mono_find_class_init_trampoline_by_addr (gconstpointer addr) M
 MonoClass*        mono_find_delegate_trampoline_by_addr (gconstpointer addr) MONO_INTERNAL;
 guint32           mono_find_rgctx_lazy_fetch_trampoline_by_addr (gconstpointer addr) MONO_INTERNAL;
 gpointer          mono_magic_trampoline (gssize *regs, guint8 *code, MonoMethod *m, guint8* tramp) MONO_INTERNAL;
+gpointer          mono_generic_virtual_remoting_trampoline (gssize *regs, guint8 *code, MonoMethod *m, guint8 *tramp) MONO_INTERNAL;
 gpointer          mono_delegate_trampoline (gssize *regs, guint8 *code, gpointer *tramp_data, guint8* tramp) MONO_INTERNAL;
 gpointer          mono_aot_trampoline (gssize *regs, guint8 *code, guint8 *token_info, 
                                                                           guint8* tramp) MONO_INTERNAL;