2008-06-12 Rodrigo Kumpera <rkumpera@novell.com>
authorRodrigo Kumpera <kumpera@gmail.com>
Thu, 12 Jun 2008 18:26:31 +0000 (18:26 -0000)
committerRodrigo Kumpera <kumpera@gmail.com>
Thu, 12 Jun 2008 18:26:31 +0000 (18:26 -0000)
* class.c (mono_class_inflate_generic_type_with_mempool):
This function allows to inflate a generic type using
a mempool.

* class.c (inflate_generic_type): Take a mempool as argument
and use it to do type dup'ing.

* class.c (mono_class_setup_fields): Field type for generic
generic classes are allocated from the image mempool.

* metadata.c (free_generic_class): Inflated field type is
now allocated in the image mempool.

svn path=/trunk/mono/; revision=105714

mono/metadata/ChangeLog
mono/metadata/class.c
mono/metadata/metadata.c

index 5f975e6c689bcc618688d0a8f005704f508c4ea3..32957a6ad5fd50fc0d4e77c3145ebbb29ec44292 100644 (file)
@@ -1,3 +1,18 @@
+2008-06-12 Rodrigo Kumpera  <rkumpera@novell.com>
+
+       * class.c (mono_class_inflate_generic_type_with_mempool):
+       This function allows to inflate a generic type using
+       a mempool.
+
+       * class.c (inflate_generic_type): Take a mempool as argument
+       and use it to do type dup'ing.
+
+       * class.c (mono_class_setup_fields): Field type for generic
+       generic classes are allocated from the image mempool.
+
+       * metadata.c (free_generic_class): Inflated field type is
+       now allocated in the image mempool.
+
 2008-06-12 Rodrigo Kumpera  <rkumpera@novell.com>
 
        * threads.c (thread_cleanup): Free MonoThread::name.
index 50507a6e5f31c4ddead1db81767bcdf624ea064d..228a01ba75d4ec3fb7ada5f5ee80a4872b0eaa6b 100644 (file)
@@ -479,7 +479,7 @@ mono_class_is_open_constructed_type (MonoType *t)
 }
 
 static MonoType*
