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