2006-05-30 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mono / metadata / reflection.c
index f3bbbfe013d226043500c35b7e5ed914d7e58d6d..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)
 {
@@ -4314,19 +4351,18 @@ create_dynamic_mono_image (MonoDynamicAssembly *assembly, char *assembly_name, c
        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);
@@ -4398,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;
@@ -5118,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)    \
@@ -5129,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;    \
@@ -5139,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
@@ -5151,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;         \
@@ -5486,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;
@@ -5513,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);
@@ -6578,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:
@@ -6668,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;
@@ -6702,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:
@@ -6745,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;
@@ -7111,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;
@@ -7138,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;
@@ -7536,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) {
@@ -7553,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;
@@ -7578,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;
@@ -7747,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) {
@@ -7761,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;
@@ -7784,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;
@@ -7894,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);
@@ -7954,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
@@ -7994,19 +8086,27 @@ mono_reflection_setup_internal_class (MonoReflectionTypeBuilder *tb)
                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; /* FIXME: GC 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);
@@ -8259,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)
@@ -8292,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) &&
@@ -8332,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;
@@ -8345,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));
                }
 
@@ -8391,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];
@@ -8402,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;
                                }
@@ -8420,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);
@@ -8429,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);
                                }
                        }
@@ -8453,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);
                                }
@@ -8461,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;
 }      
 
@@ -8477,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);
 
@@ -8498,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);
 
@@ -9089,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));
@@ -9100,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
@@ -9379,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.