Author: zoltan
Date: 2007-05-10 18:11:31 -0400 (Thu, 10 May 2007)
New Revision: 77168

Modified:
   trunk/mono/mono/mini/ChangeLog
   trunk/mono/mono/mini/aot-compiler.c
   trunk/mono/mono/mini/aot-runtime.c
   trunk/mono/mono/mini/mini.c
   trunk/mono/mono/mini/mini.h
Log:
2007-05-11  Zoltan Varga  <[EMAIL PROTECTED]>

        * mini.h (MONO_AOT_FILE_VERSION): Bump AOT file version.

        * mini.h (MonoCompile): Add 'token_info_hash' field.

        * mini.c: Save token->method associations during compilation so the AOT 
        compiler can use it.
        
        * aot-compiler.c aot-runtime.c: Add support for compiling non-generic 
methods
        which reference generic classes and methods.


Modified: trunk/mono/mono/mini/ChangeLog
===================================================================
--- trunk/mono/mono/mini/ChangeLog      2007-05-10 21:51:32 UTC (rev 77167)
+++ trunk/mono/mono/mini/ChangeLog      2007-05-10 22:11:31 UTC (rev 77168)
@@ -1,3 +1,15 @@
+2007-05-11  Zoltan Varga  <[EMAIL PROTECTED]>
+
+       * mini.h (MONO_AOT_FILE_VERSION): Bump AOT file version.
+
+       * mini.h (MonoCompile): Add 'token_info_hash' field.
+
+       * mini.c: Save token->method associations during compilation so the AOT 
+       compiler can use it.
+       
+       * aot-compiler.c aot-runtime.c: Add support for compiling non-generic 
methods
+       which reference generic classes and methods.
+
 2007-05-10  Zoltan Varga  <[EMAIL PROTECTED]>
 
        * mini.h mini-<ARCH>.h: Get rid of MONO_ARCH_HAS_XP_LOCAL_REGALLOC.

Modified: trunk/mono/mono/mini/aot-compiler.c
===================================================================
--- trunk/mono/mono/mini/aot-compiler.c 2007-05-10 21:51:32 UTC (rev 77167)
+++ trunk/mono/mono/mini/aot-compiler.c 2007-05-10 22:11:31 UTC (rev 77168)
@@ -109,6 +109,7 @@
        GPtrArray *shared_patches;
        GHashTable *image_hash;
        GHashTable *method_to_cfg;
+       GHashTable *token_info_hash;
        GPtrArray *image_table;
        GList *method_order;
        guint32 got_offset, plt_offset;
@@ -1583,16 +1584,40 @@
        }
 }
 
+static guint32
+find_typespec_for_class (MonoAotCompile *acfg, MonoClass *klass)
+{
+       int i;
+       MonoClass *k = NULL;
+
+       /* FIXME: Search referenced images as well */
+       for (i = 0; i < acfg->image->tables [MONO_TABLE_TYPESPEC].rows; ++i) {
+               /* Since we don't compile generic methods, the context is empty 
*/
+               k = mono_class_get_full (acfg->image, MONO_TOKEN_TYPE_SPEC | (i 
+ 1), NULL);
+               if (k == klass)
+                       break;
+       }
+
+       g_assert (k);
+
+       return MONO_TOKEN_TYPE_SPEC | (i + 1);
+}
+
 static void