-inflate_generic_type (MonoType *type, MonoGenericContext *context)
+inflate_generic_type (MonoMemPool *mempool, MonoType *type, MonoGenericContext *context)
 {
        switch (type->type) {
        case MONO_TYPE_MVAR: {
@@ -496,7 +496,7 @@ inflate_generic_type (MonoType *type, MonoGenericContext *context)
                 * while the VAR/MVAR duplicates a type from the context.  So, we need to ensure that the
                 * ->byref and ->attrs from @type are propagated to the returned type.
                 */
-               nt = mono_metadata_type_dup (NULL, inst->type_argv [num]);
+               nt = mono_metadata_type_dup (mempool, inst->type_argv [num]);
                nt->byref = type->byref;
                nt->attrs = type->attrs;
                return nt;
@@ -509,27 +509,27 @@ inflate_generic_type (MonoType *type, MonoGenericContext *context)
                        return NULL;
                if (num >= inst->type_argc)
                        g_error ("VAR %d (%s) cannot be expanded in this context with %d instantiations", num, type->data.generic_param->name, inst->type_argc);
-               nt = mono_metadata_type_dup (NULL, inst->type_argv [num]);
+               nt = mono_metadata_type_dup (mempool, inst->type_argv [num]);
                nt->byref = type->byref;
                nt->attrs = type->attrs;
                return nt;
        }
        case MONO_TYPE_SZARRAY: {
                MonoClass *eclass = type->data.klass;
-               MonoType *nt, *inflated = inflate_generic_type (&eclass->byval_arg, context);
+               MonoType *nt, *inflated = inflate_generic_type (NULL, &eclass->byval_arg, context);
                if (!inflated)
                        return NULL;
-               nt = mono_metadata_type_dup (NULL, type);
+               nt = mono_metadata_type_dup (mempool, type);
                nt->data.klass = mono_class_from_mono_type (inflated);
                mono_metadata_free_type (inflated);
                return nt;
        }
        case MONO_TYPE_ARRAY: {
                MonoClass *eclass = type->data.array->eklass;
-               MonoType *nt, *inflated = inflate_generic_type (&eclass->byval_arg, context);
+               MonoType *nt, *inflated = inflate_generic_type (NULL, &eclass->byval_arg, context);
                if (!inflated)
                        return NULL;
-               nt = mono_metadata_type_dup (NULL, type);
+               nt = mono_metadata_type_dup (mempool, type);
                nt->data.array = g_memdup (nt->data.array, sizeof (MonoArrayType));
                nt->data.array->eklass = mono_class_from_mono_type (inflated);
                mono_metadata_free_type (inflated);
@@ -549,7 +549,7 @@ inflate_generic_type (MonoType *type, MonoGenericContext *context)
                if (gclass == type->data.generic_class)
                        return NULL;
 
-               nt = mono_metadata_type_dup (NULL, type);
+               nt = mono_metadata_type_dup (mempool, type);
                nt->data.generic_class = gclass;
                return nt;
        }
@@ -571,7 +571,7 @@ inflate_generic_type (MonoType *type, MonoGenericContext *context)
 
                gclass = mono_metadata_lookup_generic_class (klass, inst, klass->image->dynamic);
 
-               nt = mono_metadata_type_dup (NULL, type);
+               nt = mono_metadata_type_dup (mempool, type);
                nt->type = MONO_TYPE_GENERICINST;
                nt->data.generic_class = gclass;
                return nt;
@@ -594,6 +594,24 @@ mono_class_get_context (MonoClass *class)
        return class->generic_class ? mono_generic_class_get_context (class->generic_class) : NULL;
 }
 
+/*
+ * This method allows specifying a mempool to do type duping, if needed. 
+ */
+static MonoType*
+mono_class_inflate_generic_type_with_mempool (MonoMemPool *mempool, MonoType *type, MonoGenericContext *context)
+{
+       MonoType *inflated = NULL; 
+
+       if (context)
+               inflated = inflate_generic_type (mempool, type, context);
+
+       if (!inflated)
+               return mono_metadata_type_dup (mempool, type);
+
+       mono_stats.inflated_type_count++;
+       return inflated;
+}
+
 /*
  * mono_class_inflate_generic_type:
  * @type: a type
@@ -608,18 +626,10 @@ mono_class_get_context (MonoClass *class)
 MonoType*
 mono_class_inflate_generic_type (MonoType *type, MonoGenericContext *context)
 {
-       MonoType *inflated = NULL; 
-
-       if (context)
-               inflated = inflate_generic_type (type, context);
-
-       if (!inflated)
-               return mono_metadata_type_dup (NULL, type);
-
-       mono_stats.inflated_type_count++;
-       return inflated;
+       return mono_class_inflate_generic_type_with_mempool (NULL, type, context);
 }
 
+
 static MonoGenericContext
 inflate_generic_context (MonoGenericContext *context, MonoGenericContext *inflate_with)
 {
@@ -771,7 +781,7 @@ mono_class_inflate_generic_method_full (MonoMethod *method, MonoClass *klass_hin
                result->klass = klass_hint;
 
        if (!result->klass) {
-               MonoType *inflated = inflate_generic_type (&method->klass->byval_arg, context);
+               MonoType *inflated = inflate_generic_type (NULL, &method->klass->byval_arg, context);
                result->klass = inflated ? mono_class_from_mono_type (inflated) : method->klass;
                if (inflated)
                        mono_metadata_free_type (inflated);
@@ -886,6 +896,7 @@ mono_class_find_enum_basetype (MonoClass *class)
                if (!ftype)
                        return NULL;
                if (class->generic_class) {
+                       //FIXME do we leak here?
                        ftype = mono_class_inflate_generic_type (ftype, mono_class_get_context (class));
                        ftype->attrs = cols [MONO_FIELD_FLAGS];
                }
@@ -1009,7 +1020,8 @@ mono_class_setup_fields (MonoClass *class)
                        ifield->generic_type = gfield->type;
                        field->name = gfield->name;
                        field->generic_info = ifield;
-                       field->type = mono_class_inflate_generic_type (gfield->type, mono_class_get_context (class));
+                       /*This memory must come from the image mempool as we don't have a change to free it.*/
+                       field->type = mono_class_inflate_generic_type_with_mempool (class->image->mempool, gfield->type, mono_class_get_context (class));
                        field->type->attrs = gfield->type->attrs;
                        if (mono_field_is_deleted (field))
                                continue;
@@ -4669,7 +4681,7 @@ mono_type_retrieve_from_typespec (MonoImage *image, guint32 type_spec, MonoGener
        if (!t)
                return NULL;
        if (context && (context->class_inst || context->method_inst)) {
-               MonoType *inflated = inflate_generic_type (t, context);
+               MonoType *inflated = inflate_generic_type (NULL, t, context);
                if (inflated) {
                        t = inflated;
                        *did_inflate = TRUE;
index 1ba56b2769207544e5c72fa27c92500656d65d9d..ca71361d6b753655df93733865ad9e40946242f0 100644 (file)
@@ -2243,7 +2243,6 @@ free_generic_class (MonoGenericClass *gclass)
                if (class->fields) {
                        for (i = 0; i < class->field.count; ++i) {
                                g_free (class->fields [i].generic_info);
-                               mono_metadata_free_type (class->fields [i].type);
                        }
                }
                /* Allocated in mono_generic_class_get_class () */