Merge pull request #4381 from BrzVlad/feature-generational-hash
[mono.git] / mono / metadata / metadata.c
index 973c4ca8bf3fd71660817db7391b2c5c30fa107f..545b917177bf45472e6df6c8d7eacc5d344cedd1 100644 (file)
@@ -109,7 +109,10 @@ enum {
        MONO_MT_HS_IDX,
 
        /* ResolutionScope coded index: Module, ModuleRef, AssemblytRef, TypeRef */
-       MONO_MT_RS_IDX
+       MONO_MT_RS_IDX,
+
+       /* CustomDebugInformation parent encoded index */
+       MONO_MT_HASCUSTDEBUG_IDX
 };
 
 const static unsigned char TableSchemas [] = {
@@ -397,7 +400,28 @@ const static unsigned char TableSchemas [] = {
        MONO_MT_STRING_IDX,  /* Name */
        MONO_MT_END,
 
-#define NULL_SCHEMA_OFFSET LOCALVARIABLE_SCHEMA_OFFSET + 4
+#define LOCALCONSTANT_SCHEMA_OFFSET LOCALVARIABLE_SCHEMA_OFFSET + 4
+       MONO_MT_STRING_IDX,  /* Name (String heap index) */
+       MONO_MT_BLOB_IDX,    /* Signature (Blob heap index, LocalConstantSig blob) */
+       MONO_MT_END,
+
+#define IMPORTSCOPE_SCHEMA_OFFSET LOCALCONSTANT_SCHEMA_OFFSET + 3
+       MONO_MT_TABLE_IDX, /* Parent (ImportScope row id or nil) */
+       MONO_MT_BLOB_IDX,  /* Imports (Blob index, encoding: Imports blob) */
+       MONO_MT_END,
+
+#define ASYNCMETHOD_SCHEMA_OFFSET IMPORTSCOPE_SCHEMA_OFFSET + 3
+       MONO_MT_TABLE_IDX, /* MoveNextMethod (MethodDef row id) */
+       MONO_MT_TABLE_IDX, /* KickoffMethod (MethodDef row id) */
+       MONO_MT_END,
+
+#define CUSTOMDEBUGINFORMATION_SCHEMA_OFFSET ASYNCMETHOD_SCHEMA_OFFSET + 3
+       MONO_MT_HASCUSTDEBUG_IDX, /* Parent (HasCustomDebugInformation coded index) */
+       MONO_MT_GUID_IDX,  /* Kind (Guid heap index) */
+       MONO_MT_BLOB_IDX,  /* Value (Blob heap index) */
+       MONO_MT_END,
+
+#define NULL_SCHEMA_OFFSET CUSTOMDEBUGINFORMATION_SCHEMA_OFFSET + 4
        MONO_MT_END
 };
 
@@ -455,7 +479,11 @@ table_description [] = {
        DOCUMENT_SCHEMA_OFFSET, /* 0x30 */
        METHODBODY_SCHEMA_OFFSET,
        LOCALSCOPE_SCHEMA_OFFSET,
-       LOCALVARIABLE_SCHEMA_OFFSET
+       LOCALVARIABLE_SCHEMA_OFFSET,
+       LOCALCONSTANT_SCHEMA_OFFSET,
+       IMPORTSCOPE_SCHEMA_OFFSET,
+       ASYNCMETHOD_SCHEMA_OFFSET,
+       CUSTOMDEBUGINFORMATION_SCHEMA_OFFSET
 };
 
 #ifdef HAVE_ARRAY_ELEM_INIT
@@ -523,7 +551,24 @@ inverse of this mapping.
 
  */
 #define rtsize(meta,s,b) (((s) < (1 << (b)) ? 2 : 4))
-#define idx_size(meta,tableidx) ((meta)->tables [(tableidx)].rows < 65536 ? 2 : 4)
+
+static inline int
+idx_size (MonoImage *meta, int tableidx)
+{
+       if (meta->referenced_tables && (meta->referenced_tables & ((guint64)1 << tableidx)))
+               return meta->referenced_table_rows [tableidx] < 65536 ? 2 : 4;
+       else
+               return meta->tables [tableidx].rows < 65536 ? 2 : 4;
+}
+
+static inline int
+get_nrows (MonoImage *meta, int tableidx)
+{
+       if (meta->referenced_tables && (meta->referenced_tables & ((guint64)1 << tableidx)))
+               return meta->referenced_table_rows [tableidx];
+       else
+               return meta->tables [tableidx].rows;
+}
 
 /* Reference: Partition II - 23.2.6 */
 /*
@@ -643,7 +688,7 @@ mono_metadata_compute_size (MonoImage *meta, int tableindex, guint32 *result_bit
                                break;
                        case MONO_TABLE_GENERICPARAM:
                                g_assert (i == 2);
-                               n = MAX (meta->tables [MONO_TABLE_METHOD].rows, meta->tables [MONO_TABLE_TYPEDEF].rows);
+                               n = MAX (get_nrows (meta, MONO_TABLE_METHOD), get_nrows (meta, MONO_TABLE_TYPEDEF));
                                /*This is a coded token for 2 tables, so takes 1 bit */
                                field_size = rtsize (meta, n, 16 - MONO_TYPEORMETHOD_BITS);
                                break;
@@ -673,8 +718,13 @@ mono_metadata_compute_size (MonoImage *meta, int tableindex, guint32 *result_bit
                                break;
                        case MONO_TABLE_METHODBODY:
                                g_assert (i == 0);
-                               field_size = idx_size (meta, MONO_TABLE_DOCUMENT);
-                               break;
+                               field_size = idx_size (meta, MONO_TABLE_DOCUMENT); break;
+                       case MONO_TABLE_IMPORTSCOPE:
+                               g_assert(i == 0);
+                               field_size = idx_size (meta, MONO_TABLE_IMPORTSCOPE); break;
+                       case MONO_TABLE_STATEMACHINEMETHOD:
+                               g_assert(i == 0 || i == 1);
+                               field_size = idx_size(meta, MONO_TABLE_METHOD); break;
                        default:
                                g_error ("Can't handle MONO_MT_TABLE_IDX for table %d element %d", tableindex, i);
                        }
@@ -684,9 +734,9 @@ mono_metadata_compute_size (MonoImage *meta, int tableindex, guint32 *result_bit
                         * HasConstant: ParamDef, FieldDef, Property
                         */
                case MONO_MT_CONST_IDX:
-                       n = MAX (meta->tables [MONO_TABLE_PARAM].rows,
-                                meta->tables [MONO_TABLE_FIELD].rows);
-                       n = MAX (n, meta->tables [MONO_TABLE_PROPERTY].rows);
+                       n = MAX (get_nrows (meta, MONO_TABLE_PARAM),
+                                get_nrows (meta, MONO_TABLE_FIELD));
+                       n = MAX (n, get_nrows (meta, MONO_TABLE_PROPERTY));
 
                        /* 2 bits to encode tag */
                        field_size = rtsize (meta, n, 16-2);
@@ -708,30 +758,71 @@ mono_metadata_compute_size (MonoImage *meta, int tableindex, guint32 *result_bit
                                break;
                        }*/
                        
-                       n = MAX (meta->tables [MONO_TABLE_METHOD].rows,
-                                meta->tables [MONO_TABLE_FIELD].rows);
-                       n = MAX (n, meta->tables [MONO_TABLE_TYPEREF].rows);
-                       n = MAX (n, meta->tables [MONO_TABLE_TYPEDEF].rows);
-                       n = MAX (n, meta->tables [MONO_TABLE_PARAM].rows);
-                       n = MAX (n, meta->tables [MONO_TABLE_INTERFACEIMPL].rows);
-                       n = MAX (n, meta->tables [MONO_TABLE_MEMBERREF].rows);
-                       n = MAX (n, meta->tables [MONO_TABLE_MODULE].rows);
-                       n = MAX (n, meta->tables [MONO_TABLE_DECLSECURITY].rows);
-                       n = MAX (n, meta->tables [MONO_TABLE_PROPERTY].rows);
-                       n = MAX (n, meta->tables [MONO_TABLE_EVENT].rows);
-                       n = MAX (n, meta->tables [MONO_TABLE_STANDALONESIG].rows);
-                       n = MAX (n, meta->tables [MONO_TABLE_MODULEREF].rows);
-                       n = MAX (n, meta->tables [MONO_TABLE_TYPESPEC].rows);
-                       n = MAX (n, meta->tables [MONO_TABLE_ASSEMBLY].rows);
-                       n = MAX (n, meta->tables [MONO_TABLE_ASSEMBLYREF].rows);
-                       n = MAX (n, meta->tables [MONO_TABLE_FILE].rows);
-                       n = MAX (n, meta->tables [MONO_TABLE_EXPORTEDTYPE].rows);
-                       n = MAX (n, meta->tables [MONO_TABLE_MANIFESTRESOURCE].rows);
+                       n = MAX (get_nrows (meta, MONO_TABLE_METHOD),
+                                get_nrows (meta, MONO_TABLE_FIELD));
+                       n = MAX (n, get_nrows (meta, MONO_TABLE_TYPEREF));
+                       n = MAX (n, get_nrows (meta, MONO_TABLE_TYPEDEF));
+                       n = MAX (n, get_nrows (meta, MONO_TABLE_PARAM));
+                       n = MAX (n, get_nrows (meta, MONO_TABLE_INTERFACEIMPL));
+                       n = MAX (n, get_nrows (meta, MONO_TABLE_MEMBERREF));
+                       n = MAX (n, get_nrows (meta, MONO_TABLE_MODULE));
+                       n = MAX (n, get_nrows (meta, MONO_TABLE_DECLSECURITY));
+                       n = MAX (n, get_nrows (meta, MONO_TABLE_PROPERTY));
+                       n = MAX (n, get_nrows (meta, MONO_TABLE_EVENT));
+                       n = MAX (n, get_nrows (meta, MONO_TABLE_STANDALONESIG));
+                       n = MAX (n, get_nrows (meta, MONO_TABLE_MODULEREF));
+                       n = MAX (n, get_nrows (meta, MONO_TABLE_TYPESPEC));
+                       n = MAX (n, get_nrows (meta, MONO_TABLE_ASSEMBLY));
+                       n = MAX (n, get_nrows (meta, MONO_TABLE_ASSEMBLYREF));
+                       n = MAX (n, get_nrows (meta, MONO_TABLE_FILE));
+                       n = MAX (n, get_nrows (meta, MONO_TABLE_EXPORTEDTYPE));
+                       n = MAX (n, get_nrows (meta, MONO_TABLE_MANIFESTRESOURCE));
+                       n = MAX (n, get_nrows (meta, MONO_TABLE_GENERICPARAM));
+                       n = MAX (n, get_nrows (meta, MONO_TABLE_GENERICPARAMCONSTRAINT));
+                       n = MAX (n, get_nrows (meta, MONO_TABLE_METHODSPEC));
 
                        /* 5 bits to encode */
                        field_size = rtsize (meta, n, 16-5);
                        break;
 
+                       /*
+                       * HasCustomAttribute: points to any table but
+                       * itself.
+                       */
+
+               case MONO_MT_HASCUSTDEBUG_IDX:
+                       n = MAX(get_nrows (meta, MONO_TABLE_METHOD),
+                                       get_nrows (meta, MONO_TABLE_FIELD));
+                       n = MAX(n, get_nrows (meta, MONO_TABLE_TYPEREF));
+                       n = MAX(n, get_nrows (meta, MONO_TABLE_TYPEDEF));
+                       n = MAX(n, get_nrows (meta, MONO_TABLE_PARAM));
+                       n = MAX(n, get_nrows (meta, MONO_TABLE_INTERFACEIMPL));
+                       n = MAX(n, get_nrows (meta, MONO_TABLE_MEMBERREF));
+                       n = MAX(n, get_nrows (meta, MONO_TABLE_MODULE));
+                       n = MAX(n, get_nrows (meta, MONO_TABLE_DECLSECURITY));
+                       n = MAX(n, get_nrows (meta, MONO_TABLE_PROPERTY));
+                       n = MAX(n, get_nrows (meta, MONO_TABLE_EVENT));
+                       n = MAX(n, get_nrows (meta, MONO_TABLE_STANDALONESIG));
+                       n = MAX(n, get_nrows (meta, MONO_TABLE_MODULEREF));
+                       n = MAX(n, get_nrows (meta, MONO_TABLE_TYPESPEC));
+                       n = MAX(n, get_nrows (meta, MONO_TABLE_ASSEMBLY));
+                       n = MAX(n, get_nrows (meta, MONO_TABLE_ASSEMBLYREF));
+                       n = MAX(n, get_nrows (meta, MONO_TABLE_FILE));
+                       n = MAX(n, get_nrows (meta, MONO_TABLE_EXPORTEDTYPE));
+                       n = MAX(n, get_nrows (meta, MONO_TABLE_MANIFESTRESOURCE));
+                       n = MAX(n, get_nrows (meta, MONO_TABLE_GENERICPARAM));
+                       n = MAX(n, get_nrows (meta, MONO_TABLE_GENERICPARAMCONSTRAINT));
+                       n = MAX(n, get_nrows (meta, MONO_TABLE_METHODSPEC));
+                       n = MAX(n, get_nrows (meta, MONO_TABLE_DOCUMENT));
+                       n = MAX(n, get_nrows (meta, MONO_TABLE_LOCALSCOPE));
+                       n = MAX(n, get_nrows (meta, MONO_TABLE_LOCALVARIABLE));
+                       n = MAX(n, get_nrows (meta, MONO_TABLE_LOCALCONSTANT));
+                       n = MAX(n, get_nrows (meta, MONO_TABLE_IMPORTSCOPE));
+
+                       /* 5 bits to encode */
+                       field_size = rtsize(meta, n, 16 - 5);
+                       break;
+
                        /*
                         * CustomAttributeType: TypeDef, TypeRef, MethodDef, 
                         * MemberRef and String.  
@@ -744,10 +835,10 @@ mono_metadata_compute_size (MonoImage *meta, int tableindex, guint32 *result_bit
                                break;
                        }*/
                        
-                       n = MAX (meta->tables [MONO_TABLE_TYPEREF].rows,
-                                meta->tables [MONO_TABLE_TYPEDEF].rows);
-                       n = MAX (n, meta->tables [MONO_TABLE_METHOD].rows);
-                       n = MAX (n, meta->tables [MONO_TABLE_MEMBERREF].rows);
+                       n = MAX (get_nrows (meta, MONO_TABLE_TYPEREF),
+                                get_nrows (meta, MONO_TABLE_TYPEDEF));
+                       n = MAX (n, get_nrows (meta, MONO_TABLE_METHOD));
+                       n = MAX (n, get_nrows (meta, MONO_TABLE_MEMBERREF));
 
                        /* 3 bits to encode */
                        field_size = rtsize (meta, n, 16-3);
@@ -757,9 +848,9 @@ mono_metadata_compute_size (MonoImage *meta, int tableindex, guint32 *result_bit
                         * HasDeclSecurity: Typedef, MethodDef, Assembly
                         */
                case MONO_MT_HASDEC_IDX:
-                       n = MAX (meta->tables [MONO_TABLE_TYPEDEF].rows,
-                                meta->tables [MONO_TABLE_METHOD].rows);
-                       n = MAX (n, meta->tables [MONO_TABLE_ASSEMBLY].rows);
+                       n = MAX (get_nrows (meta, MONO_TABLE_TYPEDEF),
+                                get_nrows (meta, MONO_TABLE_METHOD));
+                       n = MAX (n, get_nrows (meta, MONO_TABLE_ASSEMBLY));
 
                        /* 2 bits to encode */
                        field_size = rtsize (meta, n, 16-2);
@@ -769,9 +860,9 @@ mono_metadata_compute_size (MonoImage *meta, int tableindex, guint32 *result_bit
                         * Implementation: File, AssemblyRef, ExportedType
                         */
                case MONO_MT_IMPL_IDX:
-                       n = MAX (meta->tables [MONO_TABLE_FILE].rows,
-                                meta->tables [MONO_TABLE_ASSEMBLYREF].rows);
-                       n = MAX (n, meta->tables [MONO_TABLE_EXPORTEDTYPE].rows);
+                       n = MAX (get_nrows (meta, MONO_TABLE_FILE),
+                                get_nrows (meta, MONO_TABLE_ASSEMBLYREF));
+                       n = MAX (n, get_nrows (meta, MONO_TABLE_EXPORTEDTYPE));
 
                        /* 2 bits to encode tag */
                        field_size = rtsize (meta, n, 16-2);
@@ -781,8 +872,8 @@ mono_metadata_compute_size (MonoImage *meta, int tableindex, guint32 *result_bit
                         * HasFieldMarshall: FieldDef, ParamDef
                         */
                case MONO_MT_HFM_IDX:
-                       n = MAX (meta->tables [MONO_TABLE_FIELD].rows,
-                                meta->tables [MONO_TABLE_PARAM].rows);
+                       n = MAX (get_nrows (meta, MONO_TABLE_FIELD),
+                                get_nrows (meta, MONO_TABLE_PARAM));
 
                        /* 1 bit used to encode tag */
                        field_size = rtsize (meta, n, 16-1);
@@ -792,8 +883,8 @@ mono_metadata_compute_size (MonoImage *meta, int tableindex, guint32 *result_bit
                         * MemberForwarded: FieldDef, MethodDef
                         */
                case MONO_MT_MF_IDX:
-                       n = MAX (meta->tables [MONO_TABLE_FIELD].rows,
-                                meta->tables [MONO_TABLE_METHOD].rows);
+                       n = MAX (get_nrows (meta, MONO_TABLE_FIELD),
+                                get_nrows (meta, MONO_TABLE_METHOD));
 
                        /* 1 bit used to encode tag */
                        field_size = rtsize (meta, n, 16-1);
@@ -805,9 +896,9 @@ mono_metadata_compute_size (MonoImage *meta, int tableindex, guint32 *result_bit
                         * It is TypeDef, _TypeRef_, TypeSpec, instead.
                         */
                case MONO_MT_TDOR_IDX:
-                       n = MAX (meta->tables [MONO_TABLE_TYPEDEF].rows,
-                                meta->tables [MONO_TABLE_TYPEREF].rows);
-                       n = MAX (n, meta->tables [MONO_TABLE_TYPESPEC].rows);
+                       n = MAX (get_nrows (meta, MONO_TABLE_TYPEDEF),
+                                get_nrows (meta, MONO_TABLE_TYPEREF));
+                       n = MAX (n, get_nrows (meta, MONO_TABLE_TYPESPEC));
 
                        /* 2 bits to encode */
                        field_size = rtsize (meta, n, 16-2);
@@ -817,11 +908,11 @@ mono_metadata_compute_size (MonoImage *meta, int tableindex, guint32 *result_bit
                         * MemberRefParent: TypeDef, TypeRef, MethodDef, ModuleRef, TypeSpec, MemberRef
                         */
                case MONO_MT_MRP_IDX:
-                       n = MAX (meta->tables [MONO_TABLE_TYPEDEF].rows,
-                                meta->tables [MONO_TABLE_TYPEREF].rows);
-                       n = MAX (n, meta->tables [MONO_TABLE_METHOD].rows);
-                       n = MAX (n, meta->tables [MONO_TABLE_MODULEREF].rows);
-                       n = MAX (n, meta->tables [MONO_TABLE_TYPESPEC].rows);
+                       n = MAX (get_nrows (meta, MONO_TABLE_TYPEDEF),
+                                get_nrows (meta, MONO_TABLE_TYPEREF));
+                       n = MAX (n, get_nrows (meta, MONO_TABLE_METHOD));
+                       n = MAX (n, get_nrows (meta, MONO_TABLE_MODULEREF));
+                       n = MAX (n, get_nrows (meta, MONO_TABLE_TYPESPEC));
 
                        /* 3 bits to encode */
                        field_size = rtsize (meta, n, 16 - 3);
@@ -831,8 +922,8 @@ mono_metadata_compute_size (MonoImage *meta, int tableindex, guint32 *result_bit
                         * MethodDefOrRef: MethodDef, MemberRef
                         */
                case MONO_MT_MDOR_IDX:
-                       n = MAX (meta->tables [MONO_TABLE_METHOD].rows,
-                                meta->tables [MONO_TABLE_MEMBERREF].rows);
+                       n = MAX (get_nrows (meta, MONO_TABLE_METHOD),
+                                get_nrows (meta, MONO_TABLE_MEMBERREF));
 
                        /* 1 bit used to encode tag */
                        field_size = rtsize (meta, n, 16-1);
@@ -842,8 +933,8 @@ mono_metadata_compute_size (MonoImage *meta, int tableindex, guint32 *result_bit
                         * HasSemantics: Property, Event
                         */
                case MONO_MT_HS_IDX:
-                       n = MAX (meta->tables [MONO_TABLE_PROPERTY].rows,
-                                meta->tables [MONO_TABLE_EVENT].rows);
+                       n = MAX (get_nrows (meta, MONO_TABLE_PROPERTY),
+                                get_nrows (meta, MONO_TABLE_EVENT));
 
                        /* 1 bit used to encode tag */
                        field_size = rtsize (meta, n, 16-1);
@@ -853,10 +944,10 @@ mono_metadata_compute_size (MonoImage *meta, int tableindex, guint32 *result_bit
                         * ResolutionScope: Module, ModuleRef, AssemblyRef, TypeRef
                         */
                case MONO_MT_RS_IDX:
-                       n = MAX (meta->tables [MONO_TABLE_MODULE].rows,
-                                meta->tables [MONO_TABLE_MODULEREF].rows);
-                       n = MAX (n, meta->tables [MONO_TABLE_ASSEMBLYREF].rows);
-                       n = MAX (n, meta->tables [MONO_TABLE_TYPEREF].rows);
+                       n = MAX (get_nrows (meta, MONO_TABLE_MODULE),
+                                get_nrows (meta, MONO_TABLE_MODULEREF));
+                       n = MAX (n, get_nrows (meta, MONO_TABLE_ASSEMBLYREF));
+                       n = MAX (n, get_nrows (meta, MONO_TABLE_TYPEREF));
 
                        /* 2 bits used to encode tag (ECMA spec claims 3) */
                        field_size = rtsize (meta, n, 16 - 2);
@@ -1125,7 +1216,7 @@ mono_metadata_decode_blob_size (const char *xptr, const char **rptr)
  * @rptr: the new position of the pointer
  *
  * This routine decompresses 32-bit values as specified in the "Blob and
- * Signature" section (22.2)
+ * Signature" section (23.2)
  *
  * Returns: the decoded value
  */
@@ -1610,7 +1701,7 @@ mono_metadata_parse_type_internal (MonoImage *m, MonoGenericContainer *container
        int count = 0; // Number of mod arguments
        gboolean found;
 
-       mono_error_init (error);
+       error_init (error);
 
        /*
         * According to the spec, custom modifiers should come before the byref
@@ -1853,7 +1944,7 @@ MonoMethodSignature*
 mono_metadata_parse_signature_checked (MonoImage *image, guint32 token, MonoError *error)
 {
 
-       mono_error_init (error);
+       error_init (error);
        MonoTableInfo *tables = image->tables;
        guint32 idx = mono_metadata_token_index (token);
        guint32 sig;
@@ -2030,7 +2121,7 @@ mono_metadata_parse_method_signature_full (MonoImage *m, MonoGenericContainer *c
        guint32 gen_param_count = 0;
        gboolean is_open = FALSE;
 
-       mono_error_init (error);
+       error_init (error);
 
        if (*ptr & 0x10)
                gen_param_count = 1;
@@ -2891,8 +2982,6 @@ mono_metadata_get_generic_inst (int type_argc, MonoType **type_argv)
        gboolean is_open;
        int i;
        int size = MONO_SIZEOF_GENERIC_INST + type_argc * sizeof (MonoType *);
-       CollectData data;
-       MonoImageSet *set;
 
        for (i = 0; i < type_argc; ++i)
                if (mono_class_is_open_constructed_type (type_argv [i]))
@@ -2905,9 +2994,34 @@ mono_metadata_get_generic_inst (int type_argc, MonoType **type_argv)
        ginst->type_argc = type_argc;
        memcpy (ginst->type_argv, type_argv, type_argc * sizeof (MonoType *));
 
+       return mono_metadata_get_canonical_generic_inst (ginst);
+}
+
+
+/**
+ * mono_metadata_get_canonical_generic_inst:
+ * @candidate: an arbitrary generic instantiation
+ *
+ * Returns the canonical generic instantiation that represents the given
+ * candidate by identifying the image set for the candidate instantiation and
+ * finding the instance in the image set or adding a copy of the given instance
+ * to the image set.
+ *
+ * The returned MonoGenericInst has its own copy of the list of types.  The list
+ * passed in the argument can be freed, modified or disposed of.
+ *
+ */
+MonoGenericInst *
+mono_metadata_get_canonical_generic_inst (MonoGenericInst *candidate)
+{
+       CollectData data;
+       int type_argc = candidate->type_argc;
+       gboolean is_open = candidate->is_open;
+       MonoImageSet *set;
+
        collect_data_init (&data);
 
-       collect_ginst_images (ginst, &data);
+       collect_ginst_images (candidate, &data);
 
        set = get_image_set (data.images, data.nimages);
 
@@ -2915,8 +3029,9 @@ mono_metadata_get_generic_inst (int type_argc, MonoType **type_argv)
 
        mono_image_set_lock (set);
 
-       ginst = (MonoGenericInst *)g_hash_table_lookup (set->ginst_cache, ginst);
+       MonoGenericInst *ginst = (MonoGenericInst *)g_hash_table_lookup (set->ginst_cache, candidate);
        if (!ginst) {
+               int size = MONO_SIZEOF_GENERIC_INST + type_argc * sizeof (MonoType *);
                ginst = (MonoGenericInst *)mono_image_set_alloc0 (set, size);
 #ifndef MONO_SMALL_CONFIG
                ginst->id = ++next_generic_inst_id;
@@ -2924,8 +3039,8 @@ mono_metadata_get_generic_inst (int type_argc, MonoType **type_argv)
                ginst->is_open = is_open;
                ginst->type_argc = type_argc;
 
-               for (i = 0; i < type_argc; ++i)
-                       ginst->type_argv [i] = mono_metadata_type_dup (NULL, type_argv [i]);
+               for (int i = 0; i < type_argc; ++i)
+                       ginst->type_argv [i] = mono_metadata_type_dup (NULL, candidate->type_argv [i]);
 
                g_hash_table_insert (set->ginst_cache, ginst, ginst);
        }
@@ -3020,7 +3135,7 @@ mono_metadata_inflate_generic_inst (MonoGenericInst *ginst, MonoGenericContext *
        MonoGenericInst *nginst = NULL;
        int i, count = 0;
 
-       mono_error_init (error);
+       error_init (error);
 
        if (!ginst->is_open)
                return ginst;
@@ -3052,7 +3167,7 @@ mono_metadata_parse_generic_inst (MonoImage *m, MonoGenericContainer *container,
        MonoGenericInst *ginst;
        int i;
 
-       mono_error_init (error);
+       error_init (error);
        type_argv = g_new0 (MonoType*, count);
 
        for (i = 0; i < count; i++) {
@@ -3083,7 +3198,7 @@ do_mono_metadata_parse_generic_class (MonoType *type, MonoImage *m, MonoGenericC
        MonoType *gtype;
        int count;
 
-       mono_error_init (error);
+       error_init (error);
 
        // XXX how about transient?
        gtype = mono_metadata_parse_type_checked (m, NULL, 0, FALSE, ptr, &ptr, error);
@@ -3179,7 +3294,7 @@ mono_metadata_parse_generic_param (MonoImage *m, MonoGenericContainer *generic_c
        if (rptr)
                *rptr = ptr;
 
-       mono_error_init (error);
+       error_init (error);
 
        generic_container = select_container (generic_container, type);
        if (!generic_container) {
@@ -3253,7 +3368,7 @@ mono_metadata_get_shared_type (MonoType *type)
 static gboolean
 compare_type_literals (MonoImage *image, int class_type, int type_type, MonoError *error)
 {
-       mono_error_init (error);
+       error_init (error);
 
        /* byval_arg.type can be zero if we're decoding a type that references a class been loading.
         * See mcs/test/gtest-440. and #650936.
@@ -3303,7 +3418,7 @@ compare_type_literals (MonoImage *image, int class_type, int type_type, MonoErro
 static gboolean
 verify_var_type_and_container (MonoImage *image, int var_type, MonoGenericContainer *container, MonoError *error)
 {
-       mono_error_init (error);
+       error_init (error);
        if (var_type == MONO_TYPE_MVAR) {
                if (!container->is_method) { //MVAR and a method container
                        mono_error_set_bad_image (error, image, "MVAR parsed in a context without a method container");
@@ -3344,7 +3459,7 @@ static gboolean
 do_mono_metadata_parse_type (MonoType *type, MonoImage *m, MonoGenericContainer *container,
                                                         gboolean transient, const char *ptr, const char **rptr, MonoError *error)
 {
-       mono_error_init (error);
+       error_init (error);
 
        type->type = (MonoTypeEnum)mono_metadata_decode_value (ptr, &ptr);
        
@@ -3513,7 +3628,7 @@ parse_section_data (MonoImage *m, int *num_clauses, const unsigned char *ptr, Mo
        guint32 sect_data_len;
        MonoExceptionClause* clauses = NULL;
 
-       mono_error_init (error);
+       error_init (error);
        
        while (1) {
                /* align on 32-bit boundary */
@@ -3681,7 +3796,7 @@ mono_metadata_parse_mh_full (MonoImage *m, MonoGenericContainer *container, cons
        MonoTableInfo *t = &m->tables [MONO_TABLE_STANDALONESIG];
        guint32 cols [MONO_STAND_ALONE_SIGNATURE_SIZE];
 
-       mono_error_init (error);
+       error_init (error);
 
        if (!ptr) {
                mono_error_set_bad_image (error, m, "Method header with null pointer");
@@ -4219,7 +4334,7 @@ mono_metadata_interfaces_from_typedef_full (MonoImage *meta, guint32 index, Mono
        *interfaces = NULL;
        *count = 0;
 
-       mono_error_init (error);
+       error_init (error);
 
        if (!tdef->base)
                return TRUE;
@@ -5575,7 +5690,7 @@ mono_type_create_from_typespec_checked (MonoImage *image, guint32 type_spec, Mon
        const char *ptr;
        MonoType *type, *type2;
 
-       mono_error_init (error);
+       error_init (error);
 
        mono_image_lock (image);
        type = (MonoType *)g_hash_table_lookup (image->typespec_cache, GUINT_TO_POINTER (type_spec));
@@ -5953,7 +6068,7 @@ method_from_method_def_or_ref (MonoImage *m, guint32 tok, MonoGenericContext *co
        MonoMethod *result = NULL;
        guint32 idx = tok >> MONO_METHODDEFORREF_BITS;
 
-       mono_error_init (error);
+       error_init (error);
 
        switch (tok & MONO_METHODDEFORREF_MASK) {
        case MONO_METHODDEFORREF_METHODDEF:
@@ -6096,7 +6211,7 @@ get_constraints (MonoImage *image, int owner, MonoClass ***constraints, MonoGene
        GSList *cons = NULL, *tmp;
        MonoGenericContext *context = &container->context;
 
-       mono_error_init (error);
+       error_init (error);
 
        *constraints = NULL;
        found = 0;
@@ -6188,7 +6303,7 @@ mono_metadata_load_generic_param_constraints_checked (MonoImage *image, guint32
 {
 
        guint32 start_row, i, owner;
-       mono_error_init (error);
+       error_init (error);
 
        if (! (start_row = mono_metadata_get_generic_param_row (image, token, &owner)))
                return TRUE;
@@ -6599,7 +6714,8 @@ mono_signature_explicit_this (MonoMethodSignature *sig)
 guint
 mono_aligned_addr_hash (gconstpointer ptr)
 {
-       return GPOINTER_TO_UINT (ptr) >> 3;
+       /* Same hashing we use for objects */
+       return (GPOINTER_TO_UINT (ptr) >> 3) * 2654435761u;
 }
 
 /*
@@ -6634,8 +6750,8 @@ mono_metadata_get_corresponding_event_from_generic_type_definition (MonoEvent *e
                return event;
 
        gtd = mono_class_get_generic_class (event->parent)->container_class;
-       offset = event - mono_class_get_ext (event->parent)->events;
-       return mono_class_get_ext (gtd)->events + offset;
+       offset = event - mono_class_get_event_info (event->parent)->events;
+       return mono_class_get_event_info (gtd)->events + offset;
 }
 
 /*
@@ -6645,15 +6761,17 @@ mono_metadata_get_corresponding_event_from_generic_type_definition (MonoEvent *e
 MonoProperty*
 mono_metadata_get_corresponding_property_from_generic_type_definition (MonoProperty *property)
 {
+       MonoClassPropertyInfo *info;
        MonoClass *gtd;
        int offset;
 
        if (!mono_class_is_ginst (property->parent))
                return property;
 
+       info = mono_class_get_property_info (property->parent);
        gtd = mono_class_get_generic_class (property->parent)->container_class;
-       offset = property - mono_class_get_ext (property->parent)->properties;
-       return mono_class_get_ext (gtd)->properties + offset;
+       offset = property - info->properties;
+       return mono_class_get_property_info (gtd)->properties + offset;
 }
 
 MonoWrapperCaches*