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);
/* 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.
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
*/
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));
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;
}