-encode_klass_info (MonoAotCompile *cfg, MonoClass *klass, guint8 *buf, guint8 
**endbuf)
+encode_klass_info (MonoAotCompile *acfg, MonoClass *klass, guint8 *buf, guint8 
**endbuf)
 {
-       if (!klass->type_token) {
+       if (klass->generic_class) {
+               g_assert (klass->type_token);
+
+               encode_value (find_typespec_for_class (acfg, klass), buf, &buf);
+               encode_value (get_image_index (acfg, acfg->image), buf, &buf);
+       } else if (!klass->type_token) {
                guint32 token;
 
                /* Array class */
                g_assert (klass->rank > 0);
                encode_value (MONO_TOKEN_TYPE_DEF, buf, &buf);
-               encode_value (get_image_index (cfg, klass->image), buf, &buf);
+               encode_value (get_image_index (acfg, klass->image), buf, &buf);
                token = klass->element_class->type_token;
                if (!token) {
                        /* <Type>[][] */
@@ -1608,7 +1633,7 @@
        else {
                g_assert (mono_metadata_token_code (klass->type_token) == 
MONO_TOKEN_TYPE_DEF);
                encode_value (klass->type_token - MONO_TOKEN_TYPE_DEF, buf, 
&buf);
-               encode_value (get_image_index (cfg, klass->image), buf, &buf);
+               encode_value (get_image_index (acfg, klass->image), buf, &buf);
        }
        *endbuf = buf;
 }
@@ -1624,15 +1649,60 @@
        *endbuf = buf;
 }
 
+#if 0
+static guint32
+find_methodspec_for_method (MonoAotCompile *acfg, MonoMethod *method)
+{
+       int i;
+       MonoMethod *m = NULL;
+
+       /* FIXME: Search referenced images as well */
+       for (i = 0; i < acfg->image->tables [MONO_TABLE_METHODSPEC].rows; ++i) {
+               /* Since we don't compile generic methods, the context is empty 
*/
+               m = mono_get_method_full (acfg->image, MONO_TOKEN_METHOD_SPEC | 
(i + 1), NULL, NULL);
+               if (m == method)
+                       break;
+       }
+
+       g_assert (m);
+
+       return MONO_TOKEN_METHOD_SPEC | (i + 1);
+}
+#endif
+
 static void
 encode_method_ref (MonoAotCompile *acfg, MonoMethod *method, guint8 *buf, 
guint8 **endbuf)
 {
        guint32 image_index = get_image_index (acfg, method->klass->image);
        guint32 token = method->token;
-       g_assert (image_index < 256);
-       g_assert (mono_metadata_token_table (token) == MONO_TABLE_METHOD);
+       MonoJumpInfoToken *ji;
 
-       encode_value ((image_index << 24) + (mono_metadata_token_index 
(token)), buf, &buf);
+       g_assert (image_index < 255);
+
+       if (method->klass->generic_class || mono_method_signature 
(method)->is_inflated) {
+               /* 
+                * This is a generic method, find the original token which 
referenced it and
+                * encode that.
+                */
+               /* This doesn't work for some reason */
+               /*
+               image_index = get_image_index (acfg, acfg->image);
+               g_assert (image_index < 255);
+               token = find_methodspec_for_method (acfg, method);
+               */
+               /* Obtain the token from information recorded by the JIT */
+               ji = g_hash_table_lookup (acfg->token_info_hash, method);
+               image_index = get_image_index (acfg, ji->image);
+               g_assert (image_index < 255);
+               token = ji->token;
+
+               encode_value ((255 << 24), buf, &buf);
+               encode_value (image_index, buf, &buf);
+               encode_value (token, buf, &buf);
+       } else {
+               g_assert (mono_metadata_token_table (token) == 
MONO_TABLE_METHOD);
+               encode_value ((image_index << 24) | mono_metadata_token_index 
(token), buf, &buf);
+       }
        *endbuf = buf;
 }
 
@@ -2509,6 +2579,19 @@
 }
 
 static void
+add_token_info_hash (gpointer key, gpointer value, gpointer user_data)
+{
+       MonoMethod *method = (MonoMethod*)key;
+       MonoJumpInfoToken *ji = (MonoJumpInfoToken*)value;
+       MonoJumpInfoToken *new_ji = g_new0 (MonoJumpInfoToken, 1);
+       MonoAotCompile *acfg = user_data;
+
+       new_ji->image = ji->image;
+       new_ji->token = ji->token;
+       g_hash_table_insert (acfg->token_info_hash, method, new_ji);
+}
+
+static void
 compile_method (MonoAotCompile *acfg, int index)
 {
        MonoCompile *cfg;
@@ -2567,6 +2650,9 @@
                return;
        }
 
+       /* Collect method->token associations from the cfg */
+       g_hash_table_foreach (cfg->token_info_hash, add_token_info_hash, acfg);
+
        skip = FALSE;
        for (patch_info = cfg->patch_info; patch_info; patch_info = 
patch_info->next) {
                switch (patch_info->type) {
@@ -2586,42 +2672,6 @@
                return;
        }
 
-       /* 
-        * We can't currently handle instantinated generic types/methods
-        * since we save typedef/methoddef tokens, instead of 
typespec/methodref/methodspec 
-        * tokens.
-        */
-       for (patch_info = cfg->patch_info; patch_info; patch_info = 
patch_info->next) {
-               switch (patch_info->type) {
-               case MONO_PATCH_INFO_METHOD:
-               case MONO_PATCH_INFO_METHODCONST:
-                       /* Methods of instantinated generic types */
-                       if (patch_info->data.method->klass->generic_class)
-                               skip = TRUE;
-                       /* Instantinated generic methods */
-                       if (mono_method_signature 
(patch_info->data.method)->is_inflated)
-                               skip = TRUE;
-                       break;
-               case MONO_PATCH_INFO_VTABLE:
-               case MONO_PATCH_INFO_CLASS:
-               case MONO_PATCH_INFO_IID:
-               case MONO_PATCH_INFO_ADJUSTED_IID:
-               case MONO_PATCH_INFO_CLASS_INIT:
-                       if (patch_info->data.klass->generic_class)
-                               skip = TRUE;
-                       break;
-                       /* FIXME: Add more types of patches */
-               default:
-                       break;
-               }
-       }
-
-       if (skip) {
-               acfg->stats.genericcount++;
-               mono_destroy_compile (cfg);
-               return;
-       }
-
        skip = FALSE;
        for (patch_info = cfg->patch_info; patch_info; patch_info = 
patch_info->next) {
                if (patch_info->type == MONO_PATCH_INFO_METHOD_JUMP) {
@@ -3294,6 +3344,7 @@
        acfg->patch_to_shared_got_offset = g_hash_table_new 
(mono_patch_info_hash, mono_patch_info_equal);
        acfg->shared_patches = g_ptr_array_new ();
        acfg->method_to_cfg = g_hash_table_new (NULL, NULL);
+       acfg->token_info_hash = g_hash_table_new (NULL, NULL);
        acfg->image_hash = g_hash_table_new (NULL, NULL);
        acfg->image_table = g_ptr_array_new ();
        acfg->image = image;
@@ -3364,6 +3415,7 @@
        emit_writeout (acfg);
 
        printf ("Compiled %d out of %d methods (%d%%)\n", acfg->stats.ccount, 
acfg->stats.mcount, acfg->stats.mcount ? (acfg->stats.ccount * 100) / 
acfg->stats.mcount : 100);
+       printf ("%d methods are generic (%d%%)\n", acfg->stats.genericcount, 
acfg->stats.mcount ? (acfg->stats.genericcount * 100) / acfg->stats.mcount : 
100);
        printf ("%d methods contain absolute addresses (%d%%)\n", 
acfg->stats.abscount, acfg->stats.mcount ? (acfg->stats.abscount * 100) / 
acfg->stats.mcount : 100);
        printf ("%d methods contain wrapper references (%d%%)\n", 
acfg->stats.wrappercount, acfg->stats.mcount ? (acfg->stats.wrappercount * 100) 
/ acfg->stats.mcount : 100);
        printf ("%d methods contain lmf pointers (%d%%)\n", 
acfg->stats.lmfcount, acfg->stats.mcount ? (acfg->stats.lmfcount * 100) / 
acfg->stats.mcount : 100);

Modified: trunk/mono/mono/mini/aot-runtime.c
===================================================================
--- trunk/mono/mono/mini/aot-runtime.c  2007-05-10 21:51:32 UTC (rev 77167)
+++ trunk/mono/mono/mini/aot-runtime.c  2007-05-10 22:11:31 UTC (rev 77168)
@@ -235,9 +235,12 @@
        image = load_image (module, image_index);
        if (!image)
                return NULL;
-       if (mono_metadata_token_code (token) == 0) {
+       if (mono_metadata_token_table (token) == 0) {
                klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF + token);
+       } else if (mono_metadata_token_table (token) == MONO_TABLE_TYPESPEC) {
+               klass = mono_class_get (image, token);
        } else {
+               g_assert (mono_metadata_token_table (token) == 
MONO_TABLE_TYPEDEF);
                token = MONO_TOKEN_TYPE_DEF + decode_value (buf, &buf);
                rank = decode_value (buf, &buf);
                if (token == MONO_TOKEN_TYPE_DEF) {
@@ -289,6 +292,12 @@
        image_index = value >> 24;
        *token = MONO_TOKEN_METHOD_DEF | (value & 0xffffff);
 
+       if (image_index == 255) {
+               /* Methodspec */
+               image_index = decode_value (buf, &buf);
+               *token = decode_value (buf, &buf);
+       }
+
        image = load_image (module, image_index);
        if (!image)
                return NULL;
@@ -1099,18 +1108,14 @@
        case MONO_PATCH_INFO_METHOD:
        case MONO_PATCH_INFO_METHODCONST:
        case MONO_PATCH_INFO_METHOD_JUMP: {
-               guint32 image_index, token, value;
+               guint32 token;
 
-               value = decode_value (p, &p);
-               image_index = value >> 24;
-               token = MONO_TOKEN_METHOD_DEF | (value & 0xffffff);
-
-               image = load_image (aot_module, image_index);
+               image = decode_method_ref (aot_module, &token, buf, &buf);
                if (!image)
                        goto cleanup;
 
 #ifdef MONO_ARCH_HAVE_CREATE_TRAMPOLINE_FROM_TOKEN
-               if (ji->type == MONO_PATCH_INFO_METHOD) {
+               if ((ji->type == MONO_PATCH_INFO_METHOD) && 
(mono_metadata_token_table (token) == MONO_TABLE_METHOD)) {
                        ji->data.target = mono_create_jit_trampoline_from_token 
(image, token);
                        ji->type = MONO_PATCH_INFO_ABS;
                }

Modified: trunk/mono/mono/mini/mini.c
===================================================================
--- trunk/mono/mono/mini/mini.c 2007-05-10 21:51:32 UTC (rev 77167)
+++ trunk/mono/mono/mini/mini.c 2007-05-10 22:11:31 UTC (rev 77168)
@@ -2115,6 +2115,17 @@
        cfg->patch_info = ji;
 }
 
+static void
+mono_save_token_info (MonoCompile *cfg, MonoImage *image, guint32 token, 
gpointer key)
+{
+       if (cfg->compile_aot) {
+               MonoJumpInfoToken *jump_info_token = mono_mempool_alloc0 
(cfg->mempool, sizeof (MonoJumpInfoToken));
+               jump_info_token->image = image;
+               jump_info_token->token = token;
+               g_hash_table_insert (cfg->token_info_hash, key, 
jump_info_token);
+       }
+}
+
 /*
  * When we add a tree of instructions, we need to ensure the instructions 
currently
  * on the stack are executed before (like, if we load a value from a local).
@@ -4625,6 +4636,8 @@
                                        fsig = mono_method_get_signature_full 
(cmethod, image, token, generic_context);
                                }
 
+                               mono_save_token_info (cfg, image, token, 
cmethod);
+
                                n = fsig->param_count + fsig->hasthis;
 
                                if (mono_use_security_manager) {
@@ -5609,6 +5622,8 @@
                                goto load_error;
                        fsig = mono_method_get_signature (cmethod, image, 
token);
 
+                       mono_save_token_info (cfg, image, token, cmethod);
+
                        if (!mono_class_init (cmethod->klass))
                                goto load_error;
 
@@ -8650,6 +8665,7 @@
                g_hash_table_destroy (cfg->exvars);
        mono_mempool_destroy (cfg->mempool);
        g_list_free (cfg->ldstr_list);
+       g_hash_table_destroy (cfg->token_info_hash);
 
        g_free (cfg->varinfo);
        g_free (cfg->vars);
@@ -10349,6 +10365,7 @@
        cfg->verbose_level = mini_verbose;
        cfg->compile_aot = compile_aot;
        cfg->skip_visibility = method->skip_visibility;
+       cfg->token_info_hash = g_hash_table_new (NULL, NULL);
        if (!header) {
                cfg->exception_type = MONO_EXCEPTION_INVALID_PROGRAM;
                cfg->exception_message = g_strdup_printf ("Missing or incorrect 
header for method %s", cfg->method->name);

Modified: trunk/mono/mono/mini/mini.h
===================================================================
--- trunk/mono/mono/mini/mini.h 2007-05-10 21:51:32 UTC (rev 77167)
+++ trunk/mono/mono/mini/mini.h 2007-05-10 22:11:31 UTC (rev 77168)
@@ -50,7 +50,7 @@
 #endif
 
 /* Version number of the AOT file format */
-#define MONO_AOT_FILE_VERSION "31"
+#define MONO_AOT_FILE_VERSION "32"
 
 #if 0
 #define mono_bitset_foreach_bit(set,b,n) \
@@ -603,6 +603,7 @@
        guint32          lmf_offset;
        guint16          *intvars;
        MonoProfileCoverageInfo *coverage_info;
+       GHashTable       *token_info_hash;
        MonoCompileArch  arch;
        guint32          exception_type;        /* MONO_EXCEPTION_* */
        guint32          exception_data;

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to