Merge pull request #1952 from esdrubal/proc_name
[mono.git] / mono / metadata / object.c
index dcd321e8c520e59f695624ef176649cae2aeb93f..fbf8a288446f3afb2d497ed34fde442de3e09b7e 100644 (file)
@@ -27,7 +27,6 @@
 #include "mono/metadata/metadata-internals.h"
 #include "mono/metadata/class-internals.h"
 #include <mono/metadata/assembly.h>
-#include <mono/metadata/threadpool.h>
 #include <mono/metadata/marshal.h>
 #include "mono/metadata/debug-helpers.h"
 #include "mono/metadata/marshal.h"
 #include <mono/utils/mono-memory-model.h>
 #include "cominterop.h"
 
-#ifdef HAVE_BOEHM_GC
-#define NEED_TO_ZERO_PTRFREE 1
-#define ALLOC_PTRFREE(obj,vt,size) do { (obj) = GC_MALLOC_ATOMIC ((size)); (obj)->vtable = (vt); (obj)->synchronisation = NULL;} while (0)
-#define ALLOC_OBJECT(obj,vt,size) do { (obj) = GC_MALLOC ((size)); (obj)->vtable = (vt);} while (0)
-#ifdef HAVE_GC_GCJ_MALLOC
-#define GC_NO_DESCRIPTOR ((gpointer)(0 | GC_DS_LENGTH))
-#define ALLOC_TYPED(dest,size,type) do { (dest) = GC_GCJ_MALLOC ((size),(type)); } while (0)
-#else
-#define GC_NO_DESCRIPTOR (NULL)
-#define ALLOC_TYPED(dest,size,type) do { (dest) = GC_MALLOC ((size)); *(gpointer*)dest = (type);} while (0)
-#endif
-#else
-#ifdef HAVE_SGEN_GC
-#define GC_NO_DESCRIPTOR (NULL)
-#define ALLOC_PTRFREE(obj,vt,size) do { (obj) = mono_gc_alloc_obj (vt, size);} while (0)
-#define ALLOC_OBJECT(obj,vt,size) do { (obj) = mono_gc_alloc_obj (vt, size);} while (0)
-#define ALLOC_TYPED(dest,size,type) do { (dest) = mono_gc_alloc_obj (type, size);} while (0)
-#else
-#define NEED_TO_ZERO_PTRFREE 1
-#define GC_NO_DESCRIPTOR (NULL)
-#define ALLOC_PTRFREE(obj,vt,size) do { (obj) = malloc ((size)); (obj)->vtable = (vt); (obj)->synchronisation = NULL;} while (0)
-#define ALLOC_OBJECT(obj,vt,size) do { (obj) = calloc (1, (size)); (obj)->vtable = (vt);} while (0)
-#define ALLOC_TYPED(dest,size,type) do { (dest) = calloc (1, (size)); *(gpointer*)dest = (type);} while (0)
-#endif
-#endif
-
-static MonoObject* mono_object_new_ptrfree (MonoVTable *vtable);
-static MonoObject* mono_object_new_ptrfree_box (MonoVTable *vtable);
-
 static void
 get_default_field_value (MonoDomain* domain, MonoClassField *field, void *value);
 
