[runtime] Move object allocation into GC implementations.
authorAlex Rønne Petersen <alexrp@xamarin.com>
Wed, 13 May 2015 11:25:08 +0000 (13:25 +0200)
committerAlex Rønne Petersen <alexrp@xamarin.com>
Fri, 15 May 2015 13:16:09 +0000 (15:16 +0200)
This was already done for SGen, but Boehm and the null GC still had a bunch of
code in object.c to allocate and prepare objects. This has now been moved into
mono_gc_alloc_* () functions so that all 3 GC backends have the same interface
for allocation.

mono/metadata/boehm-gc.c
mono/metadata/null-gc.c
mono/metadata/object.c

index 8f381360e8dddbf950d0baacd7f0b13d264b4f69..3030ce8ade3f342f376718d524c3886c7608df86 100644 (file)
@@ -575,6 +575,95 @@ mono_gc_free_fixed (void* addr)
 {
 }
 
+void *
+mono_gc_alloc_obj (MonoVTable *vtable, size_t size)
+{
+       MonoObject *obj;
+
+       if (!vtable->klass->has_references) {
+               obj = GC_MALLOC_ATOMIC (size);
+
+               obj->vtable = vtable;
+               obj->synchronisation = NULL;
+
+               memset ((char *) obj + sizeof (MonoObject), 0, size - sizeof (MonoObject));
+       } else if (vtable->gc_descr != GC_NO_DESCRIPTOR) {
+               obj = GC_GCJ_MALLOC (size, vtable);
+       } else {
+               obj = GC_MALLOC (size);
+
+               obj->vtable = vtable;
+       }
+
+       return obj;
+}
+
+void *
+mono_gc_alloc_vector (MonoVTable *vtable, size_t size, uintptr_t max_length)
+{
+       MonoArray *obj;
+
+       if (!vtable->klass->has_references) {
+               obj = GC_MALLOC_ATOMIC (size);
+
+               obj->obj.vtable = vtable;
+               obj->obj.synchronisation = NULL;
+
+               memset ((char *) obj + sizeof (MonoObject), 0, size - sizeof (MonoObject));
+       } else if (vtable->gc_descr != GC_NO_DESCRIPTOR) {
+               obj = GC_GCJ_MALLOC (size, vtable);
+       } else {
+               obj = GC_MALLOC (size);
+
+               obj->obj.vtable = vtable;
+       }
+
+       obj->max_length = max_length;
+
+       return obj;
+}
+
+void *
+mono_gc_alloc_array (MonoVTable *vtable, size_t size, uintptr_t max_length, uintptr_t bounds_size)
+{
+       MonoArray *obj;
+
+       if (!vtable->klass->has_references) {
+               obj = GC_MALLOC_ATOMIC (size);
+
+               obj->obj.vtable = vtable;
+               obj->obj.synchronisation = NULL;
+
+               memset ((char *) obj + sizeof (MonoObject), 0, size - sizeof (MonoObject));
+       } else if (vtable->gc_descr != GC_NO_DESCRIPTOR) {
+               obj = GC_GCJ_MALLOC (size, vtable);
+       } else {
+               obj = GC_MALLOC (size);
+
+               obj->obj.vtable = vtable;
+       }
+
+       obj->max_length = max_length;
+
+       if (bounds_size)
+               obj->bounds = (MonoArrayBounds *) ((char *) obj + size - bounds_size);
+
+       return obj;
+}
+
+void *
+mono_gc_alloc_string (MonoVTable *vtable, size_t size, gint32 len)
+{
+       MonoString *obj = GC_MALLOC_ATOMIC (size);
+
+       obj->object.vtable = vtable;
+       obj->object.synchronisation = NULL;
+       obj->length = len;
+       obj->chars [len] = 0;
+
+       return obj;
+}
+
 int
 mono_gc_invoke_finalizers (void)
 {
index b33437dc18ec0653939dcf7d0288a7d68b781724..d16c6aab36c6f00f6e7a9becb335e49e9ca7aaa9 100644 (file)
@@ -177,6 +177,53 @@ mono_gc_free_fixed (void* addr)
        g_free (addr);
 }
 
+void *
+mono_gc_alloc_obj (MonoVTable *vtable, size_t size)
+{
+       MonoObject *obj = calloc (1, size);
+
+       obj->vtable = vtable;
+
+       return obj;
+}
+
+void *
+mono_gc_alloc_vector (MonoVTable *vtable, size_t size, uintptr_t max_length)
+{
+       MonoArray *obj = calloc (1, size);
+
+       obj->obj.vtable = vtable;
+       obj->max_length = max_length;
+
+       return obj;
+}
+
+void *
+mono_gc_alloc_array (MonoVTable *vtable, size_t size, uintptr_t max_length, uintptr_t bounds_size)
+{
+       MonoArray *obj = calloc (1, size);
+
+       obj->obj.vtable = vtable;
+       obj->max_length = max_length;
+
+       if (bounds_size)
+               obj->bounds = (MonoArrayBounds *) ((char *) obj + size - bounds_size);
+
+       return obj;
+}
+
+void *
+mono_gc_alloc_string (MonoVTable *vtable, size_t size, gint32 len)
+{
+       MonoString *obj = calloc (1, size);
+
+       obj->object.vtable = vtable;
+       obj->length = len;
+       obj->chars [len] = 0;
+
+       return obj;
+}
+
 void
 mono_gc_wbarrier_set_field (MonoObject *obj, gpointer field_ptr, MonoObject* value)
 {
index 3e134550c8790d84625bc9f484bd7112dbaaeeaf..a86dd7286789a83c0e64d21204bc3d147d1b3d8e 100644 (file)
 #include "cominterop.h"
 
 #if defined(HAVE_BOEHM_GC)
-#define NEED_TO_ZERO_PTRFREE 1
 #define GC_NO_DESCRIPTOR ((gpointer)(0 | GC_DS_LENGTH))
-#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)
-#define ALLOC_TYPED(dest,size,type) do { (dest) = GC_GCJ_MALLOC ((size),(type)); } while (0)
 #elif defined(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
 
-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);
 
@@ -952,8 +938,6 @@ 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);
 
@@ -4323,50 +4307,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
@@ -4452,63 +4392,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);
 }
 
 /**
@@ -4531,13 +4426,6 @@ mono_class_get_allocation_ftn (MonoVTable *vtable, gboolean for_box, gboolean *p
        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) {
 
                return mono_object_new_fast;
@@ -4595,7 +4483,7 @@ 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 the object doesn't contain references this will do a simple memmove. */
        mono_gc_wbarrier_object_copy (o, obj);
@@ -4809,26 +4697,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
@@ -4836,7 +4704,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) {
@@ -4895,26 +4762,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);
@@ -4999,16 +4848,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);