提交 6f1481f1 编写于 作者: Z Zoltan Varga 提交者: spatil

[runtime] Allocate the memory for gshared gparams from image sets. (#19361)

Fixes https://github.com/mono/mono/issues/18127.
上级 b60101c6
......@@ -2095,10 +2095,6 @@ mono_image_close_except_pools (MonoImage *image)
mono_wrapper_caches_free (&image->wrapper_caches);
for (i = 0; i < image->gshared_types_len; ++i)
free_hash (image->gshared_types [i]);
g_free (image->gshared_types);
/* The ownership of signatures is not well defined */
g_hash_table_destroy (image->memberref_signatures);
g_hash_table_destroy (image->helper_signatures);
......
......@@ -403,11 +403,6 @@ struct _MonoImage {
/* Maps malloc-ed char* pinvoke scope -> malloced-ed char* filename */
GHashTable *pinvoke_scope_filenames;
/* Indexed by MonoGenericParam pointers */
GHashTable **gshared_types;
/* The length of the above array */
int gshared_types_len;
/* The loader used to load this image */
MonoImageLoader *loader;
......@@ -447,6 +442,11 @@ typedef struct {
MonoWrapperCaches wrapper_caches;
/* Indexed by MonoGenericParam pointers */
GHashTable **gshared_types;
/* The length of the above array */
int gshared_types_len;
mono_mutex_t lock;
/*
......@@ -726,6 +726,12 @@ mono_image_set_strdup (MonoImageSet *set, const char *s);
void mono_metadata_image_set_foreach(MonoImageSetFunc func, gpointer user_data);
MonoImageSet *
mono_metadata_get_image_set_for_type (MonoType *type);
MonoImageSet *
mono_metadata_merge_image_sets (MonoImageSet *set1, MonoImageSet *set2);
#define mono_image_set_new0(image,type,size) ((type *) mono_image_set_alloc0 (image, sizeof (type)* (size)))
gboolean
......
......@@ -2624,6 +2624,12 @@ delete_image_set (MonoImageSet *set)
if (set->ptr_cache)
g_hash_table_destroy (set->ptr_cache);
for (i = 0; i < set->gshared_types_len; ++i) {
if (set->gshared_types [i])
g_hash_table_destroy (set->gshared_types [i]);
}
g_free (set->gshared_types);
mono_wrapper_caches_free (&set->wrapper_caches);
image_sets_lock ();
......@@ -3102,19 +3108,25 @@ mono_metadata_get_inflated_signature (MonoMethodSignature *sig, MonoGenericConte
}
MonoImageSet *
mono_metadata_get_image_set_for_class (MonoClass *klass)
mono_metadata_get_image_set_for_type (MonoType *type)
{
MonoImageSet *set;
CollectData image_set_data;
collect_data_init (&image_set_data);
collect_type_images (&klass->byval_arg, &image_set_data);
collect_type_images (type, &image_set_data);
set = get_image_set (image_set_data.images, image_set_data.nimages);
collect_data_free (&image_set_data);
return set;
}
MonoImageSet *
mono_metadata_get_image_set_for_class (MonoClass *klass)
{
return mono_metadata_get_image_set_for_type (&klass->byval_arg);
}
MonoImageSet *
mono_metadata_get_image_set_for_method (MonoMethodInflated *method)
{
......@@ -3129,6 +3141,26 @@ mono_metadata_get_image_set_for_method (MonoMethodInflated *method)
return set;
}
MonoImageSet *
mono_metadata_merge_image_sets (MonoImageSet *set1, MonoImageSet *set2)
{
MonoImage **images = g_newa (MonoImage*, set1->nimages + set2->nimages);
memcpy (images, set1->images, sizeof (MonoImage*) * set1->nimages);
int nimages = set1->nimages;
// FIXME: Quaratic
for (int i = 0; i < set1->nimages; ++i) {
int j;
for (j = 0; j < set2->nimages; ++j) {
if (set1->images [i] == set2->images [j])
break;
}
if (j == set2->nimages)
images [nimages ++] = set2->images [i];
}
return get_image_set (images, nimages);
}
static gboolean
type_is_gtd (MonoType *type)
{
......
......@@ -3460,12 +3460,15 @@ shared_gparam_equal (gconstpointer ka, gconstpointer kb)
MonoType*
mini_get_shared_gparam (MonoType *t, MonoType *constraint)
{
MonoImageSet *set;
MonoGenericParam *par = t->data.generic_param;
MonoGSharedGenericParam *copy, key;
MonoType *res;
MonoImage *image = NULL;
char *name;
set = mono_metadata_merge_image_sets (mono_metadata_get_image_set_for_type (t), mono_metadata_get_image_set_for_type (constraint));
memset (&key, 0, sizeof (key));
key.parent = par;
key.param.param.gshared_constraint = constraint;
......@@ -3477,23 +3480,24 @@ mini_get_shared_gparam (MonoType *t, MonoType *constraint)
* Need a cache to ensure the newly created gparam
* is unique wrt T/CONSTRAINT.
*/
mono_image_lock (image);
if (!image->gshared_types) {
image->gshared_types_len = MONO_TYPE_INTERNAL;
image->gshared_types = g_new0 (GHashTable*, image->gshared_types_len);
}
if (!image->gshared_types [constraint->type])
image->gshared_types [constraint->type] = g_hash_table_new (shared_gparam_hash, shared_gparam_equal);
res = (MonoType *)g_hash_table_lookup (image->gshared_types [constraint->type], &key);
mono_image_unlock (image);
mono_image_set_lock (set);
if (!set->gshared_types) {
set->gshared_types_len = MONO_TYPE_INTERNAL;
set->gshared_types = g_new0 (GHashTable*, set->gshared_types_len);
}
if (!set->gshared_types [constraint->type])
set->gshared_types [constraint->type] = g_hash_table_new (shared_gparam_hash, shared_gparam_equal);
res = (MonoType *)g_hash_table_lookup (set->gshared_types [constraint->type], &key);
mono_image_set_unlock (set);
if (res)
return res;
copy = (MonoGSharedGenericParam *)mono_image_alloc0 (image, sizeof (MonoGSharedGenericParam));
copy = (MonoGSharedGenericParam *)mono_image_set_alloc0 (set, sizeof (MonoGSharedGenericParam));
memcpy (&copy->param, par, sizeof (MonoGenericParamFull));
copy->param.info.pklass = NULL;
constraint = mono_metadata_type_dup (image, constraint);
// FIXME:
constraint = mono_metadata_type_dup (NULL, constraint);
name = get_shared_gparam_name (constraint->type, ((MonoGenericParamFull*)copy)->info.name);
copy->param.info.name = mono_image_strdup (image, name);
copy->param.info.name = mono_image_set_strdup (set, name);
g_free (name);
copy->param.param.owner = par->owner;
......@@ -3503,12 +3507,10 @@ mini_get_shared_gparam (MonoType *t, MonoType *constraint)
res = mono_metadata_type_dup (NULL, t);
res->data.generic_param = (MonoGenericParam*)copy;
if (image) {
mono_image_lock (image);
/* Duplicates are ok */
g_hash_table_insert (image->gshared_types [constraint->type], copy, res);
mono_image_unlock (image);
}
mono_image_set_lock (set);
/* Duplicates are ok */
g_hash_table_insert (set->gshared_types [constraint->type], copy, res);
mono_image_set_unlock (set);
return res;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册