@@ -91,8 +61,6 @@ mono_string_to_utf8_internal (MonoMemPool *mp, MonoImage *image, MonoString *s,
 #define ldstr_unlock() mono_mutex_unlock (&ldstr_section)
 static mono_mutex_t ldstr_section;
 
-static gboolean profile_allocs = TRUE;
-
 void
 mono_runtime_object_init (MonoObject *this)
 {
@@ -144,6 +112,21 @@ typedef struct
 #define mono_type_initialization_unlock() mono_mutex_unlock (&type_initialization_section)
 static mono_mutex_t type_initialization_section;
 
+
+static void
+mono_type_init_lock (TypeInitializationLock *lock)
+{
+       MONO_TRY_BLOCKING;
+       mono_mutex_lock (&lock->initialization_section);
+       MONO_FINISH_TRY_BLOCKING;
+}
+
+static void
+mono_type_init_unlock (TypeInitializationLock *lock)
+{
+       mono_mutex_unlock (&lock->initialization_section);
+}
+
 /* from vtable to lock */
 static GHashTable *type_initialization_hash;
 
@@ -347,7 +330,7 @@ mono_runtime_class_init_full (MonoVTable *vtable, gboolean raise_exception)
                        lock->waiting_count = 1;
                        lock->done = FALSE;
                        /* grab the vtable lock while this thread still owns type_initialization_section */
-                       mono_mutex_lock (&lock->initialization_section);
+                       mono_type_init_lock (lock);
                        g_hash_table_insert (type_initialization_hash, vtable, lock);
                        do_initialization = 1;
                } else {
@@ -412,11 +395,11 @@ mono_runtime_class_init_full (MonoVTable *vtable, gboolean raise_exception)
                        if (last_domain)
                                mono_domain_set (last_domain, TRUE);
                        lock->done = TRUE;
-                       mono_mutex_unlock (&lock->initialization_section);
+                       mono_type_init_unlock (lock);
                } else {
                        /* this just blocks until the initializing thread is done */
-                       mono_mutex_lock (&lock->initialization_section);
-                       mono_mutex_unlock (&lock->initialization_section);
+                       mono_type_init_lock (lock);
+                       mono_type_init_unlock (lock);
                }
 
                mono_type_initialization_lock ();
@@ -460,7 +443,7 @@ gboolean release_type_locks (gpointer key, gpointer value, gpointer user)
                 * and get_type_init_exception_for_class () needs to be aware of this.
                 */
                vtable->init_failed = 1;
-               mono_mutex_unlock (&lock->initialization_section);
+               mono_type_init_unlock (lock);
                --lock->waiting_count;
                if (lock->waiting_count == 0) {
                        mono_mutex_destroy (&lock->initialization_section);
@@ -515,8 +498,7 @@ default_delegate_trampoline (MonoDomain *domain, MonoClass *klass)
 static MonoTrampoline arch_create_jit_trampoline = default_trampoline;
 static MonoJumpTrampoline arch_create_jump_trampoline = default_jump_trampoline;
 static MonoDelegateTrampoline arch_create_delegate_trampoline = default_delegate_trampoline;
-static MonoImtThunkBuilder imt_thunk_builder = NULL;
-#define ARCH_USE_IMT (imt_thunk_builder != NULL)
+static MonoImtThunkBuilder imt_thunk_builder;
 #if (MONO_IMT_SIZE > 32)
 #error "MONO_IMT_SIZE cannot be larger than 32"
 #endif
@@ -945,26 +927,9 @@ mono_class_compute_gc_descriptor (MonoClass *class)
        if (!gcj_inited) {
                mono_loader_lock ();
 
-               mono_register_jit_icall (mono_object_new_ptrfree, "mono_object_new_ptrfree", mono_create_icall_signature ("object ptr"), FALSE);
-               mono_register_jit_icall (mono_object_new_ptrfree_box, "mono_object_new_ptrfree_box", mono_create_icall_signature ("object ptr"), FALSE);
                mono_register_jit_icall (mono_object_new_fast, "mono_object_new_fast", mono_create_icall_signature ("object ptr"), FALSE);
                mono_register_jit_icall (mono_string_alloc, "mono_string_alloc", mono_create_icall_signature ("object int"), FALSE);
 
-#ifdef HAVE_GC_GCJ_MALLOC
-               /* 
-                * This is not needed unless the relevant code in mono_get_allocation_ftn () is 
-                * turned on.
-                */
-#if 0
-#ifdef GC_REDIRECT_TO_LOCAL
-               mono_register_jit_icall (GC_local_gcj_malloc, "GC_local_gcj_malloc", mono_create_icall_signature ("object int ptr"), FALSE);
-               mono_register_jit_icall (GC_local_gcj_fast_malloc, "GC_local_gcj_fast_malloc", mono_create_icall_signature ("object int ptr"), FALSE);
-#endif
-               mono_register_jit_icall (GC_gcj_malloc, "GC_gcj_malloc", mono_create_icall_signature ("object int ptr"), FALSE);
-               mono_register_jit_icall (GC_gcj_fast_malloc, "GC_gcj_fast_malloc", mono_create_icall_signature ("object int ptr"), FALSE);
-#endif
-
-#endif
                gcj_inited = TRUE;
                mono_loader_unlock ();
        }
@@ -976,11 +941,11 @@ mono_class_compute_gc_descriptor (MonoClass *class)
                return;
 
        class->gc_descr_inited = TRUE;
-       class->gc_descr = GC_NO_DESCRIPTOR;
+       class->gc_descr = MONO_GC_DESCRIPTOR_NULL;
 
        bitmap = default_bitmap;
        if (class == mono_defaults.string_class) {
-               class->gc_descr = (gpointer)mono_gc_make_descr_for_string (bitmap, 2);
+               class->gc_descr = mono_gc_make_descr_for_string (bitmap, 2);
        } else if (class->rank) {
                mono_class_compute_gc_descriptor (class->element_class);
                if (MONO_TYPE_IS_REFERENCE (&class->element_class->byval_arg)) {
@@ -1002,9 +967,9 @@ mono_class_compute_gc_descriptor (MonoClass *class)
                if (count++ > 58)
                        return;*/
                bitmap = compute_class_bitmap (class, default_bitmap, sizeof (default_bitmap) * 8, 0, &max_set, FALSE);
-               class->gc_descr = (gpointer)mono_gc_make_descr_for_object (bitmap, max_set + 1, class->instance_size);
+               class->gc_descr = mono_gc_make_descr_for_object (bitmap, max_set + 1, class->instance_size);
                /*
-               if (class->gc_descr == GC_NO_DESCRIPTOR)
+               if (class->gc_descr == MONO_GC_DESCRIPTOR_NULL)
                        g_print ("disabling typed alloc (%d) for %s.%s\n", max_set, class->name_space, class->name);
                */
                /*printf ("new descriptor: %p 0x%x for %s.%s\n", class->gc_descr, bitmap [0], class->name_space, class->name);*/
@@ -1402,7 +1367,7 @@ build_imt_slots (MonoClass *klass, MonoVTable *vt, MonoDomain *domain, gpointer*
                                 * The IMT thunk might be called with an instance of one of the 
                                 * generic virtual methods, so has to fallback to the IMT trampoline.
                                 */
-                               imt [i] = initialize_imt_slot (vt, domain, imt_builder [i], callbacks.get_imt_trampoline ? callbacks.get_imt_trampoline (i) : NULL);
+                               imt [i] = initialize_imt_slot (vt, domain, imt_builder [i], callbacks.get_imt_trampoline (i));
                        } else {
                                imt [i] = initialize_imt_slot (vt, domain, imt_builder [i], NULL);
                        }
@@ -1950,16 +1915,12 @@ mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *class, gboolean
        if (class_size)
                vtable_slots++;
 
-       if (ARCH_USE_IMT) {
-               if (class->interface_offsets_count) {
-                       imt_table_bytes = sizeof (gpointer) * (MONO_IMT_SIZE);
-                       mono_stats.imt_number_of_tables++;
-                       mono_stats.imt_tables_size += imt_table_bytes;
-               } else {
-                       imt_table_bytes = 0;
-               }
+       if (class->interface_offsets_count) {
+               imt_table_bytes = sizeof (gpointer) * (MONO_IMT_SIZE);
+               mono_stats.imt_number_of_tables++;
+               mono_stats.imt_tables_size += imt_table_bytes;
        } else {
-               imt_table_bytes = sizeof (gpointer) * (class->max_interface_id + 1);
+               imt_table_bytes = 0;
        }
 
        vtable_size = imt_table_bytes + MONO_SIZEOF_VTABLE + vtable_slots * sizeof (gpointer);
@@ -1990,7 +1951,7 @@ mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *class, gboolean
                 */
 #ifdef HAVE_BOEHM_GC
        if (domain != mono_get_root_domain () && !mono_dont_free_domains)
-               vt->gc_descr = GC_NO_DESCRIPTOR;
+               vt->gc_descr = MONO_GC_DESCRIPTOR_NULL;
        else
 #endif
                vt->gc_descr = class->gc_descr;
@@ -2003,7 +1964,7 @@ mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *class, gboolean
        if (class_size) {
                /* we store the static field pointer at the end of the vtable: vt->vtable [class->vtable_size] */
                if (class->has_static_refs) {
-                       gpointer statics_gc_descr;
+                       MonoGCDescriptor statics_gc_descr;
                        int max_set = 0;
                        gsize default_bitmap [4] = {0};
                        gsize *bitmap;
@@ -2091,15 +2052,6 @@ mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *class, gboolean
        
        //printf ("Initializing VT for class %s (interface_offsets_count = %d)\n",
        //              class->name, class->interface_offsets_count);
-       
-       if (! ARCH_USE_IMT) {
-               /* initialize interface offsets */
-               for (i = 0; i < class->interface_offsets_count; ++i) {
-                       int interface_id = class->interfaces_packed [i]->interface_id;
-                       int slot = class->interface_offsets_packed [i];
-                       interface_offsets [class->max_interface_id - interface_id] = &(vt->vtable [slot]);
-               }
-       }
 
        /* Initialize vtable */
        if (callbacks.get_vtable_trampoline) {
@@ -2118,15 +2070,10 @@ mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *class, gboolean
                }
        }
 
-       if (ARCH_USE_IMT && imt_table_bytes) {
+       if (imt_table_bytes) {
                /* Now that the vtable is full, we can actually fill up the IMT */
-               if (callbacks.get_imt_trampoline) {
-                       /* lazy construction of the IMT entries enabled */
                        for (i = 0; i < MONO_IMT_SIZE; ++i)
                                interface_offsets [i] = callbacks.get_imt_trampoline (i);
-               } else {
-                       build_imt (class, vt, domain, interface_offsets, NULL);
-               }
        }
 
        /*
@@ -2201,10 +2148,6 @@ mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *class, gboolean
        mono_domain_unlock (domain);
        mono_loader_unlock ();
 
-       /* Initialization is now complete, we can throw if the InheritanceDemand aren't satisfied */
-       if (mono_security_enabled () && (class->exception_type == MONO_EXCEPTION_SECURITY_INHERITANCEDEMAND) && raise_on_error)
-               mono_raise_exception (mono_class_get_exception_for_failure (class));
-
        /* make sure the parent is initialized */
        /*FIXME shouldn't this fail the current type?*/
        if (class->parent)
@@ -2282,13 +2225,9 @@ mono_class_proxy_vtable (MonoDomain *domain, MonoRemoteClass *remote_class, Mono
                if (iclass->max_interface_id > max_interface_id) max_interface_id = iclass->max_interface_id;
        }
 
-       if (ARCH_USE_IMT) {
-               imt_table_bytes = sizeof (gpointer) * MONO_IMT_SIZE;
-               mono_stats.imt_number_of_tables++;
-               mono_stats.imt_tables_size += imt_table_bytes;
-       } else {
-               imt_table_bytes = sizeof (gpointer) * (max_interface_id + 1);
-       }
+       imt_table_bytes = sizeof (gpointer) * MONO_IMT_SIZE;
+       mono_stats.imt_number_of_tables++;
+       mono_stats.imt_tables_size += imt_table_bytes;
 
        vtsize = imt_table_bytes + MONO_SIZEOF_VTABLE + class->vtable_size * sizeof (gpointer);
 
@@ -2334,14 +2273,6 @@ mono_class_proxy_vtable (MonoDomain *domain, MonoRemoteClass *remote_class, Mono
        bitmap = mono_domain_alloc0 (domain, bsize);
 #endif
 
-       if (! ARCH_USE_IMT) {
-               /* initialize interface offsets */
-               for (i = 0; i < class->interface_offsets_count; ++i) {
-                       int interface_id = class->interfaces_packed [i]->interface_id;
-                       int slot = class->interface_offsets_packed [i];
-                       interface_offsets [class->max_interface_id - interface_id] = &(pvt->vtable [slot]);
-               }
-       }
        for (i = 0; i < class->interface_offsets_count; ++i) {
                int interface_id = class->interfaces_packed [i]->interface_id;
                bitmap [interface_id >> 3] |= (1 << (interface_id & 7));
@@ -2358,9 +2289,6 @@ mono_class_proxy_vtable (MonoDomain *domain, MonoRemoteClass *remote_class, Mono
                for (list_item = extra_interfaces; list_item != NULL; list_item=list_item->next) {
                        interf = list_item->data;
                        
-                       if (! ARCH_USE_IMT) {
-                               interface_offsets [max_interface_id - interf->interface_id] = &pvt->vtable [slot];
-                       }
                        bitmap [interf->interface_id >> 3] |= (1 << (interf->interface_id & 7));
 
                        iter = NULL;
@@ -2370,17 +2298,12 @@ mono_class_proxy_vtable (MonoDomain *domain, MonoRemoteClass *remote_class, Mono
                        
                        slot += mono_class_num_methods (interf);
                }
-               if (! ARCH_USE_IMT) {
-                       g_slist_free (extra_interfaces);
-               }
        }
 
-       if (ARCH_USE_IMT) {
-               /* Now that the vtable is full, we can actually fill up the IMT */
-               build_imt (class, pvt, domain, interface_offsets, extra_interfaces);
-               if (extra_interfaces) {
-                       g_slist_free (extra_interfaces);
-               }
+       /* Now that the vtable is full, we can actually fill up the IMT */
+       build_imt (class, pvt, domain, interface_offsets, extra_interfaces);
+       if (extra_interfaces) {
+               g_slist_free (extra_interfaces);
        }
 
 #ifdef COMPRESSED_INTERFACE_BITMAP
@@ -4373,50 +4296,6 @@ arith_overflow (void)
        mono_raise_exception (mono_get_exception_overflow ());
 }
 
-/**
- * mono_object_allocate:
- * @size: number of bytes to allocate
- *
- * This is a very simplistic routine until we have our GC-aware
- * memory allocator. 
- *
- * Returns: an allocated object of size @size, or NULL on failure.
- */
-static inline void *
-mono_object_allocate (size_t size, MonoVTable *vtable)
-{
-       MonoObject *o;
-       ALLOC_OBJECT (o, vtable, size);
-
-       return o;
-}
-
-#ifndef HAVE_SGEN_GC
-/**
- * mono_object_allocate_ptrfree:
- * @size: number of bytes to allocate
- *
- * Note that the memory allocated is not zeroed.
- * Returns: an allocated object of size @size, or NULL on failure.
- */
-static inline void *
-mono_object_allocate_ptrfree (size_t size, MonoVTable *vtable)
-{
-       MonoObject *o;
-       ALLOC_PTRFREE (o, vtable, size);
-       return o;
-}
-#endif
-
-static inline void *
-mono_object_allocate_spec (size_t size, MonoVTable *vtable)
-{
-       void *o;
-       ALLOC_TYPED (o, size, vtable);
-
-       return o;
-}
-
 /**
  * mono_object_new:
  * @klass: the class of the object that we want to create
@@ -4502,63 +4381,18 @@ mono_object_new_specific (MonoVTable *vtable)
 MonoObject *
 mono_object_new_alloc_specific (MonoVTable *vtable)
 {
-       MonoObject *o;
+       MonoObject *o = mono_gc_alloc_obj (vtable, vtable->klass->instance_size);
 
-       if (!vtable->klass->has_references) {
-               o = mono_object_new_ptrfree (vtable);
-       } else if (vtable->gc_descr != GC_NO_DESCRIPTOR) {
-               o = mono_object_allocate_spec (vtable->klass->instance_size, vtable);
-       } else {
-/*             printf("OBJECT: %s.%s.\n", vtable->klass->name_space, vtable->klass->name); */
-               o = mono_object_allocate (vtable->klass->instance_size, vtable);
-       }
        if (G_UNLIKELY (vtable->klass->has_finalize))
                mono_object_register_finalizer (o);
-       
-       if (G_UNLIKELY (profile_allocs))
-               mono_profiler_allocation (o, vtable->klass);
+
        return o;
 }
 
 MonoObject*
 mono_object_new_fast (MonoVTable *vtable)
 {
-       MonoObject *o;
-       ALLOC_TYPED (o, vtable->klass->instance_size, vtable);
-       return o;
-}
-
-static MonoObject*
-mono_object_new_ptrfree (MonoVTable *vtable)
-{
-       MonoObject *obj;
-       ALLOC_PTRFREE (obj, vtable, vtable->klass->instance_size);
-#if NEED_TO_ZERO_PTRFREE
-       /* an inline memset is much faster for the common vcase of small objects
-        * note we assume the allocated size is a multiple of sizeof (void*).
-        */
-       if (vtable->klass->instance_size < 128) {
-               gpointer *p, *end;
-               end = (gpointer*)((char*)obj + vtable->klass->instance_size);
-               p = (gpointer*)((char*)obj + sizeof (MonoObject));
-               while (p < end) {
-                       *p = NULL;
-                       ++p;
-               }
-       } else {
-               memset ((char*)obj + sizeof (MonoObject), 0, vtable->klass->instance_size - sizeof (MonoObject));
-       }
-#endif
-       return obj;
-}
-
-static MonoObject*
-mono_object_new_ptrfree_box (MonoVTable *vtable)
-{
-       MonoObject *obj;
-       ALLOC_PTRFREE (obj, vtable, vtable->klass->instance_size);
-       /* the object will be boxed right away, no need to memzero it */
-       return obj;
+       return mono_gc_alloc_obj (vtable, vtable->klass->instance_size);
 }
 
 /**
@@ -4575,20 +4409,10 @@ mono_class_get_allocation_ftn (MonoVTable *vtable, gboolean for_box, gboolean *p
 {
        *pass_size_in_words = FALSE;
 
-       if (!(mono_profiler_get_events () & MONO_PROFILE_ALLOCATIONS))
-               profile_allocs = FALSE;
-
        if (mono_class_has_finalizer (vtable->klass) || mono_class_is_marshalbyref (vtable->klass) || (mono_profiler_get_events () & MONO_PROFILE_ALLOCATIONS))
                return mono_object_new_specific;
 
-       if (!vtable->klass->has_references) {
-               //g_print ("ptrfree for %s.%s\n", vtable->klass->name_space, vtable->klass->name);
-               if (for_box)
-                       return mono_object_new_ptrfree_box;
-               return mono_object_new_ptrfree;
-       }
-
-       if (vtable->gc_descr != GC_NO_DESCRIPTOR) {
+       if (vtable->gc_descr != MONO_GC_DESCRIPTOR_NULL) {
 
                return mono_object_new_fast;
 
@@ -4645,17 +4469,10 @@ mono_object_clone (MonoObject *obj)
        if (obj->vtable->klass->rank)
                return (MonoObject*)mono_array_clone ((MonoArray*)obj);
 
-       o = mono_object_allocate (size, obj->vtable);
+       o = mono_gc_alloc_obj (obj->vtable, size);
 
-       if (obj->vtable->klass->has_references) {
-               mono_gc_wbarrier_object_copy (o, obj);
-       } else {
-               int size = obj->vtable->klass->instance_size;
-               /* do not copy the sync state */
-               mono_gc_memmove_atomic ((char*)o + sizeof (MonoObject), (char*)obj + sizeof (MonoObject), size - sizeof (MonoObject));
-       }
-       if (G_UNLIKELY (profile_allocs))
-               mono_profiler_allocation (o, obj->vtable->klass);
+       /* If the object doesn't contain references this will do a simple memmove. */
+       mono_gc_wbarrier_object_copy (o, obj);
 
        if (obj->vtable->klass->has_finalize)
                mono_object_register_finalizer (o);
@@ -4863,26 +4680,6 @@ mono_array_new_full (MonoDomain *domain, MonoClass *array_class, uintptr_t *leng
         * they need to be kept in sync.
         */
        vtable = mono_class_vtable_full (domain, array_class, TRUE);
-#ifndef HAVE_SGEN_GC
-       if (!array_class->has_references) {
-               o = mono_object_allocate_ptrfree (byte_len, vtable);
-#if NEED_TO_ZERO_PTRFREE
-               memset ((char*)o + sizeof (MonoObject), 0, byte_len - sizeof (MonoObject));
-#endif
-       } else if (vtable->gc_descr != GC_NO_DESCRIPTOR) {
-               o = mono_object_allocate_spec (byte_len, vtable);
-       }else {
-               o = mono_object_allocate (byte_len, vtable);
-       }
-
-       array = (MonoArray*)o;
-       array->max_length = len;
-
-       if (bounds_size) {
-               bounds = (MonoArrayBounds*)((char*)array + byte_len - bounds_size);
-               array->bounds = bounds;
-       }
-#else
        if (bounds_size)
                o = mono_gc_alloc_array (vtable, byte_len, len, bounds_size);
        else
@@ -4890,7 +4687,6 @@ mono_array_new_full (MonoDomain *domain, MonoClass *array_class, uintptr_t *leng
        array = (MonoArray*)o;
 
        bounds = array->bounds;
-#endif
 
        if (bounds_size) {
                for (i = 0; i < array_class->rank; ++i) {
@@ -4900,9 +4696,6 @@ mono_array_new_full (MonoDomain *domain, MonoClass *array_class, uintptr_t *leng
                }
        }
 
-       if (G_UNLIKELY (profile_allocs))
-               mono_profiler_allocation (o, array_class);
-
        return array;
 }
 
@@ -4949,29 +4742,8 @@ mono_array_new_specific (MonoVTable *vtable, uintptr_t n)
                mono_gc_out_of_memory (MONO_ARRAY_MAX_SIZE);
                return NULL;
        }
-#ifndef HAVE_SGEN_GC
-       if (!vtable->klass->has_references) {
-               o = mono_object_allocate_ptrfree (byte_len, vtable);
-#if NEED_TO_ZERO_PTRFREE
-               ((MonoArray*)o)->bounds = NULL;
-               memset ((char*)o + sizeof (MonoObject), 0, byte_len - sizeof (MonoObject));
-#endif
-       } else if (vtable->gc_descr != GC_NO_DESCRIPTOR) {
-               o = mono_object_allocate_spec (byte_len, vtable);
-       } else {
-/*             printf("ARRAY: %s.%s.\n", vtable->klass->name_space, vtable->klass->name); */
-               o = mono_object_allocate (byte_len, vtable);
-       }
-
-       ao = (MonoArray *)o;
-       ao->max_length = n;
-#else
        o = mono_gc_alloc_vector (vtable, byte_len, n);
        ao = (MonoArray*)o;
-#endif
-
-       if (G_UNLIKELY (profile_allocs))
-               mono_profiler_allocation (o, vtable->klass);
 
        return ao;
 }
@@ -5053,18 +4825,7 @@ mono_string_new_size (MonoDomain *domain, gint32 len)
        vtable = mono_class_vtable (domain, mono_defaults.string_class);
        g_assert (vtable);
 
-#ifndef HAVE_SGEN_GC
-       s = mono_object_allocate_ptrfree (size, vtable);
-
-       s->length = len;
-#else
        s = mono_gc_alloc_string (vtable, size, len);
-#endif
-#if NEED_TO_ZERO_PTRFREE
-       s->chars [len] = 0;
-#endif
-       if (G_UNLIKELY (profile_allocs))
-               mono_profiler_allocation ((MonoObject*)s, mono_defaults.string_class);
 
        return s;
 }
@@ -5183,8 +4944,6 @@ mono_value_box (MonoDomain *domain, MonoClass *class, gpointer value)
                return NULL;
        size = mono_class_instance_size (class);
        res = mono_object_new_alloc_specific (vtable);
-       if (G_UNLIKELY (profile_allocs))
-               mono_profiler_allocation (res, class);
 
        size = size - sizeof (MonoObject);
 
@@ -6023,9 +5782,49 @@ mono_async_result_new (MonoDomain *domain, HANDLE handle, MonoObject *state, gpo
        return res;
 }
 
+MonoObject *
+ves_icall_System_Runtime_Remoting_Messaging_AsyncResult_Invoke (MonoAsyncResult *ares)
+{
+       MonoAsyncCall *ac;
+       MonoObject *res;
+
+       g_assert (ares);
+       g_assert (ares->async_delegate);
+
+       ac = (MonoAsyncCall*) ares->object_data;
+       if (!ac) {
+               res = mono_runtime_delegate_invoke (ares->async_delegate, (void**) &ares->async_state, NULL);
+       } else {
+               gpointer wait_event = NULL;
+
+               ac->msg->exc = NULL;
+               res = mono_message_invoke (ares->async_delegate, ac->msg, &ac->msg->exc, &ac->out_args);
+               MONO_OBJECT_SETREF (ac, res, res);
+
+               mono_monitor_enter ((MonoObject*) ares);
+               ares->completed = 1;
+               if (ares->handle)
+                       wait_event = mono_wait_handle_get_handle ((MonoWaitHandle*) ares->handle);
+               mono_monitor_exit ((MonoObject*) ares);
+
+               if (wait_event != NULL)
+                       SetEvent (wait_event);
+
+               if (ac->cb_method) {
+                       /* we swallow the excepton as it is the behavior on .NET */
+                       MonoObject *exc = NULL;
+                       mono_runtime_invoke (ac->cb_method, ac->cb_target, (gpointer*) &ares, &exc);
+                       if (exc)
+                               mono_unhandled_exception (exc);
+               }
+       }
+
+       return res;
+}
+
 void
 mono_message_init (MonoDomain *domain,
-                  MonoMethodMessage *this, 
+                  MonoMethodMessage *this_obj
                   MonoReflectionMethod *method,
                   MonoArray *out_args)
 {
@@ -6055,20 +5854,20 @@ mono_message_init (MonoDomain *domain,
                mono_atomic_store_release (&object_array_klass, klass);
        }
 
-       MONO_OBJECT_SETREF (this, method, method);
+       MONO_OBJECT_SETREF (this_obj, method, method);
 
-       MONO_OBJECT_SETREF (this, args, mono_array_new_specific (mono_class_vtable (domain, object_array_klass), sig->param_count));
-       MONO_OBJECT_SETREF (this, arg_types, mono_array_new_specific (mono_class_vtable (domain, byte_array_klass), sig->param_count));
-       this->async_result = NULL;
-       this->call_type = CallType_Sync;
+       MONO_OBJECT_SETREF (this_obj, args, mono_array_new_specific (mono_class_vtable (domain, object_array_klass), sig->param_count));
+       MONO_OBJECT_SETREF (this_obj, arg_types, mono_array_new_specific (mono_class_vtable (domain, byte_array_klass), sig->param_count));
+       this_obj->async_result = NULL;
+       this_obj->call_type = CallType_Sync;
 
        names = g_new (char *, sig->param_count);
        mono_method_get_param_names (method->method, (const char **) names);
-       MONO_OBJECT_SETREF (this, names, mono_array_new_specific (mono_class_vtable (domain, string_array_klass), sig->param_count));
+       MONO_OBJECT_SETREF (this_obj, names, mono_array_new_specific (mono_class_vtable (domain, string_array_klass), sig->param_count));
        
        for (i = 0; i < sig->param_count; i++) {
                name = mono_string_new (domain, names [i]);
-               mono_array_setref (this->names, i, name);       
+               mono_array_setref (this_obj->names, i, name);   
        }
 
        g_free (names);
@@ -6076,7 +5875,7 @@ mono_message_init (MonoDomain *domain,
                if (sig->params [i]->byref) {
                        if (out_args) {
                                MonoObject* arg = mono_array_get (out_args, gpointer, j);
-                               mono_array_setref (this->args, i, arg);
+                               mono_array_setref (this_obj->args, i, arg);
                                j++;
                        }
                        arg_type = 2;
@@ -6087,7 +5886,7 @@ mono_message_init (MonoDomain *domain,
                        if (sig->params [i]->attrs & PARAM_ATTRIBUTE_OUT)
                                arg_type |= 4;
                }
-               mono_array_set (this->arg_types, guint8, i, arg_type);
+               mono_array_set (this_obj->arg_types, guint8, i, arg_type);
        }
 }
 
@@ -6171,8 +5970,7 @@ mono_message_invoke (MonoObject *target, MonoMethodMessage *msg,
                object_array_klass = klass;
        }
 
-       /* FIXME: GC ensure we insert a write barrier for out_args, maybe in the caller? */
-       *out_args = mono_array_new_specific (mono_class_vtable (domain, object_array_klass), outarg_count);
+       mono_gc_wbarrier_generic_store (out_args, (MonoObject*) mono_array_new_specific (mono_class_vtable (domain, object_array_klass), outarg_count));
        *exc = NULL;
 
        ret = mono_runtime_invoke_array (method, method->klass->valuetype? mono_object_unbox (target): target, msg->args, exc);
@@ -6235,6 +6033,9 @@ mono_print_unhandled_exception (MonoObject *exc)
        if (exc == (MonoObject*)mono_object_domain (exc)->out_of_memory_ex) {
                message = g_strdup ("OutOfMemoryException");
                free_message = TRUE;
+       } else if (exc == (MonoObject*)mono_object_domain (exc)->stack_overflow_ex) {
+               message = g_strdup ("StackOverflowException"); //if we OVF, we can't expect to have stack space to JIT Exception::ToString.
+               free_message = TRUE;
        } else {
                
                if (((MonoException*)exc)->native_trace_ips) {
@@ -6288,13 +6089,15 @@ mono_print_unhandled_exception (MonoObject *exc)
  * correct instantiation of the method.
  */
 void
-mono_delegate_ctor_with_method (MonoObject *this, MonoObject *target, gpointer addr, MonoMethod *method)
+mono_delegate_ctor_with_method (MonoObject *this_obj, MonoObject *target, gpointer addr, MonoMethod *method)
 {
-       MonoDelegate *delegate = (MonoDelegate *)this;
+       MonoDelegate *delegate = (MonoDelegate *)this_obj;
 
-       g_assert (this);
+       g_assert (this_obj);
        g_assert (addr);
 
+       g_assert (mono_class_has_parent (mono_object_class (this_obj), mono_defaults.multicastdelegate_class));
+
        if (method)
                delegate->method = method;
 
@@ -6325,7 +6128,7 @@ mono_delegate_ctor_with_method (MonoObject *this, MonoObject *target, gpointer a
  * This is used to initialize a delegate.
  */
 void
-mono_delegate_ctor (MonoObject *this, MonoObject *target, gpointer addr)
+mono_delegate_ctor (MonoObject *this_obj, MonoObject *target, gpointer addr)
 {
        MonoDomain *domain = mono_domain_get ();
        MonoJitInfo *ji;
@@ -6342,7 +6145,7 @@ mono_delegate_ctor (MonoObject *this, MonoObject *target, gpointer addr)
                g_assert (!method->klass->generic_container);
        }
 
-       mono_delegate_ctor_with_method (this, target, addr, method);
+       mono_delegate_ctor_with_method (this_obj, target, addr, method);
 }
 
 /**
@@ -6471,18 +6274,18 @@ mono_method_return_message_restore (MonoMethod *method, gpointer *params, MonoAr
  * Returns: an address pointing to the value of field.
  */
 gpointer
-mono_load_remote_field (MonoObject *this, MonoClass *klass, MonoClassField *field, gpointer *res)
+mono_load_remote_field (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, gpointer *res)
 {
        static MonoMethod *getter = NULL;
        MonoDomain *domain = mono_domain_get ();
-       MonoTransparentProxy *tp = (MonoTransparentProxy *) this;
+       MonoTransparentProxy *tp = (MonoTransparentProxy *) this_obj;
        MonoClass *field_class;
        MonoMethodMessage *msg;
        MonoArray *out_args;
        MonoObject *exc;
        char* full_name;
 
-       g_assert (mono_object_is_transparent_proxy (this));
+       g_assert (mono_object_is_transparent_proxy (this_obj));
        g_assert (res != NULL);
 
        if (mono_class_is_contextbound (tp->remote_class->proxy_class) && tp->rp->context == (MonoObject *) mono_context_get ()) {
@@ -6530,18 +6333,18 @@ mono_load_remote_field (MonoObject *this, MonoClass *klass, MonoClassField *fiel
  * Missing documentation.
  */
 MonoObject *
-mono_load_remote_field_new (MonoObject *this, MonoClass *klass, MonoClassField *field)
+mono_load_remote_field_new (MonoObject *this_obj, MonoClass *klass, MonoClassField *field)
 {
        static MonoMethod *getter = NULL;
        MonoDomain *domain = mono_domain_get ();
-       MonoTransparentProxy *tp = (MonoTransparentProxy *) this;
+       MonoTransparentProxy *tp = (MonoTransparentProxy *) this_obj;
        MonoClass *field_class;
        MonoMethodMessage *msg;
        MonoArray *out_args;
        MonoObject *exc, *res;
        char* full_name;
 
-       g_assert (mono_object_is_transparent_proxy (this));
+       g_assert (mono_object_is_transparent_proxy (this_obj));
 
        field_class = mono_class_from_mono_type (field->type);
 
@@ -6586,21 +6389,21 @@ mono_load_remote_field_new (MonoObject *this, MonoClass *klass, MonoClassField *
 
 /**
  * mono_store_remote_field:
- * @this: pointer to an object
+ * @this_obj: pointer to an object
  * @klass: klass of the object containing @field
  * @field: the field to load
  * @val: the value/object to store
  *
  * This method is called by the runtime on attempts to store fields of
- * transparent proxy objects. @this points to such TP, @klass is the class of
+ * transparent proxy objects. @this_obj points to such TP, @klass is the class of
  * the object containing @field. @val is the new value to store in @field.
  */
 void
-mono_store_remote_field (MonoObject *this, MonoClass *klass, MonoClassField *field, gpointer val)
+mono_store_remote_field (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, gpointer val)
 {
        static MonoMethod *setter = NULL;
        MonoDomain *domain = mono_domain_get ();
-       MonoTransparentProxy *tp = (MonoTransparentProxy *) this;
+       MonoTransparentProxy *tp = (MonoTransparentProxy *) this_obj;
        MonoClass *field_class;
        MonoMethodMessage *msg;
        MonoArray *out_args;
@@ -6608,7 +6411,7 @@ mono_store_remote_field (MonoObject *this, MonoClass *klass, MonoClassField *fie
        MonoObject *arg;
        char* full_name;
 
-       g_assert (mono_object_is_transparent_proxy (this));
+       g_assert (mono_object_is_transparent_proxy (this_obj));
 
        field_class = mono_class_from_mono_type (field->type);
 
@@ -6645,7 +6448,7 @@ mono_store_remote_field (MonoObject *this, MonoClass *klass, MonoClassField *fie
 
 /**
  * mono_store_remote_field_new:
- * @this:
+ * @this_obj:
  * @klass:
  * @field:
  * @arg:
@@ -6653,18 +6456,18 @@ mono_store_remote_field (MonoObject *this, MonoClass *klass, MonoClassField *fie
  * Missing documentation
  */
 void
-mono_store_remote_field_new (MonoObject *this, MonoClass *klass, MonoClassField *field, MonoObject *arg)
+mono_store_remote_field_new (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, MonoObject *arg)
 {
        static MonoMethod *setter = NULL;
        MonoDomain *domain = mono_domain_get ();
-       MonoTransparentProxy *tp = (MonoTransparentProxy *) this;
+       MonoTransparentProxy *tp = (MonoTransparentProxy *) this_obj;
        MonoClass *field_class;
        MonoMethodMessage *msg;
        MonoArray *out_args;
        MonoObject *exc;
        char* full_name;
 
-       g_assert (mono_object_is_transparent_proxy (this));
+       g_assert (mono_object_is_transparent_proxy (this_obj));
 
        field_class = mono_class_from_mono_type (field->type);