2009-04-11 Zoltan Varga <vargaz@gmail.com>
authorZoltan Varga <vargaz@gmail.com>
Sat, 11 Apr 2009 04:48:44 +0000 (04:48 -0000)
committerZoltan Varga <vargaz@gmail.com>
Sat, 11 Apr 2009 04:48:44 +0000 (04:48 -0000)
* mini.h (MONO_AOT_FILE_VERSION): Bump this.

* aot-compiler.c (emit_extra_methods): Emit the wrapper method names in
a more compact format.
(mono_aot_wrapper_name): New function to return a unique name for a
wrapper method, also used by the AOT runtime.

* aot-runtime.c (find_extra_method_in_amodule): Update after the changes to
aot-compiler.c.

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

mono/metadata/marshal.c
mono/mini/ChangeLog
mono/mini/aot-compiler.c
mono/mini/aot-runtime.c
mono/mini/mini.h

index 94f3a3ba2e8267984dad08d3853fd7b647f1f6e4..1fc4beada7c0e49225a7a088443a0ebe7dd70ed6 100644 (file)
@@ -3984,7 +3984,7 @@ mono_marshal_get_runtime_invoke (MonoMethod *method, gboolean virtual)
 
                // FIXME: When to free callsig ?
        }
-       
+
        /* to make it work with our special string constructors */
        if (!string_dummy) {
                MONO_GC_REGISTER_ROOT (string_dummy);
index 8ea865dec27b81d2c30e29e116c1288437e0bb31..3849f6469f66e523b315a9caa318f286f3f27bef 100644 (file)
@@ -1,5 +1,15 @@
 2009-04-11  Zoltan Varga  <vargaz@gmail.com>
 
+       * mini.h (MONO_AOT_FILE_VERSION): Bump this.
+
+       * aot-compiler.c (emit_extra_methods): Emit the wrapper method names in
+       a more compact format.
+       (mono_aot_wrapper_name): New function to return a unique name for a
+       wrapper method, also used by the AOT runtime.
+
+       * aot-runtime.c (find_extra_method_in_amodule): Update after the changes to
+       aot-compiler.c.
+
        * aot-compiler.c (add_generic_class): Add the helper methods from T[]
        when a ICollection<T> etc is encountered.
        (add_generic_instances): Process method arguments/locals too.
index c88994beebf8e0551cadc0c03da4d54cf653102b..ff80d34c218871a622e9b5e25c11d1b9fb4f8527 100644 (file)
@@ -975,11 +975,13 @@ encode_method_ref (MonoAotCompile *acfg, MonoMethod *method, guint8 *buf, guint8
                                g_assert_not_reached ();
                        break;
                case MONO_WRAPPER_STATIC_RGCTX_INVOKE:
-               case MONO_WRAPPER_SYNCHRONIZED: {
+               case MONO_WRAPPER_SYNCHRONIZED:
+               case MONO_WRAPPER_MANAGED_TO_NATIVE: {
                        MonoMethod *m;
 
                        m = mono_marshal_method_from_wrapper (method);
                        g_assert (m);
+                       g_assert (m != method);
                        encode_method_ref (acfg, m, p, &p);
                        break;
                }
@@ -3261,6 +3263,38 @@ mono_aot_method_hash (MonoMethod *method)
        return hash;
 }
 
+/*
+ * mono_aot_wrapper_name:
+ *
+ *   Return a string which uniqely identifies the given wrapper method.
+ */
+char*
+mono_aot_wrapper_name (MonoMethod *method)
+{
+       char *name, *tmpsig, *klass_desc;
+
+       tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
+
+       switch (method->wrapper_type) {
+       case MONO_WRAPPER_RUNTIME_INVOKE:
+       case MONO_WRAPPER_DELEGATE_INVOKE:
+       case MONO_WRAPPER_DELEGATE_BEGIN_INVOKE:
+       case MONO_WRAPPER_DELEGATE_END_INVOKE:
+               /* This is a hack to work around the fact that runtime invoke wrappers get assigned to some random class */
+               name = g_strdup_printf ("%s (%s)", method->name, tmpsig);
+               break;
+       default:
+               klass_desc = mono_type_full_name (&method->klass->byval_arg);
+
+               name = g_strdup_printf ("%s:%s (%s)", klass_desc, method->name, tmpsig);
+               break;
+       }
+
+       g_free (tmpsig);
+
+       return name;
+}
+
 #if !defined(DISABLE_AOT) && !defined(DISABLE_JIT)
 
 typedef struct HashEntry {
@@ -3299,6 +3333,7 @@ emit_extra_methods (MonoAotCompile *acfg)
        for (i = 0; i < acfg->extra_methods->len; ++i) {
                MonoMethod *method = g_ptr_array_index (acfg->extra_methods, i);
                MonoCompile *cfg = g_hash_table_lookup (acfg->method_to_cfg, method);
+               char *name;
 
                if (!cfg)
                        continue;
@@ -3306,31 +3341,27 @@ emit_extra_methods (MonoAotCompile *acfg)
                nmethods ++;
                info_offsets [i] = p - buf;
 
+               name = NULL;
                if (method->wrapper_type) {
-                       char *name;
-
-                       // FIXME: Optimize disk usage
-                       if (method->wrapper_type == MONO_WRAPPER_RUNTIME_INVOKE) {
-                               char *tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
-                               name = g_strdup_printf ("(wrapper runtime-invoke):%s (%s)", method->name, tmpsig);
-                               g_free (tmpsig);
-                       } else if (method->wrapper_type == MONO_WRAPPER_DELEGATE_INVOKE) {
-                               char *tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
-                               name = g_strdup_printf ("(wrapper delegate-invoke):%s (%s)", method->name, tmpsig);
-                               g_free (tmpsig);
-                       } else if (method->wrapper_type == MONO_WRAPPER_DELEGATE_BEGIN_INVOKE) {
-                               char *tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
-                               name = g_strdup_printf ("(wrapper delegate-begin-invoke):%s (%s)", method->name, tmpsig);
-                               g_free (tmpsig);
-                       } else if (method->wrapper_type == MONO_WRAPPER_DELEGATE_END_INVOKE) {
-                               char *tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
-                               name = g_strdup_printf ("(wrapper delegate-end-invoke):%s (%s)", method->name, tmpsig);
-                               g_free (tmpsig);
-                       } else {
-                               name = mono_method_full_name (cfg->orig_method, TRUE);
+                       /* 
+                        * We encode some wrappers using their name, since encoding them
+                        * directly would be difficult. This also avoids creating the wrapper
+                        * methods at runtime, since they are not needed anyway.
+                        */
+                       switch (method->wrapper_type) {
+                       case MONO_WRAPPER_REMOTING_INVOKE_WITH_CHECK:
+                       case MONO_WRAPPER_SYNCHRONIZED:
+                               /* encode_method_ref () can handle these */
+                               break;
+                       default:
+                               name = mono_aot_wrapper_name (method);
+                               break;
                        }
+               }
 
+               if (name) {
                        encode_value (1, p, &p);
+                       encode_value (method->wrapper_type, p, &p);
                        strcpy ((char*)p, name);
                        p += strlen (name ) + 1;
                        g_free (name);
index 8346cad7c2b6a58c32a93844be74f7c38686f8d1..ac0e82ce105ad4336affc629280ffde60b73b4ed 100644 (file)
@@ -2164,8 +2164,9 @@ find_extra_method_in_amodule (MonoAotModule *amodule, MonoMethod *method)
 {
        guint32 table_size, entry_size, hash;
        guint32 *table, *entry;
-       char *full_name = NULL;
+       char *name = NULL;
        int num_checks = 0;
+       guint32 index;
 
        if (!amodule)
                return 0xffffff;
@@ -2175,26 +2176,7 @@ find_extra_method_in_amodule (MonoAotModule *amodule, MonoMethod *method)
        entry_size = 3;
 
        if (method->wrapper_type) {
-               /* FIXME: This is a hack to work around the fact that runtime invoke wrappers get assigned to some random class */
-               if (method->wrapper_type == MONO_WRAPPER_RUNTIME_INVOKE) {
-                       char *tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
-                       full_name = g_strdup_printf ("(wrapper runtime-invoke):%s (%s)", method->name, tmpsig);
-                       g_free (tmpsig);
-               } else if (method->wrapper_type == MONO_WRAPPER_DELEGATE_INVOKE) {
-                       char *tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
-                       full_name = g_strdup_printf ("(wrapper delegate-invoke):%s (%s)", method->name, tmpsig);
-                       g_free (tmpsig);
-               } else if (method->wrapper_type == MONO_WRAPPER_DELEGATE_BEGIN_INVOKE) {
-                       char *tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
-                       full_name = g_strdup_printf ("(wrapper delegate-begin-invoke):%s (%s)", method->name, tmpsig);
-                       g_free (tmpsig);
-               } else if (method->wrapper_type == MONO_WRAPPER_DELEGATE_END_INVOKE) {
-                       char *tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
-                       full_name = g_strdup_printf ("(wrapper delegate-end-invoke):%s (%s)", method->name, tmpsig);
-                       g_free (tmpsig);
-               } else {
-                       full_name = mono_method_full_name (method, TRUE);
-               }
+               name = mono_aot_wrapper_name (method);
        }
 
        hash = mono_aot_method_hash (method) % table_size;
@@ -2204,19 +2186,23 @@ find_extra_method_in_amodule (MonoAotModule *amodule, MonoMethod *method)
        if (entry [0] == 0)
                return 0xffffff;
 
+       index = 0xffffff;
        while (TRUE) {
                guint32 key = entry [0];
                guint32 value = entry [1];
                guint32 next = entry [entry_size - 1];
                MonoMethod *m;
                guint8 *p;
-               int is_wrapper;
+               int is_wrapper_name;
 
                p = amodule->extra_method_info + key;
-               is_wrapper = decode_value (p, &p);
-               if (is_wrapper) {
-                       if (full_name && !strcmp (full_name, (char*)p))
-                               return value;
+               is_wrapper_name = decode_value (p, &p);
+               if (is_wrapper_name) {
+                       int wrapper_type = decode_value (p, &p);
+                       if (wrapper_type == method->wrapper_type && !strcmp (name, (char*)p)) {
+                               index = value;
+                               break;
+                       }
                } else if (can_method_ref_match_method (amodule, p, method)) {
                        num_checks ++;
                        mono_aot_lock ();
@@ -2237,8 +2223,10 @@ find_extra_method_in_amodule (MonoAotModule *amodule, MonoMethod *method)
                          if (m)
                          printf ("%d %s %s\n", num_checks, mono_method_full_name (method, TRUE), mono_method_full_name (m, TRUE));
                        */
-                       if (m == method)
-                               return value;
+                       if (m == method) {
+                               index = value;
+                               break;
+                       }
                }
 
                if (next != 0)
@@ -2247,7 +2235,8 @@ find_extra_method_in_amodule (MonoAotModule *amodule, MonoMethod *method)
                        break;
        }
 
-       return 0xffffff;
+       g_free (name);
+       return index;
 }
 
 static void
index d7343d396f27f8e1575d7ea149749e80ceb3ff68..934ce8b09f871023de8cbd57322075f8650c0d8c 100644 (file)
@@ -89,7 +89,7 @@ typedef gint64 mgreg_t;
 #define MONO_FAKE_VTABLE_METHOD ((MonoMethod*)GINT_TO_POINTER(-2))
 
 /* Version number of the AOT file format */
-#define MONO_AOT_FILE_VERSION "48"
+#define MONO_AOT_FILE_VERSION "49"
 
 /* Constants used to encode different types of methods in AOT */
 enum {
@@ -1336,6 +1336,7 @@ gpointer mono_aot_get_unbox_trampoline      (MonoMethod *method) MONO_INTERNAL;
 gpointer mono_aot_get_lazy_fetch_trampoline (guint32 slot) MONO_INTERNAL;
 guint8*  mono_aot_get_unwind_info           (MonoJitInfo *ji, guint32 *unwind_info_len) MONO_INTERNAL;
 guint32  mono_aot_method_hash               (MonoMethod *method) MONO_INTERNAL;
+char*    mono_aot_wrapper_name              (MonoMethod *method) MONO_INTERNAL;
 /* This is an exported function */
 void     mono_aot_register_globals          (gpointer *globals);
 /* This too */