Author: raja
Date: 2005-11-28 07:14:07 -0500 (Mon, 28 Nov 2005)
New Revision: 53547

Modified:
   trunk/mono/mono/metadata/ChangeLog
   trunk/mono/mono/metadata/metadata.c
Log:
* metadata.c (mono_type_create_from_typespec_full): Ensure that
owner-less generic-parameters are never evicted from the typespec
cache.


Modified: trunk/mono/mono/metadata/ChangeLog
===================================================================
--- trunk/mono/mono/metadata/ChangeLog  2005-11-28 11:31:22 UTC (rev 53546)
+++ trunk/mono/mono/metadata/ChangeLog  2005-11-28 12:14:07 UTC (rev 53547)
@@ -1,5 +1,9 @@
 2005-11-28  Raja R Harinath  <[EMAIL PROTECTED]>
 
+       * metadata.c (mono_type_create_from_typespec_full): Ensure that
+       owner-less generic-parameters are never evicted from the typespec
+       cache.
+
        * loader.c (method_from_memberref): Don't use the current context
        when parsing signatures.
        (method_from_methodspec, mono_get_method_from_token): Update to changes.

Modified: trunk/mono/mono/metadata/metadata.c
===================================================================
--- trunk/mono/mono/metadata/metadata.c 2005-11-28 11:31:22 UTC (rev 53546)
+++ trunk/mono/mono/metadata/metadata.c 2005-11-28 12:14:07 UTC (rev 53547)
@@ -3704,6 +3704,7 @@
        const char *ptr;
        guint32 len;
        MonoType *type;
+       gboolean cache_type = TRUE;
 
        mono_loader_lock ();
 
@@ -3711,21 +3712,33 @@
 
        if (type && type->type == MONO_TYPE_GENERICINST && 
type->data.generic_class->inst->is_open &&
            !has_same_context (type->data.generic_class->inst, generic_context))
-               /* is_open AND does not have the same context as 
generic_context,
-                  so don't use cached MonoType */
+               /* is_open AND does not have the same context as 
generic_context, so don't use cached MonoType */
                type = NULL;
 
        if (type && (type->type == MONO_TYPE_VAR || type->type == 
MONO_TYPE_MVAR)) {
-               g_assert (generic_context);
-               if (((MonoGenericContext *) type->data.generic_param->owner) != 
generic_context) {
-                       /* cached MonoType's context differs from 
generic_context */
+               if (generic_context) {
                        MonoGenericContainer *gc = generic_context->container;
                        if (type->type == MONO_TYPE_VAR && gc->parent)
                                gc = gc->parent;
 
                        g_assert (type->type == MONO_TYPE_VAR || gc->is_method);
 
+                       /* Use the one already cached in the container, if it 
exists. Otherwise, ensure that it's created */
                        type = gc->types ? gc->types 
[type->data.generic_param->num] : NULL;
+
+                       /* Either way, some other variant of this 
generic-parameter is already in the typespec cache. */
+                       cache_type = FALSE;
+               } else if (type->data.generic_param->owner) {
+                       /*
+                        * We need a null-owner generic-parameter, but the one 
in the cache has an owner.
+                        * Ensure that the null-owner generic-parameter goes 
into the cache.
+                        *
+                        * Together with the 'cache_type = FALSE;' line in the 
other arm of this condition,
+                        * this ensures that a null-owner generic-parameter, 
once created, doesn't need to be re-created.
+                        * The generic-parameters with owners are cached in 
their respective owners, and thus don't
+                        * need to be re-created either.
+                        */
+                       type = NULL;
                }
        }
 
@@ -3742,7 +3755,8 @@
 
        type = g_new0 (MonoType, 1);
 
-       g_hash_table_insert (image->typespec_cache, GUINT_TO_POINTER 
(type_spec), type);
+       if (!cache_type)
+               g_hash_table_insert (image->typespec_cache, GUINT_TO_POINTER 
(type_spec), type);
 
        if (*ptr == MONO_TYPE_BYREF) {
                type->byref = 1; 
@@ -3760,7 +3774,6 @@
                container->types [type->data.generic_param->num] = type;
        }
 
-
        mono_loader_unlock ();
 
        return type;

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to