2006-05-30 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mono / metadata / reflection.c
index fae69be56cbef47d6076ed65b98d246d9b03fddb..656de69934c2e391307e210448b235e74bf6995b 100644 (file)
@@ -13,6 +13,7 @@
 #include "mono/metadata/tabledefs.h"
 #include "mono/metadata/metadata-internals.h"
 #include "mono/metadata/class-internals.h"
+#include "mono/metadata/gc-internal.h"
 #include "mono/metadata/tokentype.h"
 #include "mono/metadata/domain-internals.h"
 #include "mono/metadata/opcodes.h"
@@ -142,6 +143,42 @@ static void get_default_param_value_blobs (MonoMethod *method, char **blobs, gui
 static MonoObject *mono_get_object_from_blob (MonoDomain *domain, MonoType *type, const char *blob);
 static inline MonoType *dup_type (const MonoType *original);
 
+/**
+ * mp_g_alloc:
+ *
+ * Allocate memory from the mempool MP if it is non-NULL. Otherwise, allocate memory
+ * from the C heap.
+ */
+static gpointer
+mp_g_malloc (MonoMemPool *mp, guint size)
+{
+       if (mp)
+               return mono_mempool_alloc (mp, size);
+       else
+               return g_malloc (size);
+}
+
+/**
+ * mp_g_alloc0:
+ *
+ * Allocate memory from the mempool MP if it is non-NULL. Otherwise, allocate memory
+ * from the C heap.
+ */
+static gpointer
+mp_g_malloc0 (MonoMemPool *mp, guint size)
+{
+       if (mp)
+               return mono_mempool_alloc0 (mp, size);
+       else
+               return g_malloc0 (size);
+}
+
+#define mp_g_new(mp,struct_type, n_structs)            \
+    ((struct_type *) mp_g_malloc (mp, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
+
+#define mp_g_new0(mp,struct_type, n_structs)           \
+    ((struct_type *) mp_g_malloc0 (mp, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
+
 static void
 alloc_table (MonoDynamicTable *table, guint nrows)
 {
@@ -285,7 +322,7 @@ add_to_blob_cached (MonoDynamicImage *assembly, char *b1, int s1, char *b2, int
        guint32 idx;
        char *copy;
        gpointer oldkey, oldval;
-       
+
        copy = g_malloc (s1+s2);
        memcpy (copy, b1, s1);
        memcpy (copy + s1, b2, s2);
@@ -2028,7 +2065,7 @@ mono_image_get_generic_param_info (MonoReflectionGenericParam *gparam, guint32 o
 
        entry = g_new0 (GenericParamTableEntry, 1);
        entry->owner = owner;
-       entry->gparam = gparam;
+       entry->gparam = gparam; /* FIXME: GC object stored in unmanaged mem */
 
        g_ptr_array_add (assembly->gen_params, entry);
 }
@@ -2908,7 +2945,7 @@ collect_types (GPtrArray *types, MonoReflectionTypeBuilder *type)
 {
        int i;
 
-       g_ptr_array_add (types, type);
+       g_ptr_array_add (types, type); /* FIXME: GC object added to unmanaged memory */
 
        if (!type->subtypes)
                return;
@@ -3161,6 +3198,44 @@ mono_image_fill_export_table_from_module (MonoDomain *domain, MonoReflectionModu
        }
 }
 
+static void
+mono_image_fill_export_table_from_type_forwarders (MonoReflectionAssemblyBuilder *assemblyb, MonoDynamicImage *assembly)
+{
+       MonoDynamicTable *table;
+       MonoClass *klass;
+       guint32 *values;
+       guint32 scope, idx;
+       int i;
+
+       table = &assembly->tables [MONO_TABLE_EXPORTEDTYPE];
+
+       if (assemblyb->type_forwarders) {
+               for (i = 0; i < mono_array_length (assemblyb->type_forwarders); ++i) {
+                       MonoReflectionType *t = mono_array_get (assemblyb->type_forwarders, MonoReflectionType*, i);
+                       if (!t)
+                               continue;
+
+                       g_assert (t->type);
+
+                       klass = mono_class_from_mono_type (t->type);
+
+                       scope = resolution_scope_from_image (assembly, klass->image);
+                       g_assert ((scope & MONO_RESOLTION_SCOPE_MASK) == MONO_RESOLTION_SCOPE_ASSEMBLYREF);
+                       idx = scope >> MONO_RESOLTION_SCOPE_BITS;
+
+                       table->rows++;
+                       alloc_table (table, table->rows);
+                       values = table->values + table->next_idx * MONO_EXP_TYPE_SIZE;
+
+                       values [MONO_EXP_TYPE_FLAGS] = TYPE_ATTRIBUTE_FORWARDER;
+                       values [MONO_EXP_TYPE_TYPEDEF] = 0;
+                       values [MONO_EXP_TYPE_IMPLEMENTATION] = (idx << MONO_IMPLEMENTATION_BITS) + MONO_IMPLEMENTATION_ASSEMBLYREF;
+                       values [MONO_EXP_TYPE_NAME] = string_heap_insert (&assembly->sheap, klass->name);
+                       values [MONO_EXP_TYPE_NAMESPACE] = string_heap_insert (&assembly->sheap, klass->name_space);
+               }
+       }
+}
+
 #define align_pointer(base,p)\
        do {\
                guint32 __diff = (unsigned char*)(p)-(unsigned char*)(base);\
@@ -3847,6 +3922,8 @@ mono_image_emit_manifest (MonoReflectionModuleBuilder *moduleb)
                        mono_image_fill_export_table_from_module (domain, file_module, module_index, assembly);
                }
        }
+       if (assemblyb->type_forwarders)
+               mono_image_fill_export_table_from_type_forwarders (assemblyb, assembly);
 
        /* Emit MANIFESTRESOURCE table */
        module_index = 0;
@@ -4270,23 +4347,22 @@ create_dynamic_mono_image (MonoDynamicAssembly *assembly, char *assembly_name, c
        image->image.name = assembly_name;
        image->image.assembly_name = image->image.name; /* they may be different */
        image->image.module_name = module_name;
-       image->image.version = version;
+       image->image.version = g_strdup (version);
        image->image.md_version_major = 1;
        image->image.md_version_minor = 1;
        image->image.dynamic = TRUE;
-       image->image.ref_count = 1;
 
        image->image.references = g_new0 (MonoAssembly*, 1);
        image->image.references [0] = NULL;
 
        mono_image_init (&image->image);
 
-       image->token_fixups = mono_g_hash_table_new (NULL, NULL);
+       image->token_fixups = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_KEY_GC);
        image->method_to_table_idx = g_hash_table_new (NULL, NULL);
        image->field_to_table_idx = g_hash_table_new (NULL, NULL);
        image->method_aux_hash = g_hash_table_new (NULL, NULL);
        image->handleref = g_hash_table_new (NULL, NULL);
-       image->tokens = mono_g_hash_table_new (NULL, NULL);
+       image->tokens = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC);
        image->typespec = g_hash_table_new ((GHashFunc)mono_metadata_type_hash, (GCompareFunc)mono_metadata_type_equal);
        image->typeref = g_hash_table_new ((GHashFunc)mono_metadata_type_hash, (GCompareFunc)mono_metadata_type_equal);
        image->blob_cache = g_hash_table_new ((GHashFunc)mono_blob_entry_hash, (GCompareFunc)mono_blob_entry_equal);
@@ -4358,19 +4434,21 @@ mono_image_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
                assembly->assembly.aname.culture = g_strdup ("");
 
         if (assemblyb->version) {
-                char **version = g_strsplit (mono_string_to_utf8 (assemblyb->version), ".", 4);
-                char **parts = version;
-                assembly->assembly.aname.major = atoi (*parts++);
-                assembly->assembly.aname.minor = atoi (*parts++);
-                assembly->assembly.aname.build = *parts != NULL ? atoi (*parts++) : 0;
-                assembly->assembly.aname.revision = *parts != NULL ? atoi (*parts) : 0;
-
-                g_strfreev (version);
+                       char *vstr = mono_string_to_utf8 (assemblyb->version);
+                       char **version = g_strsplit (vstr, ".", 4);
+                       char **parts = version;
+                       assembly->assembly.aname.major = atoi (*parts++);
+                       assembly->assembly.aname.minor = atoi (*parts++);
+                       assembly->assembly.aname.build = *parts != NULL ? atoi (*parts++) : 0;
+                       assembly->assembly.aname.revision = *parts != NULL ? atoi (*parts) : 0;
+
+                       g_strfreev (version);
+                       g_free (vstr);
         } else {
-                assembly->assembly.aname.major = 0;
-                assembly->assembly.aname.minor = 0;
-                assembly->assembly.aname.build = 0;
-                assembly->assembly.aname.revision = 0;
+                       assembly->assembly.aname.major = 0;
+                       assembly->assembly.aname.minor = 0;
+                       assembly->assembly.aname.build = 0;
+                       assembly->assembly.aname.revision = 0;
         }
 
        assembly->run = assemblyb->access != 2;
@@ -4457,6 +4535,7 @@ resource_tree_create (MonoArray *win32_resources)
 
                /* Create node */
 
+               /* FIXME: BUG: this stores managed references in unmanaged memory */
                lang_node = g_new0 (ResTreeNode, 1);
                lang_node->id = win32_res->lang_id;
                lang_node->win32_res = win32_res;
@@ -5040,6 +5119,7 @@ mono_image_load_module (MonoReflectionAssemblyBuilder *ab, MonoString *fileName)
        if (image->assembly->image->modules)
                memcpy (new_modules, image->assembly->image->modules, module_count * sizeof (MonoImage *));
        new_modules [module_count] = image;
+       mono_image_addref (image);
 
        g_free (image->assembly->image->modules);
        image->assembly->image->modules = new_modules;
@@ -5076,7 +5156,7 @@ reflected_equal (gconstpointer a, gconstpointer b) {
 static guint
 reflected_hash (gconstpointer a) {
        const ReflectedEntry *ea = a;
-       return GPOINTER_TO_UINT (ea->item);
+       return mono_aligned_addr_hash (ea->item);
 }
 
 #define CHECK_OBJECT(t,p,k)    \
@@ -5087,7 +5167,7 @@ reflected_hash (gconstpointer a) {
                e.refclass = (k);       \
                mono_domain_lock (domain);      \
                if (!domain->refobject_hash)    \
-                       domain->refobject_hash = mono_g_hash_table_new (reflected_hash, reflected_equal);       \
+                       domain->refobject_hash = mono_g_hash_table_new_type (reflected_hash, reflected_equal, MONO_HASH_VALUE_GC);      \
                if ((_obj = mono_g_hash_table_lookup (domain->refobject_hash, &e))) {   \
                        mono_domain_unlock (domain);    \
                        return _obj;    \
@@ -5097,6 +5177,8 @@ reflected_hash (gconstpointer a) {
 
 #if HAVE_BOEHM_GC
 #define ALLOC_REFENTRY GC_MALLOC (sizeof (ReflectedEntry))
+#elif HAVE_SGEN_GC
+#define ALLOC_REFENTRY mono_gc_alloc_fixed (sizeof (ReflectedEntry), NULL)
 #else
 #define ALLOC_REFENTRY mono_mempool_alloc (domain->mp, sizeof (ReflectedEntry))
 #endif
@@ -5109,7 +5191,7 @@ reflected_hash (gconstpointer a) {
         pe.refclass = (k); \
         mono_domain_lock (domain); \
                if (!domain->refobject_hash)    \
-                       domain->refobject_hash = mono_g_hash_table_new (reflected_hash, reflected_equal);       \
+                       domain->refobject_hash = mono_g_hash_table_new_type (reflected_hash, reflected_equal, MONO_HASH_VALUE_GC);      \
         _obj = mono_g_hash_table_lookup (domain->refobject_hash, &pe); \
         if (!_obj) { \
                    ReflectedEntry *e = ALLOC_REFENTRY;         \
@@ -5163,6 +5245,7 @@ mono_image_module_basic_init (MonoReflectionModuleBuilder *moduleb)
                if (ass->modules)
                        memcpy (new_modules, ass->modules, module_count * sizeof (MonoImage *));
                new_modules [module_count] = &image->image;
+               mono_image_addref (&image->image);
 
                g_free (ass->modules);
                ass->modules = new_modules;
@@ -5209,11 +5292,12 @@ mono_module_get_object   (MonoDomain *domain, MonoImage *image)
        res = (MonoReflectionModule *)mono_object_new (domain, System_Reflection_Module);
 
        res->image = image;
-       res->assembly = (MonoReflectionAssembly *) mono_assembly_get_object(domain, image->assembly);
+       MONO_OBJECT_SETREF (res, assembly, (MonoReflectionAssembly *) mono_assembly_get_object(domain, image->assembly));
 
-       res->fqname    = mono_string_new (domain, image->name);
-       res->name      = mono_string_new (domain, basename = g_path_get_basename (image->name));
-       res->scopename = mono_string_new (domain, image->module_name);
+       MONO_OBJECT_SETREF (res, fqname, mono_string_new (domain, image->name));
+       basename = g_path_get_basename (image->name);
+       MONO_OBJECT_SETREF (res, name, mono_string_new (domain, basename));
+       MONO_OBJECT_SETREF (res, scopename, mono_string_new (domain, image->module_name));
        
        g_free (basename);
 
@@ -5230,8 +5314,6 @@ mono_module_get_object   (MonoDomain *domain, MonoImage *image)
                g_assert (res->token);
        }
 
-       mono_image_addref (image);
-
        CACHE_OBJECT (MonoReflectionModule *, image, res, NULL);
 }
 
@@ -5255,8 +5337,8 @@ mono_module_file_get_object (MonoDomain *domain, MonoImage *image, int table_ind
        g_assert (table_index < table->rows);
        mono_metadata_decode_row (table, table_index, cols, MONO_FILE_SIZE);
 
-       res->image = 0;
-       res->assembly = (MonoReflectionAssembly *) mono_assembly_get_object(domain, image->assembly);
+       res->image = NULL;
+       MONO_OBJECT_SETREF (res, assembly, (MonoReflectionAssembly *) mono_assembly_get_object(domain, image->assembly));
        name = mono_metadata_string_heap (image, cols [MONO_FILE_NAME]);
 
        /* Check whenever the row has a corresponding row in the moduleref table */
@@ -5268,9 +5350,9 @@ mono_module_file_get_object (MonoDomain *domain, MonoImage *image, int table_ind
                        res->image = image->modules [i];
        }
 
-       res->fqname    = mono_string_new (domain, name);
-       res->name      = mono_string_new (domain, name);
-       res->scopename = mono_string_new (domain, name);
+       MONO_OBJECT_SETREF (res, fqname, mono_string_new (domain, name));
+       MONO_OBJECT_SETREF (res, name, mono_string_new (domain, name));
+       MONO_OBJECT_SETREF (res, scopename, mono_string_new (domain, name));
        res->is_resource = cols [MONO_FILE_FLAGS] && FILE_CONTAINS_NO_METADATA;
        res->token = mono_metadata_make_token (MONO_TABLE_FILE, table_index + 1);
 
@@ -5393,9 +5475,9 @@ mono_generic_class_get_object (MonoDomain *domain, MonoType *geninst)
 
        res->type.type = geninst;
        if (gklass->wastypebuilder && gklass->reflection_info)
-               res->generic_type = gklass->reflection_info;
+               MONO_OBJECT_SETREF (res, generic_type, gklass->reflection_info);
        else
-               res->generic_type = mono_type_get_object (domain, &gklass->byval_arg);
+               MONO_OBJECT_SETREF (res, generic_type, mono_type_get_object (domain, &gklass->byval_arg));
 
        return res;
 }
@@ -5444,8 +5526,8 @@ mono_type_get_object (MonoDomain *domain, MonoType *type)
 
        mono_domain_lock (domain);
        if (!domain->type_hash)
-               domain->type_hash = mono_g_hash_table_new ((GHashFunc)mymono_metadata_type_hash, 
-                               (GCompareFunc)mymono_metadata_type_equal);
+               domain->type_hash = mono_g_hash_table_new_type ((GHashFunc)mymono_metadata_type_hash, 
+                               (GCompareFunc)mymono_metadata_type_equal, MONO_HASH_VALUE_GC);
        if ((res = mono_g_hash_table_lookup (domain->type_hash, type))) {
                mono_domain_unlock (domain);
                return res;
@@ -5471,7 +5553,11 @@ mono_type_get_object (MonoDomain *domain, MonoType *type)
                }
        }
        mono_class_init (klass);
+#ifdef HAVE_SGEN_GC
+       res = (MonoReflectionType *)mono_gc_alloc_pinned_obj (mono_class_vtable (domain, mono_defaults.monotype_class), mono_class_instance_size (mono_defaults.monotype_class));
+#else
        res = (MonoReflectionType *)mono_object_new (domain, mono_defaults.monotype_class);
+#endif
        res->type = type;
        mono_g_hash_table_insert (domain->type_hash, type, res);
        mono_domain_unlock (domain);
@@ -5511,8 +5597,8 @@ mono_method_get_object (MonoDomain *domain, MonoMethod *method, MonoClass *refcl
 
                gret = (MonoReflectionGenericMethod*)mono_object_new (domain, klass);
                gret->method.method = method;
-               gret->method.name = mono_string_new (domain, method->name);
-               gret->method.reftype = mono_type_get_object (domain, &refclass->byval_arg);
+               MONO_OBJECT_SETREF (gret, method.name, mono_string_new (domain, method->name));
+               MONO_OBJECT_SETREF (gret, method.reftype, mono_type_get_object (domain, &refclass->byval_arg));
                CACHE_OBJECT (MonoReflectionMethod *, method, (MonoReflectionMethod*)gret, refclass);
        }
 
@@ -5528,8 +5614,8 @@ mono_method_get_object (MonoDomain *domain, MonoMethod *method, MonoClass *refcl
 
        ret = (MonoReflectionMethod*)mono_object_new (domain, klass);
        ret->method = method;
-       ret->name = mono_string_new (domain, method->name);
-       ret->reftype = mono_type_get_object (domain, &refclass->byval_arg);
+       MONO_OBJECT_SETREF (ret, name, mono_string_new (domain, method->name));
+       MONO_OBJECT_SETREF (ret, reftype, mono_type_get_object (domain, &refclass->byval_arg));
        CACHE_OBJECT (MonoReflectionMethod *, method, ret, refclass);
 }
 
@@ -5553,12 +5639,12 @@ mono_field_get_object (MonoDomain *domain, MonoClass *klass, MonoClassField *fie
        res = (MonoReflectionField *)mono_object_new (domain, oklass);
        res->klass = klass;
        res->field = field;
-       res->name = mono_string_new (domain, field->name);
+       MONO_OBJECT_SETREF (res, name, mono_string_new (domain, field->name));
        if (field->generic_info)
                res->attrs = field->generic_info->generic_type->attrs;
        else
                res->attrs = field->type->attrs;
-       res->type = mono_type_get_object (domain, field->type);
+       MONO_OBJECT_SETREF (res, type, mono_type_get_object (domain, field->type));
        CACHE_OBJECT (MonoReflectionField *, field, res, klass);
 }
 
@@ -5652,14 +5738,14 @@ mono_param_get_objects (MonoDomain *domain, MonoMethod *method)
        res = mono_array_new (domain, System_Reflection_ParameterInfo, mono_method_signature (method)->param_count);
        for (i = 0; i < mono_method_signature (method)->param_count; ++i) {
                param = (MonoReflectionParameter *)mono_object_new (domain, System_Reflection_ParameterInfo);
-               param->ClassImpl = mono_type_get_object (domain, mono_method_signature (method)->params [i]);
-               param->MemberImpl = (MonoObject*)member;
-               param->NameImpl = mono_string_new (domain, names [i]);
+               MONO_OBJECT_SETREF (param, ClassImpl, mono_type_get_object (domain, mono_method_signature (method)->params [i]));
+               MONO_OBJECT_SETREF (param, MemberImpl, (MonoObject*)member);
+               MONO_OBJECT_SETREF (param, NameImpl, mono_string_new (domain, names [i]));
                param->PositionImpl = i;
                param->AttrsImpl = mono_method_signature (method)->params [i]->attrs;
 
                if (!(param->AttrsImpl & PARAM_ATTRIBUTE_HAS_DEFAULT)) {
-                       param->DefaultValueImpl = dbnull;
+                       MONO_OBJECT_SETREF (param, DefaultValueImpl, dbnull);
                } else {
 
                        if (!blobs) {
@@ -5678,16 +5764,16 @@ mono_param_get_objects (MonoDomain *domain, MonoMethod *method)
                        else    
                                type->data.klass = mono_class_from_mono_type (type);
                        
-                       param->DefaultValueImpl = mono_get_object_from_blob (domain, type, blobs [i]);
+                       MONO_OBJECT_SETREF (param, DefaultValueImpl, mono_get_object_from_blob (domain, type, blobs [i]));
 
                        /* Type in the Constant table is MONO_TYPE_CLASS for nulls */
                        if (types [i] != MONO_TYPE_CLASS && !param->DefaultValueImpl) 
-                               param->DefaultValueImpl = dbnull;
+                               MONO_OBJECT_SETREF (param, DefaultValueImpl, dbnull);
                        
                }
 
                if (mspecs [i + 1])
-                       param->MarshalAsImpl = (MonoObject*)mono_reflection_marshal_from_marshal_spec (domain, method->klass, mspecs [i + 1]);
+                       MONO_OBJECT_SETREF (param, MarshalAsImpl, (MonoObject*)mono_reflection_marshal_from_marshal_spec (domain, method->klass, mspecs [i + 1]));
                
                mono_array_setref (res, i, param);
        }
@@ -5767,21 +5853,21 @@ mono_method_body_get_object (MonoDomain *domain, MonoMethod *method)
        ret->init_locals = header->init_locals;
        ret->max_stack = header->max_stack;
        ret->local_var_sig_token = local_var_sig_token;
-       ret->il = mono_array_new (domain, mono_defaults.byte_class, header->code_size);
-       memcpy (mono_array_addr (ret->il, guint8*, 0), header->code, header->code_size);
+       MONO_OBJECT_SETREF (ret, il, mono_array_new (domain, mono_defaults.byte_class, header->code_size));
+       memcpy (mono_array_addr (ret->il, guint8, 0), header->code, header->code_size);
 
        /* Locals */
-       ret->locals = mono_array_new (domain, System_Reflection_LocalVariableInfo, header->num_locals);
+       MONO_OBJECT_SETREF (ret, locals, mono_array_new (domain, System_Reflection_LocalVariableInfo, header->num_locals));
        for (i = 0; i < header->num_locals; ++i) {
                MonoReflectionLocalVariableInfo *info = (MonoReflectionLocalVariableInfo*)mono_object_new (domain, System_Reflection_LocalVariableInfo);
-               info->local_type = mono_type_get_object (domain, header->locals [i]);
+               MONO_OBJECT_SETREF (info, local_type, mono_type_get_object (domain, header->locals [i]));
                info->is_pinned = header->locals [i]->pinned;
                info->local_index = i;
                mono_array_setref (ret->locals, i, info);
        }
 
        /* Exceptions */
-       ret->clauses = mono_array_new (domain, System_Reflection_ExceptionHandlingClause, header->num_clauses);
+       MONO_OBJECT_SETREF (ret, clauses, mono_array_new (domain, System_Reflection_ExceptionHandlingClause, header->num_clauses));
        for (i = 0; i < header->num_clauses; ++i) {
                MonoReflectionExceptionHandlingClause *info = (MonoReflectionExceptionHandlingClause*)mono_object_new (domain, System_Reflection_ExceptionHandlingClause);
                MonoExceptionClause *clause = &header->clauses [i];
@@ -5794,7 +5880,7 @@ mono_method_body_get_object (MonoDomain *domain, MonoMethod *method)
                if (clause->flags == MONO_EXCEPTION_CLAUSE_FILTER)
                        info->filter_offset = clause->data.filter_offset;
                else if (clause->data.catch_class)
-                       info->catch_type = mono_type_get_object (mono_domain_get (), &clause->data.catch_class->byval_arg);
+                       MONO_OBJECT_SETREF (info, catch_type, mono_type_get_object (mono_domain_get (), &clause->data.catch_class->byval_arg));
 
                mono_array_setref (ret->clauses, i, info);
        }
@@ -6536,6 +6622,8 @@ static void*
 load_cattr_value (MonoImage *image, MonoType *t, const char *p, const char **end)
 {
        int slen, type = t->type;
+       MonoClass *tklass = t->data.klass;
+
 handle_enum:
        switch (type) {
        case MONO_TYPE_U1:
@@ -6626,6 +6714,15 @@ handle_type:
                } else if (subt == 0x0E) {
                        type = MONO_TYPE_STRING;
                        goto handle_enum;
+               } else if (subt == 0x1D) {
+                       MonoType simple_type = {{0}};
+                       int etype = *p;
+                       p ++;
+
+                       type = MONO_TYPE_SZARRAY;
+                       simple_type.type = etype;
+                       tklass = mono_class_from_mono_type (&simple_type);
+                       goto handle_enum;
                } else if (subt == 0x55) {
                        char *n;
                        MonoType *t;
@@ -6660,8 +6757,8 @@ handle_type:
                        *end = p;
                        return NULL;
                }
-               arr = mono_array_new (mono_domain_get(), t->data.klass, alen);
-               basetype = t->data.klass->byval_arg.type;
+               arr = mono_array_new (mono_domain_get(), tklass, alen);
+               basetype = tklass->byval_arg.type;
                switch (basetype)
                {
                        case MONO_TYPE_U1:
@@ -6703,7 +6800,7 @@ handle_type:
                        case MONO_TYPE_OBJECT:
                        case MONO_TYPE_STRING:
                                for (i = 0; i < alen; i++) {
-                                       MonoObject *item = load_cattr_value (image, &t->data.klass->byval_arg, p, &p);
+                                       MonoObject *item = load_cattr_value (image, &tklass->byval_arg, p, &p);
                                        mono_array_setref (arr, i, item);
                                }
                                break;
@@ -7069,7 +7166,7 @@ mono_custom_attrs_construct (MonoCustomAttrInfo *cinfo)
        return result;
 }
 
-MonoArray*
+static MonoArray*
 mono_custom_attrs_construct_by_type (MonoCustomAttrInfo *cinfo, MonoClass *attr_klass)
 {
        MonoArray *result;
@@ -7096,7 +7193,7 @@ mono_custom_attrs_construct_by_type (MonoCustomAttrInfo *cinfo, MonoClass *attr_
        return result;
 }
 
-MonoArray*
+static MonoArray*
 mono_custom_attrs_data_construct (MonoCustomAttrInfo *cinfo)
 {
        MonoArray *result;
@@ -7494,14 +7591,17 @@ mono_reflection_get_custom_attrs_data (MonoObject *obj)
        return result;
 }
 
+/**
+ * LOCKING: Assumes the loader lock is held.
+ */
 static MonoMethodSignature*
-parameters_to_signature (MonoArray *parameters) {
+parameters_to_signature (MonoMemPool *mp, MonoArray *parameters) {
        MonoMethodSignature *sig;
        int count, i;
 
        count = parameters? mono_array_length (parameters): 0;
 
-       sig = g_malloc0 (sizeof (MonoMethodSignature) + sizeof (MonoType*) * count);
+       sig = mp_g_malloc0 (mp, sizeof (MonoMethodSignature) + sizeof (MonoType*) * count);
        sig->param_count = count;
        sig->sentinelpos = -1; /* FIXME */
        for (i = 0; i < count; ++i) {
@@ -7511,21 +7611,27 @@ parameters_to_signature (MonoArray *parameters) {
        return sig;
 }
 
+/**
+ * LOCKING: Assumes the loader lock is held.
+ */
 static MonoMethodSignature*
-ctor_builder_to_signature (MonoReflectionCtorBuilder *ctor) {
+ctor_builder_to_signature (MonoMemPool *mp, MonoReflectionCtorBuilder *ctor) {
        MonoMethodSignature *sig;
 
-       sig = parameters_to_signature (ctor->parameters);
+       sig = parameters_to_signature (mp, ctor->parameters);
        sig->hasthis = ctor->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
        sig->ret = &mono_defaults.void_class->byval_arg;
        return sig;
 }
 
+/**
+ * LOCKING: Assumes the loader lock is held.
+ */
 static MonoMethodSignature*
-method_builder_to_signature (MonoReflectionMethodBuilder *method) {
+method_builder_to_signature (MonoMemPool *mp, MonoReflectionMethodBuilder *method) {
        MonoMethodSignature *sig;
 
-       sig = parameters_to_signature (method->parameters);
+       sig = parameters_to_signature (mp, method->parameters);
        sig->hasthis = method->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
        sig->ret = method->rtype? method->rtype->type: &mono_defaults.void_class->byval_arg;
        sig->generic_param_count = method->generic_params ? mono_array_length (method->generic_params) : 0;
@@ -7536,7 +7642,7 @@ static MonoMethodSignature*
 dynamic_method_to_signature (MonoReflectionDynamicMethod *method) {
        MonoMethodSignature *sig;
 
-       sig = parameters_to_signature (method->parameters);
+       sig = parameters_to_signature (NULL, method->parameters);
        sig->hasthis = method->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
        sig->ret = method->rtype? method->rtype->type: &mono_defaults.void_class->byval_arg;
        sig->generic_param_count = 0;
@@ -7705,7 +7811,19 @@ handle_type:
                *retbuffer = buffer;
                eclass = type->data.klass;
                arg_eclass = mono_object_class (arg)->element_class;
-               if (eclass->valuetype && arg_eclass->valuetype) {
+
+               if (!eclass) {
+                       /* Happens when we are called from the MONO_TYPE_OBJECT case below */
+                       eclass = mono_defaults.object_class;
+               }
+               if (eclass == mono_defaults.object_class && arg_eclass->valuetype) {
+                       char *elptr = mono_array_addr ((MonoArray*)arg, char, 0);
+                       int elsize = mono_class_array_element_size (arg_eclass);
+                       for (i = 0; i < len; ++i) {
+                               encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &arg_eclass->byval_arg, NULL, elptr);
+                               elptr += elsize;
+                       }
+               } else if (eclass->valuetype && arg_eclass->valuetype) {
                        char *elptr = mono_array_addr ((MonoArray*)arg, char, 0);
                        int elsize = mono_class_array_element_size (eclass);
                        for (i = 0; i < len; ++i) {
@@ -7719,12 +7837,17 @@ handle_type:
                }
                break;
        }
-       /* it may be a boxed value or a Type */
        case MONO_TYPE_OBJECT: {
                MonoClass *klass;
                char *str;
                guint32 slen;
 
+               /*
+                * The parameter type is 'object' but the type of the actual
+                * argument is not. So we have to add type information to the blob
+                * too. This is completely undocumented in the spec.
+                */
+
                if (arg == NULL) {
                        *p++ = MONO_TYPE_STRING;        // It's same hack as MS uses
                        *p++ = 0xFF;
@@ -7733,7 +7856,7 @@ handle_type:
                
                klass = mono_object_class (arg);
 
-               if (mono_object_isinst (arg, mono_defaults.monotype_class)) {
+               if (mono_object_isinst (arg, mono_defaults.systemtype_class)) {
                        *p++ = 0x50;
                        goto handle_type;
                } else if (klass->enumtype) {
@@ -7742,6 +7865,11 @@ handle_type:
                        simple_type = MONO_TYPE_STRING;
                        *p++ = 0x0E;
                        goto handle_enum;
+               } else if (klass->rank == 1) {
+                       simple_type = MONO_TYPE_SZARRAY;
+                       *p++ = 0x1D;
+                       *p++ = klass->element_class->byval_arg.type;
+                       goto handle_enum;
                } else if (klass->byval_arg.type >= MONO_TYPE_BOOLEAN && klass->byval_arg.type <= MONO_TYPE_R8) {
                        *p++ = simple_type = klass->byval_arg.type;
                        goto handle_enum;
@@ -7852,10 +7980,12 @@ mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObj
        MONO_ARCH_SAVE_REGS;
 
        if (strcmp (ctor->vtable->klass->name, "MonoCMethod")) {
-               sig = ctor_builder_to_signature ((MonoReflectionCtorBuilder*)ctor);
+               /* sig is freed later so allocate it in the heap */
+               sig = ctor_builder_to_signature (NULL, (MonoReflectionCtorBuilder*)ctor);
        } else {
                sig = mono_method_signature (((MonoReflectionMethod*)ctor)->method);
        }
+
        g_assert (mono_array_length (ctorArgs) == sig->param_count);
        buflen = 256;
        p = buffer = g_malloc (buflen);
@@ -7912,6 +8042,10 @@ mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObj
        return result;
 }
 
+#if HAVE_SGEN_GC
+static void* reflection_info_desc = NULL;
+#endif
+
 /*
  * mono_reflection_setup_internal_class:
  * @tb: a TypeBuilder object
@@ -7946,26 +8080,33 @@ mono_reflection_setup_internal_class (MonoReflectionTypeBuilder *tb)
                klass = mono_class_from_mono_type (tb->type.type);
                klass->parent = NULL;
                /* fool mono_class_setup_parent */
-               g_free (klass->supertypes);
                klass->supertypes = NULL;
                mono_class_setup_parent (klass, parent);
                mono_class_setup_mono_type (klass);
                mono_loader_unlock ();
                return;
        }
-       
-       klass = g_new0 (MonoClass, 1);
+
+       klass = mono_mempool_alloc0 (tb->module->dynamic_image->image.mempool, sizeof (MonoClass));
 
        klass->image = &tb->module->dynamic_image->image;
 
        klass->inited = 1; /* we lie to the runtime */
-       klass->name = mono_string_to_utf8 (tb->name);
-       klass->name_space = mono_string_to_utf8 (tb->nspace);
+       klass->name = mono_string_to_utf8_mp (klass->image->mempool, tb->name);
+       klass->name_space = mono_string_to_utf8_mp (klass->image->mempool, tb->nspace);
        klass->type_token = MONO_TOKEN_TYPE_DEF | tb->table_idx;
        klass->flags = tb->attrs;
 
        klass->element_class = klass;
-       klass->reflection_info = tb; /* need to pin. */
+
+#if HAVE_SGEN_GC
+       if (!reflection_info_desc) {
+               gsize bmap = 1;
+               reflection_info_desc = mono_gc_make_descr_from_bitmap (&bmap, 1);
+       }
+       mono_gc_register_root (&klass->reflection_info, sizeof (gpointer), reflection_info_desc);
+#endif
+       klass->reflection_info = tb;
 
        /* Put into cache so mono_class_get () will find it */
        mono_image_add_to_name_cache (klass->image, klass->name_space, klass->name, tb->table_idx);
@@ -8194,12 +8335,12 @@ mono_reflection_marshal_from_marshal_spec (MonoDomain *domain, MonoClass *klass,
                if (spec->data.custom_data.custom_name) {
                        mtype = mono_reflection_type_from_name (spec->data.custom_data.custom_name, klass->image);
                        if (mtype)
-                               minfo->marshaltyperef = mono_type_get_object (domain, mtype);
+                               MONO_OBJECT_SETREF (minfo, marshaltyperef, mono_type_get_object (domain, mtype));
 
-                       minfo->marshaltype = mono_string_new (domain, spec->data.custom_data.custom_name);
+                       MONO_OBJECT_SETREF (minfo, marshaltype, mono_string_new (domain, spec->data.custom_data.custom_name));
                }
                if (spec->data.custom_data.cookie)
-                       minfo->mcookie = mono_string_new (domain, spec->data.custom_data.cookie);
+                       MONO_OBJECT_SETREF (minfo, mcookie, mono_string_new (domain, spec->data.custom_data.cookie));
                break;
 
        default:
@@ -8218,24 +8359,36 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
        MonoMethodNormal *pm;
        MonoMarshalSpec **specs;
        MonoReflectionMethodAux *method_aux;
+       MonoMemPool *mp;
+       gboolean dynamic;
        int i;
 
        g_assert (!klass->generic_class);
 
+       /*
+        * Methods created using a MethodBuilder should have their memory allocated
+        * inside the image mempool, while dynamic methods should have their memory
+        * malloc'd.
+        */
+       dynamic = rmb->refs != NULL;
+       mp = dynamic ? NULL : klass->image->mempool;
+
+       mono_loader_lock ();
+
        if ((rmb->attrs & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
                        (rmb->iattrs & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
-               m = (MonoMethod *)g_new0 (MonoMethodPInvoke, 1);
+               m = (MonoMethod *)mp_g_new0 (mp, MonoMethodPInvoke, 1);
        else if (rmb->refs)
-               m = (MonoMethod *)g_new0 (MonoMethodWrapper, 1);
+               m = (MonoMethod *)mp_g_new0 (mp, MonoMethodWrapper, 1);
        else
-               m = (MonoMethod *)g_new0 (MonoMethodNormal, 1);
+               m = (MonoMethod *)mp_g_new0 (mp, MonoMethodNormal, 1);
 
        pm = (MonoMethodNormal*)m;
 
        m->slot = -1;
        m->flags = rmb->attrs;
        m->iflags = rmb->iattrs;
-       m->name = mono_string_to_utf8 (rmb->name);
+       m->name = dynamic ? mono_string_to_utf8 (rmb->name) : mono_string_to_utf8_mp (mp, rmb->name);
        m->klass = klass;
        m->signature = sig;
        if (rmb->table_idx)
@@ -8251,14 +8404,16 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
 
                method_aux = g_new0 (MonoReflectionMethodAux, 1);
 
-               method_aux->dllentry = rmb->dllentry ? g_strdup (mono_string_to_utf8 (rmb->dllentry)) : g_strdup (m->name);
-               method_aux->dll = g_strdup (mono_string_to_utf8 (rmb->dll));
+               method_aux->dllentry = rmb->dllentry ? mono_string_to_utf8_mp (mp, rmb->dllentry) : mono_mempool_strdup (mp, m->name);
+               method_aux->dll = mono_string_to_utf8_mp (mp, rmb->dll);
                
                ((MonoMethodPInvoke*)m)->piflags = (rmb->native_cc << 8) | (rmb->charset ? (rmb->charset - 1) * 2 : 0) | rmb->extra_flags;
 
                if (klass->image->dynamic)
                        g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
 
+               mono_loader_unlock ();
+
                return m;
        } else if (!m->klass->dummy && 
                           !(m->flags & METHOD_ATTRIBUTE_ABSTRACT) &&
@@ -8291,10 +8446,10 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
                        }
                }
 
-               header = g_malloc0 (sizeof (MonoMethodHeader) + 
+               header = mp_g_malloc0 (mp, sizeof (MonoMethodHeader) + 
                        (num_locals - MONO_ZERO_LEN_ARRAY) * sizeof (MonoType*));
                header->code_size = code_size;
-               header->code = g_malloc (code_size);
+               header->code = mp_g_malloc (mp, code_size);
                memcpy ((char*)header->code, code, code_size);
                header->max_stack = max_stack;
                header->init_locals = rmb->init_locals;
@@ -8304,7 +8459,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
                        MonoReflectionLocalBuilder *lb = 
                                mono_array_get (rmb->ilgen->locals, MonoReflectionLocalBuilder*, i);
 
-                       header->locals [i] = g_new0 (MonoType, 1);
+                       header->locals [i] = mp_g_new0 (mp, MonoType, 1);
                        memcpy (header->locals [i], lb->type->type, sizeof (MonoType));
                }
 
@@ -8350,7 +8505,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
 
                m->wrapper_type = MONO_WRAPPER_DYNAMIC_METHOD;
 
-               mw->method_data = data = g_new (gpointer, rmb->nrefs + 1);
+               mw->method_data = data = mp_g_new (mp, gpointer, rmb->nrefs + 1);
                data [0] = GUINT_TO_POINTER (rmb->nrefs);
                for (i = 0; i < rmb->nrefs; ++i)
                        data [i + 1] = rmb->refs [i];
@@ -8361,13 +8516,14 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
        /* Parameter info */
        if (rmb->pinfo) {
                if (!method_aux)
-                       method_aux = g_new0 (MonoReflectionMethodAux, 1);
-               method_aux->param_names = g_new0 (char *, mono_method_signature (m)->param_count + 1);
+                       method_aux = mp_g_new0 (mp, MonoReflectionMethodAux, 1);
+               method_aux->param_names = mp_g_new0 (mp, char *, mono_method_signature (m)->param_count + 1);
                for (i = 0; i <= m->signature->param_count; ++i) {
                        MonoReflectionParamBuilder *pb;
                        if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
                                if ((i > 0) && (pb->attrs)) {
                                        /* Make a copy since it might point to a shared type structure */
+                                       /* FIXME: Alloc this from a mempool */
                                        m->signature->params [i - 1] = g_memdup (m->signature->params [i - 1], sizeof (MonoType) + ((m->signature->params [i - 1]->num_mods - MONO_ZERO_LEN_ARRAY) * sizeof (MonoCustomMod)));
                                        m->signature->params [i - 1]->attrs = pb->attrs;
                                }
@@ -8379,8 +8535,8 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
                                        const char *p2;
 
                                        if (!method_aux->param_defaults) {
-                                               method_aux->param_defaults = g_new0 (guint8*, m->signature->param_count + 1);
-                                               method_aux->param_default_types = g_new0 (guint32, m->signature->param_count + 1);
+                                               method_aux->param_defaults = mp_g_new0 (mp, guint8*, m->signature->param_count + 1);
+                                               method_aux->param_default_types = mp_g_new0 (mp, guint32, m->signature->param_count + 1);
                                        }
                                        assembly = (MonoDynamicImage*)klass->image;
                                        idx = encode_constant (assembly, pb->def_value, &def_type);
@@ -8388,16 +8544,16 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
                                        p = assembly->blob.data + idx;
                                        len = mono_metadata_decode_blob_size (p, &p2);
                                        len += p2 - p;
-                                       method_aux->param_defaults [i] = g_malloc (len);
+                                       method_aux->param_defaults [i] = mp_g_malloc (mp, len);
                                        method_aux->param_default_types [i] = def_type;
                                        memcpy ((gpointer)method_aux->param_defaults [i], p, len);
                                }
 
                                if (pb->name)
-                                       method_aux->param_names [i] = mono_string_to_utf8 (pb->name);
+                                       method_aux->param_names [i] = dynamic ? mono_string_to_utf8 (pb->name) : mono_string_to_utf8_mp (mp, pb->name);
                                if (pb->cattrs) {
                                        if (!method_aux->param_cattr)
-                                               method_aux->param_cattr = g_new0 (MonoCustomAttrInfo*, m->signature->param_count + 1);
+                                               method_aux->param_cattr = mp_g_new0 (mp, MonoCustomAttrInfo*, m->signature->param_count + 1);
                                        method_aux->param_cattr [i] = mono_custom_attrs_from_builders (klass->image, pb->cattrs);
                                }
                        }
@@ -8412,7 +8568,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
                        if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
                                if (pb->marshal_info) {
                                        if (specs == NULL)
-                                               specs = g_new0 (MonoMarshalSpec*, sig->param_count + 1);
+                                               specs = mp_g_new0 (mp, MonoMarshalSpec*, sig->param_count + 1);
                                        specs [pb->position] = 
                                                mono_marshal_spec_from_builder (klass->image->assembly, pb->marshal_info);
                                }
@@ -8420,13 +8576,15 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
                }
        if (specs != NULL) {
                if (!method_aux)
-                       method_aux = g_new0 (MonoReflectionMethodAux, 1);
+                       method_aux = mp_g_new0 (mp, MonoReflectionMethodAux, 1);
                method_aux->param_marshall = specs;
        }
 
        if (klass->image->dynamic && method_aux)
                g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
 
+       mono_loader_unlock ();
+
        return m;
 }      
 
@@ -8436,7 +8594,9 @@ ctorbuilder_to_mono_method (MonoClass *klass, MonoReflectionCtorBuilder* mb)
        ReflectionMethodBuilder rmb;
        MonoMethodSignature *sig;
 
-       sig = ctor_builder_to_signature (mb);
+       mono_loader_lock ();
+       sig = ctor_builder_to_signature (klass->image->mempool, mb);
+       mono_loader_unlock ();
 
        reflection_methodbuilder_from_ctor_builder (&rmb, mb);
 
@@ -8457,7 +8617,9 @@ methodbuilder_to_mono_method (MonoClass *klass, MonoReflectionMethodBuilder* mb)
        ReflectionMethodBuilder rmb;
        MonoMethodSignature *sig;
 
-       sig = method_builder_to_signature (mb);
+       mono_loader_lock ();
+       sig = method_builder_to_signature (klass->image->mempool, mb);
+       mono_loader_unlock ();
 
        reflection_methodbuilder_from_method_builder (&rmb, mb);
 
@@ -8478,9 +8640,6 @@ fieldbuilder_to_mono_class_field (MonoClass *klass, MonoReflectionFieldBuilder*
        const char *p, *p2;
        guint32 len, idx;
 
-       if (fb->handle)
-               return fb->handle;
-
        field = g_new0 (MonoClassField, 1);
 
        field->name = mono_string_to_utf8 (fb->name);
@@ -8492,11 +8651,10 @@ fieldbuilder_to_mono_class_field (MonoClass *klass, MonoReflectionFieldBuilder*
                field->type = fb->type->type;
        }
        if ((fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) && fb->rva_data)
-               field->data = mono_array_addr (fb->rva_data, char, 0);
+               field->data = mono_array_addr (fb->rva_data, char, 0); /* FIXME: GC pin array */
        if (fb->offset != -1)
                field->offset = fb->offset;
        field->parent = klass;
-       fb->handle = field;
        mono_save_custom_attrs (klass->image, field, fb->cattrs);
 
        if (fb->def_value) {
@@ -8514,9 +8672,8 @@ fieldbuilder_to_mono_class_field (MonoClass *klass, MonoReflectionFieldBuilder*
        return field;
 }
 
-static MonoType*
-do_mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc, MonoType **types,
-                                           MonoType *parent)
+MonoType*
+mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc, MonoType **types)
 {
        MonoClass *klass;
        MonoReflectionTypeBuilder *tb = NULL;
@@ -8648,67 +8805,11 @@ do_mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_a
        gclass->context->container = gclass->container_class->generic_container;
        gclass->context->gclass = gclass;
 
-       if (is_dynamic)
-               dgclass->parent = parent;
-
        mono_loader_unlock ();
 
        return geninst;
 }
 
-MonoType*
-mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc, MonoType **types)
-{
-       MonoClass *klass, *pklass = NULL;
-       MonoReflectionType *parent = NULL;
-       MonoType *the_parent = NULL, *geninst;
-       MonoReflectionTypeBuilder *tb = NULL;
-       MonoGenericClass *gclass;
-       MonoDomain *domain;
-
-       domain = mono_object_domain (type);
-       klass = mono_class_from_mono_type (type->type);
-
-       if (!strcmp (((MonoObject *) type)->vtable->klass->name, "TypeBuilder")) {
-               tb = (MonoReflectionTypeBuilder *) type;
-
-               if (tb->parent) {
-                       parent = tb->parent;
-                       pklass = mono_class_from_mono_type (parent->type);
-               }
-       } else if (klass->wastypebuilder) {
-               tb = (MonoReflectionTypeBuilder *) klass->reflection_info;
-               if (tb->parent) {
-                       parent = tb->parent;
-                       pklass = mono_class_from_mono_type (parent->type);
-               }
-       } else {
-               pklass = klass->parent;
-               if (pklass)
-                       parent = mono_type_get_object (domain, &pklass->byval_arg);
-               else if (klass->generic_class && klass->generic_class->is_dynamic) {
-                       MonoDynamicGenericClass *dgclass;
-
-                       dgclass = (MonoDynamicGenericClass *) klass->generic_class;
-                       if (dgclass->parent) {
-                               parent = mono_type_get_object (domain, dgclass->parent);
-                               pklass = mono_class_from_mono_type (dgclass->parent);
-                       }
-               }
-       }
-
-       if (pklass && pklass->generic_class)
-               the_parent = mono_reflection_bind_generic_parameters (parent, type_argc, types);
-
-       geninst = do_mono_reflection_bind_generic_parameters (type, type_argc, types, the_parent);
-       if (!geninst)
-               return NULL;
-
-       gclass = geninst->data.generic_class;
-
-       return geninst;
-}
-
 MonoType*
 mono_class_bind_generic_parameters (MonoType *type, int type_argc, MonoType **types)
 {
@@ -8976,7 +9077,7 @@ mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, Mono
 {
        MonoGenericClass *gclass;
        MonoDynamicGenericClass *dgclass;
-       MonoClass *klass, *gklass, *pklass;
+       MonoClass *klass, *gklass;
        int i;
 
        MONO_ARCH_SAVE_REGS;
@@ -8993,11 +9094,6 @@ mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, Mono
        gklass = gclass->container_class;
        mono_class_init (gklass);
 
-       if (dgclass->parent)
-               pklass = mono_class_from_mono_type (dgclass->parent);
-       else
-               pklass = gklass->parent;
-
        dgclass->count_methods = methods ? mono_array_length (methods) : 0;
        dgclass->count_ctors = ctors ? mono_array_length (ctors) : 0;
        dgclass->count_fields = fields ? mono_array_length (fields) : 0;
@@ -9114,7 +9210,7 @@ ensure_runtime_vtable (MonoClass *klass)
        num = tb->ctors? mono_array_length (tb->ctors): 0;
        num += tb->num_methods;
        klass->method.count = num;
-       klass->methods = g_new (MonoMethod*, num);
+       klass->methods = mono_mempool_alloc (klass->image->mempool, sizeof (MonoMethod*) * num);
        num = tb->ctors? mono_array_length (tb->ctors): 0;
        for (i = 0; i < num; ++i)
                klass->methods [i] = ctorbuilder_to_mono_method (klass, mono_array_get (tb->ctors, MonoReflectionCtorBuilder*, i));
@@ -9125,16 +9221,19 @@ ensure_runtime_vtable (MonoClass *klass)
 
        if (tb->interfaces) {
                klass->interface_count = mono_array_length (tb->interfaces);
-               klass->interfaces = g_new (MonoClass*, klass->interface_count);
+               klass->interfaces = mono_mempool_alloc (klass->image->mempool, sizeof (MonoClass*) * klass->interface_count);
                for (i = 0; i < klass->interface_count; ++i) {
                        MonoReflectionType *iface = mono_array_get (tb->interfaces, gpointer, i);
                        klass->interfaces [i] = mono_class_from_mono_type (iface->type);
                }
        }
 
-       if (klass->flags & TYPE_ATTRIBUTE_INTERFACE)
+       if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
                for (i = 0; i < klass->method.count; ++i)
                        klass->methods [i]->slot = i;
+               
+               mono_class_setup_interface_offsets (klass);
+       }
 
        /*
         * The generic vtable is needed even if image->run is not set since some
@@ -9404,8 +9503,8 @@ mono_reflection_create_runtime_class (MonoReflectionTypeBuilder *tb)
        if (klass->parent) {
                if (!klass->parent->size_inited)
                        mono_class_init (klass->parent);
-               klass->instance_size += klass->parent->instance_size;
-               klass->class_size += klass->parent->class_size;
+               klass->instance_size = klass->parent->instance_size;
+               klass->class_size = 0;
                klass->min_align = klass->parent->min_align;
                /* if the type has no fields we won't call the field_setup
                 * routine which sets up klass->has_references.
@@ -9429,6 +9528,7 @@ mono_reflection_create_runtime_class (MonoReflectionTypeBuilder *tb)
 
        res = mono_type_get_object (mono_object_domain (tb), &klass->byval_arg);
        g_assert (res != (MonoReflectionType*)tb);
+
        return res;
 }
 
@@ -9458,7 +9558,7 @@ mono_reflection_initialize_generic_parameter (MonoReflectionGenericParam *gparam
        image = &gparam->tbuilder->module->dynamic_image->image;
        mono_class_from_generic_parameter (param, image, gparam->mbuilder != NULL);
 
-       param->pklass->reflection_info = gparam;
+       param->pklass->reflection_info = gparam; /* FIXME: GC pin gparam */
 
        gparam->type.type = g_new0 (MonoType, 1);
        gparam->type.type->type = gparam->mbuilder ? MONO_TYPE_MVAR : MONO_TYPE_VAR;
@@ -9554,7 +9654,7 @@ mono_reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb)
                        mono_raise_exception (mono_get_exception_type_load (NULL, NULL));
                        return;
                }
-               rmb.refs [i] = ref;
+               rmb.refs [i] = ref; /* FIXME: GC object stored in unamanged memory (change also resolve_object() signature) */
                rmb.refs [i + 1] = handle_class;
        }