X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fmetadata.c;h=aafcbb55e121991306c9cc99078ec3dfe264769c;hb=6963bb4a65b95aa2716bce869696cde13abb8732;hp=4f1cfaf04154bc596df2b0c9703b7516a08239ec;hpb=0fadfc5c04c5d9101dd076fe71b2559fdd74a210;p=mono.git diff --git a/mono/metadata/metadata.c b/mono/metadata/metadata.c index 4f1cfaf0415..aafcbb55e12 100644 --- a/mono/metadata/metadata.c +++ b/mono/metadata/metadata.c @@ -36,7 +36,7 @@ typedef struct { MonoGenericContext context; } MonoInflatedMethodSignature; -static gboolean do_mono_metadata_parse_type (MonoType *type, MonoImage *m, MonoGenericContainer *container, +static gboolean do_mono_metadata_parse_type (MonoType *type, MonoImage *m, MonoGenericContainer *container, gboolean transient, const char *ptr, const char **rptr); static gboolean do_mono_metadata_type_equal (MonoType *t1, MonoType *t2, gboolean signature_only); @@ -1245,27 +1245,29 @@ mono_metadata_parse_custom_mod (MonoImage *m, MonoCustomMod *dest, const char *p } /* - * mono_metadata_parse_array_full: + * mono_metadata_parse_array_internal: * @m: a metadata context. + * @transient: whenever to allocate data from the heap * @ptr: a pointer to an encoded array description. * @rptr: pointer updated to match the end of the decoded stream * * Decodes the compressed array description found in the metadata @m at @ptr. * * Returns: a #MonoArrayType structure describing the array type - * and dimensions. Memory is allocated from the image mempool. + * and dimensions. Memory is allocated from the heap or from the image mempool, depending + * on the value of @transient. * * LOCKING: Acquires the loader lock */ -MonoArrayType * -mono_metadata_parse_array_full (MonoImage *m, MonoGenericContainer *container, - const char *ptr, const char **rptr) +static MonoArrayType * +mono_metadata_parse_array_internal (MonoImage *m, MonoGenericContainer *container, + gboolean transient, const char *ptr, const char **rptr) { int i; MonoArrayType *array; MonoType *etype; - array = mono_image_alloc0 (m, sizeof (MonoArrayType)); + array = transient ? g_malloc0 (sizeof (MonoArrayType)) : mono_image_alloc0 (m, sizeof (MonoArrayType)); etype = mono_metadata_parse_type_full (m, container, MONO_PARSE_TYPE, 0, ptr, &ptr); if (!etype) return NULL; @@ -1274,13 +1276,13 @@ mono_metadata_parse_array_full (MonoImage *m, MonoGenericContainer *container, array->numsizes = mono_metadata_decode_value (ptr, &ptr); if (array->numsizes) - array->sizes = mono_image_alloc0 (m, sizeof (int) * array->numsizes); + array->sizes = transient ? g_malloc0 (sizeof (int) * array->numsizes) : mono_image_alloc0 (m, sizeof (int) * array->numsizes); for (i = 0; i < array->numsizes; ++i) array->sizes [i] = mono_metadata_decode_value (ptr, &ptr); array->numlobounds = mono_metadata_decode_value (ptr, &ptr); if (array->numlobounds) - array->lobounds = mono_image_alloc0 (m, sizeof (int) * array->numlobounds); + array->lobounds = transient ? g_malloc0 (sizeof (int) * array->numlobounds) : mono_image_alloc0 (m, sizeof (int) * array->numlobounds); for (i = 0; i < array->numlobounds; ++i) array->lobounds [i] = mono_metadata_decode_signed_value (ptr, &ptr); @@ -1289,6 +1291,13 @@ mono_metadata_parse_array_full (MonoImage *m, MonoGenericContainer *container, return array; } +MonoArrayType * +mono_metadata_parse_array_full (MonoImage *m, MonoGenericContainer *container, + const char *ptr, const char **rptr) +{ + return mono_metadata_parse_array_internal (m, container, FALSE, ptr, rptr); +} + MonoArrayType * mono_metadata_parse_array (MonoImage *m, const char *ptr, const char **rptr) { @@ -1495,6 +1504,7 @@ mono_metadata_cleanup (void) * @opt_attrs: optional attributes to store in the returned type * @ptr: pointer to the type representation * @rptr: pointer updated to match the end of the decoded stream + * @transient: whenever to allocate the result from the heap or from a mempool * * Decode a compressed type description found at @ptr in @m. * @mode can be one of MONO_PARSE_MOD_TYPE, MONO_PARSE_PARAM, MONO_PARSE_RET, @@ -1507,15 +1517,14 @@ mono_metadata_cleanup (void) * (stored in image->property_hash) generic container. * When we encounter any MONO_TYPE_VAR or MONO_TYPE_MVAR's, they're looked up in * this MonoGenericContainer. - * This is a Mono runtime internal function. * * LOCKING: Acquires the loader lock. * * Returns: a #MonoType structure representing the decoded type. */ -MonoType* -mono_metadata_parse_type_full (MonoImage *m, MonoGenericContainer *container, MonoParseTypeMode mode, - short opt_attrs, const char *ptr, const char **rptr) +static MonoType* +mono_metadata_parse_type_internal (MonoImage *m, MonoGenericContainer *container, MonoParseTypeMode mode, + short opt_attrs, gboolean transient, const char *ptr, const char **rptr) { MonoType *type, *cached; MonoType stype; @@ -1557,7 +1566,10 @@ mono_metadata_parse_type_full (MonoImage *m, MonoGenericContainer *container, Mo } if (count) { - type = mono_image_alloc0 (m, MONO_SIZEOF_TYPE + ((gint32)count) * sizeof (MonoCustomMod)); + int size; + + size = MONO_SIZEOF_TYPE + ((gint32)count) * sizeof (MonoCustomMod); + type = transient ? g_malloc0 (size) : mono_image_alloc0 (m, size); type->num_mods = count; if (count > 64) g_warning ("got more than 64 modifiers in type"); @@ -1593,14 +1605,14 @@ mono_metadata_parse_type_full (MonoImage *m, MonoGenericContainer *container, Mo type->byref = byref; type->pinned = pinned ? 1 : 0; - if (!do_mono_metadata_parse_type (type, m, container, ptr, &ptr)) { + if (!do_mono_metadata_parse_type (type, m, container, transient, ptr, &ptr)) { return NULL; } if (rptr) *rptr = ptr; - if (!type->num_mods) { + if (!type->num_mods && !transient) { /* no need to free type here, because it is on the stack */ if ((type->type == MONO_TYPE_CLASS || type->type == MONO_TYPE_VALUETYPE) && !type->pinned && !type->attrs) { MonoType *ret = type->byref ? &type->data.klass->this_arg : &type->data.klass->byval_arg; @@ -1636,12 +1648,19 @@ mono_metadata_parse_type_full (MonoImage *m, MonoGenericContainer *container, Mo /* printf ("%x %x %c %s\n", type->attrs, type->num_mods, type->pinned ? 'p' : ' ', mono_type_full_name (type)); */ if (type == &stype) { - type = mono_image_alloc (m, MONO_SIZEOF_TYPE); + type = transient ? g_malloc (MONO_SIZEOF_TYPE) : mono_image_alloc (m, MONO_SIZEOF_TYPE); memcpy (type, &stype, MONO_SIZEOF_TYPE); } return type; } +MonoType* +mono_metadata_parse_type_full (MonoImage *m, MonoGenericContainer *container, MonoParseTypeMode mode, + short opt_attrs, const char *ptr, const char **rptr) +{ + return mono_metadata_parse_type_internal (m, container, mode, opt_attrs, FALSE, ptr, rptr); +} + /* * LOCKING: Acquires the loader lock. */ @@ -2640,10 +2659,22 @@ free_generic_class_dependents (MonoGenericClass *gclass) /* Allocated in mono_class_init () */ g_free (class->methods); - if (class->ext) + if (class->ext) { g_free (class->ext->properties); + g_free (class->ext->field_def_values); + } + /* Allocated in mono_class_setup_fields () */ + g_free (class->fields); + /* Allocated in mono_class_setup_vtable_general () */ + g_free (class->vtable); /* Allocated in mono_generic_class_get_class () */ g_free (class->interfaces); + /* Allocated in setup_interface_offsets () */ + g_free (class->interfaces_packed); + g_free (class->interface_offsets_packed); + g_free (class->interface_bitmap); + /* Allocated in mono_class_setup_supertypes () */ + g_free (class->supertypes); l = g_slist_prepend (l, class); } else if (gclass->is_dynamic) { MonoDynamicGenericClass *dgclass = (MonoDynamicGenericClass *)gclass; @@ -3075,6 +3106,7 @@ mono_metadata_get_shared_type (MonoType *type) * @type: MonoType to be filled in with the return value * @m: image context * @generic_context: generics_context + * @transient: whenever to allocate data from the heap * @ptr: pointer to the encoded type * @rptr: pointer where the end of the encoded type is saved * @@ -3092,7 +3124,7 @@ mono_metadata_get_shared_type (MonoType *type) */ static gboolean do_mono_metadata_parse_type (MonoType *type, MonoImage *m, MonoGenericContainer *container, - const char *ptr, const char **rptr) + gboolean transient, const char *ptr, const char **rptr) { gboolean ok = TRUE; type->type = mono_metadata_decode_value (ptr, &ptr); @@ -3136,7 +3168,7 @@ do_mono_metadata_parse_type (MonoType *type, MonoImage *m, MonoGenericContainer break; } case MONO_TYPE_PTR: - type->data.type = mono_metadata_parse_type_full (m, container, MONO_PARSE_MOD_TYPE, 0, ptr, &ptr); + type->data.type = mono_metadata_parse_type_internal (m, container, MONO_PARSE_MOD_TYPE, 0, transient, ptr, &ptr); if (!type->data.type) return FALSE; break; @@ -3146,7 +3178,7 @@ do_mono_metadata_parse_type (MonoType *type, MonoImage *m, MonoGenericContainer return FALSE; break; case MONO_TYPE_ARRAY: - type->data.array = mono_metadata_parse_array_full (m, container, ptr, &ptr); + type->data.array = mono_metadata_parse_array_internal (m, container, transient, ptr, &ptr); if (!type->data.array) return FALSE; break; @@ -3392,7 +3424,7 @@ mono_method_get_header_summary (MonoMethod *method, MonoMethodHeaderSummary *sum * * LOCKING: Acquires the loader lock. * - * Returns: a MonoMethodHeader allocated from the image mempool. + * Returns: a transient MonoMethodHeader allocated from the heap. */ MonoMethodHeader * mono_metadata_parse_mh_full (MonoImage *m, MonoGenericContainer *container, const char *ptr) @@ -3474,10 +3506,11 @@ mono_metadata_parse_mh_full (MonoImage *m, MonoGenericContainer *container, cons mh = g_malloc0 (MONO_SIZEOF_METHOD_HEADER + len * sizeof (MonoType*) + num_clauses * sizeof (MonoExceptionClause)); mh->num_locals = len; for (i = 0; i < len; ++i) { - mh->locals [i] = mono_metadata_parse_type_full ( - m, container, MONO_PARSE_LOCAL, 0, locals_ptr, &locals_ptr); + mh->locals [i] = mono_metadata_parse_type_internal (m, container, + MONO_PARSE_LOCAL, 0, TRUE, locals_ptr, &locals_ptr); if (!mh->locals [i]) { g_free (clauses); + g_free (mh); return NULL; } } @@ -3533,12 +3566,17 @@ mono_metadata_parse_mh (MonoImage *m, const char *ptr) void mono_metadata_free_mh (MonoMethodHeader *mh) { + int i; + /* If it is not transient it means it's part of a wrapper method, * or a SRE-generated method, so the lifetime in that case is * dictated by the method's own lifetime */ - if (mh->is_transient) + if (mh->is_transient) { + for (i = 0; i < mh->num_locals; ++i) + mono_metadata_free_type (mh->locals [i]); g_free (mh); + } } /* @@ -4516,9 +4554,20 @@ mono_metadata_type_hash (MonoType *t1) switch (t1->type) { case MONO_TYPE_VALUETYPE: case MONO_TYPE_CLASS: - case MONO_TYPE_SZARRAY: - /* check if the distribution is good enough */ - return ((hash << 5) - hash) ^ mono_metadata_str_hash (t1->data.klass->name); + case MONO_TYPE_SZARRAY: { + MonoClass *class = t1->data.klass; + /* + * Dynamic classes must not be hashed on their type since it can change + * during runtime. For example, if we hash a reference type that is + * later made into a valuetype. + * + * This is specially problematic with generic instances since they are + * inserted in a bunch of hash tables before been finished. + */ + if (class->image->dynamic) + return (t1->byref << 6) | mono_metadata_str_hash (class->name); + return ((hash << 5) - hash) ^ mono_metadata_str_hash (class->name); + } case MONO_TYPE_PTR: return ((hash << 5) - hash) ^ mono_metadata_type_hash (t1->data.type); case MONO_TYPE_ARRAY: @@ -5194,7 +5243,7 @@ mono_type_create_from_typespec (MonoImage *image, guint32 type_spec) ptr++; } - if (!do_mono_metadata_parse_type (type, image, NULL, ptr, &ptr)) { + if (!do_mono_metadata_parse_type (type, image, NULL, FALSE, ptr, &ptr)) { mono_loader_unlock (); return NULL; }