[jit] Cache gsharedvt types in get_gsharedvt_type ().
authorZoltan Varga <vargaz@gmail.com>
Sat, 14 Dec 2013 06:05:22 +0000 (07:05 +0100)
committerZoltan Varga <vargaz@gmail.com>
Sat, 14 Dec 2013 06:05:22 +0000 (07:05 +0100)
mono/metadata/image.c
mono/metadata/metadata-internals.h
mono/mini/mini.c

index 1673eededde9e24b0f5b98a259f625980bc98ab1..dcb5c399a62edab973fd29eba6650b7071ab56ba 100644 (file)
@@ -1650,6 +1650,7 @@ mono_image_close_except_pools (MonoImage *image)
        free_hash (image->native_wrapper_aot_cache);
        free_hash (image->pinvoke_scopes);
        free_hash (image->pinvoke_scope_filenames);
+       free_hash (image->gsharedvt_types);
 
        /* The ownership of signatures is not well defined */
        g_hash_table_destroy (image->memberref_signatures);
index 497d77b12dcb3049215409ff5cb6e4b71abe1976..53ff05e493c2c2c8956a0e5d42c49f7b00f94e4f 100644 (file)
@@ -337,6 +337,9 @@ struct _MonoImage {
        /* Maps malloc-ed char* pinvoke scope -> malloced-ed char* filename */
        GHashTable *pinvoke_scope_filenames;
 
+       /* Indexed by MonoGenericParam pointers */
+       GHashTable *gsharedvt_types;
+
        /*
         * No other runtime locks must be taken while holding this lock.
         * It's meant to be used only to mutate and query structures part of this image.
index cfad4d6acf5e4a1672f2f9264092f114937d13a2..7e7449e5990d8da391849a232cd6fa5c35ddf1ad 100644 (file)
@@ -4598,6 +4598,7 @@ get_gsharedvt_type (MonoType *t)
        MonoGenericParam *par = t->data.generic_param;
        MonoGenericParam *copy;
        MonoType *res;
+       MonoImage *image = NULL;
 
        /* 
         * Create an anonymous gparam with a different serial so normal gshared and gsharedvt methods have
@@ -4605,7 +4606,16 @@ get_gsharedvt_type (MonoType *t)
         */
        g_assert (mono_generic_param_info (par));
        if (par->owner) {
-               copy = mono_image_alloc0 (par->owner->image, sizeof (MonoGenericParamFull));
+               image = par->owner->image;
+
+               mono_image_lock (image);
+               if (!image->gsharedvt_types)
+                       image->gsharedvt_types = g_hash_table_new (NULL, NULL);
+               res = g_hash_table_lookup (image->gsharedvt_types, par);
+               mono_image_unlock (image);
+               if (res)
+                       return res;
+               copy = mono_image_alloc0 (image, sizeof (MonoGenericParamFull));
                memcpy (copy, par, sizeof (MonoGenericParamFull));
        } else {
                copy = g_memdup (par, sizeof (MonoGenericParamFull));
@@ -4617,6 +4627,13 @@ get_gsharedvt_type (MonoType *t)
        res = mono_metadata_type_dup (NULL, t);
        res->data.generic_param = copy;
 
+       if (par->owner) {
+               mono_image_lock (image);
+               /* Duplicates are ok */
+               g_hash_table_insert (image->gsharedvt_types, par, res);
+               mono_image_unlock (image);
+       }
+
        return res;
 }