[sgen] Move array filling into client code.
authorMark Probst <mark.probst@gmail.com>
Mon, 15 Dec 2014 18:12:48 +0000 (10:12 -0800)
committerMark Probst <mark.probst@gmail.com>
Wed, 29 Apr 2015 17:57:44 +0000 (10:57 -0700)
mono/metadata/sgen-client.h
mono/metadata/sgen-gc.c
mono/metadata/sgen-gc.h
mono/metadata/sgen-mono.c
mono/metadata/sgen-nursery-allocator.c

index 6d822f7e26312f66ce21ee6731749112b4d985c0..1345c7df2a233153bb6f9ed2523aeeede6b1b1be 100644 (file)
 
 void sgen_client_init (void);
 
+/*
+ * Returns the vtable used for dummy objects to fill the nursery for ease and speed of
+ * walking.  Must be a valid vtable that is not used by any actual objects.  Must be
+ * idempotent.
+ */
+MonoVTable* sgen_client_get_array_fill_vtable (void);
+
+/*
+ * Fill the given range with a dummy object.  Its vtable must be the one returned by
+ * `sgen_client_get_array_fill_vtable()`.  If the range is too short to be filled with an
+ * object, null it.  Return `TRUE` if the range was filled with an object, `FALSE` if it was
+ * nulled.
+ */
+gboolean sgen_client_array_fill_range (char *start, size_t size);
+
 /*
  * Called after an object is enqueued for finalization.  This is a very low-level callback.
  * It should almost certainly be a NOP.
index 77665fd33b6ae53bc2624e11ab0a84179f309e89..5e215e698ec973ad403d48fd70932d3b9a2d95a8 100644 (file)
@@ -362,8 +362,6 @@ mono_gc_flush_info (void)
 
 SGEN_TV_DECLARE (sgen_init_timestamp);
 
-#define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1))
-
 NurseryClearPolicy nursery_clear_policy = CLEAR_AT_TLAB_CREATION;
 
 #define object_is_forwarded    SGEN_OBJECT_IS_FORWARDED
@@ -495,9 +493,6 @@ static MonoGCCallbacks gc_callbacks;
 static void *moved_objects [MOVED_OBJECTS_NUM];
 static int moved_objects_idx = 0;
 
-/* Vtable of the objects used to fill out nursery fragments before a collection */
-static MonoVTable *array_fill_vtable;
-
 #ifdef SGEN_DEBUG_INTERNAL_ALLOC
 MonoNativeThreadId main_gc_thread = NULL;
 #endif
@@ -580,6 +575,8 @@ gray_queue_enable_redirect (SgenGrayQueue *queue)
 void
 sgen_scan_area_with_callback (char *start, char *end, IterateObjectCallbackFunc callback, void *data, gboolean allow_flags)
 {
+       MonoVTable *array_fill_vtable = sgen_client_get_array_fill_vtable ();
+
        while (start < end) {
                size_t size;
                char *obj;
@@ -1775,9 +1772,9 @@ verify_nursery (void)
                if (do_dump_nursery_content) {
                        if (cur > hole_start)
                                SGEN_LOG (1, "HOLE [%p %p %d]", hole_start, cur, (int)(cur - hole_start));
-                       SGEN_LOG (1, "OBJ  [%p %p %d %d %s %d]", cur, cur + size, (int)size, (int)ss, sgen_safe_name ((MonoObject*)cur), (gpointer)LOAD_VTABLE (cur) == sgen_get_array_fill_vtable ());
+                       SGEN_LOG (1, "OBJ  [%p %p %d %d %s %d]", cur, cur + size, (int)size, (int)ss, sgen_safe_name ((MonoObject*)cur), (gpointer)LOAD_VTABLE (cur) == sgen_client_get_array_fill_vtable ());
                }
-               if (nursery_canaries_enabled () && (MonoVTable*)SGEN_LOAD_VTABLE (cur) != array_fill_vtable) {
+               if (nursery_canaries_enabled () && (MonoVTable*)SGEN_LOAD_VTABLE (cur) != sgen_client_get_array_fill_vtable ()) {
                        CHECK_CANARY_FOR_OBJECT (cur);
                        CANARIFY_SIZE (size);
                }
@@ -4518,34 +4515,6 @@ sgen_get_nursery_clear_policy (void)
        return nursery_clear_policy;
 }
 
-MonoVTable*
-sgen_get_array_fill_vtable (void)
-{
-       if (!array_fill_vtable) {
-               static MonoClass klass;
-               static char _vtable[sizeof(MonoVTable)+8];
-               MonoVTable* vtable = (MonoVTable*) ALIGN_TO(_vtable, 8);
-               gsize bmap;
-
-               MonoDomain *domain = mono_get_root_domain ();
-               g_assert (domain);
-
-               klass.element_class = mono_defaults.byte_class;
-               klass.rank = 1;
-               klass.instance_size = sizeof (MonoArray);
-               klass.sizes.element_size = 1;
-               klass.name = "array_filler_type";
-
-               vtable->klass = &klass;
-               bmap = 0;
-               vtable->gc_descr = mono_gc_make_descr_for_array (TRUE, &bmap, 0, 1);
-               vtable->rank = 1;
-
-               array_fill_vtable = vtable;
-       }
-       return array_fill_vtable;
-}
-
 void
 sgen_gc_lock (void)
 {
index e408ce447c8d08a3b6b97fdb4bc07503153b08d8..e8f1ba27fbb6624144ef8d961bedee1f5e54adb1 100644 (file)
@@ -1021,7 +1021,6 @@ void sgen_alloc_init_heavy_stats (void);
 char* sgen_nursery_alloc_get_upper_alloc_bound (void);
 void* sgen_nursery_alloc (size_t size);
 void* sgen_nursery_alloc_range (size_t size, size_t min_size, size_t *out_alloc_size);
-MonoVTable* sgen_get_array_fill_vtable (void);
 gboolean sgen_can_alloc_size (size_t size);
 void sgen_nursery_retire_region (void *address, ptrdiff_t size);
 
index c772c066988f151eb629708a9bbb5484cd445444..fa511b78dda424967d3f063d755dd2af406f2b3c 100644 (file)
@@ -115,6 +115,59 @@ mono_gc_wbarrier_object_copy (MonoObject* obj, MonoObject *src)
        sgen_get_remset ()->wbarrier_object_copy (obj, src);
 }
 
+#define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1))
+
+/* Vtable of the objects used to fill out nursery fragments before a collection */
+static MonoVTable *array_fill_vtable;
+
+MonoVTable*
+sgen_client_get_array_fill_vtable (void)
+{
+       if (!array_fill_vtable) {
+               static MonoClass klass;
+               static char _vtable[sizeof(MonoVTable)+8];
+               MonoVTable* vtable = (MonoVTable*) ALIGN_TO(_vtable, 8);
+               gsize bmap;
+
+               MonoDomain *domain = mono_get_root_domain ();
+               g_assert (domain);
+
+               klass.element_class = mono_defaults.byte_class;
+               klass.rank = 1;
+               klass.instance_size = sizeof (MonoArray);
+               klass.sizes.element_size = 1;
+               klass.name = "array_filler_type";
+
+               vtable->klass = &klass;
+               bmap = 0;
+               vtable->gc_descr = mono_gc_make_descr_for_array (TRUE, &bmap, 0, 1);
+               vtable->rank = 1;
+
+               array_fill_vtable = vtable;
+       }
+       return array_fill_vtable;
+}
+
+gboolean
+sgen_client_array_fill_range (char *start, size_t size)
+{
+       MonoArray *o;
+
+       if (size < sizeof (MonoArray)) {
+               memset (start, 0, size);
+               return FALSE;
+       }
+
+       o = (MonoArray*)start;
+       o->obj.vtable = sgen_client_get_array_fill_vtable ();
+       /* Mark this as not a real object */
+       o->obj.synchronisation = GINT_TO_POINTER (-1);
+       o->bounds = NULL;
+       o->max_length = (mono_array_size_t)(size - sizeof (MonoArray));
+
+       return TRUE;
+}
+
 static MonoGCFinalizerCallbacks fin_callbacks;
 
 guint
index aa570ad1acd55a16b9dc944bdd9bc95bdd263dd4..5bfc7a9f6ed43bd498ecff41cdeba26da98d637d 100644 (file)
@@ -71,6 +71,7 @@
 #include "metadata/sgen-bridge.h"
 #include "metadata/sgen-memory-governor.h"
 #include "metadata/sgen-pinning.h"
+#include "metadata/sgen-client.h"
 #include "metadata/mono-gc.h"
 #include "metadata/method-builder.h"
 #include "metadata/profiler-private.h"
@@ -667,25 +668,15 @@ sgen_clear_nursery_fragments (void)
 void
 sgen_clear_range (char *start, char *end)
 {
-       MonoArray *o;
        size_t size = end - start;
 
        if ((start && !end) || (start > end))
                g_error ("Invalid range [%p %p]", start, end);
 
-       if (size < sizeof (MonoArray)) {
-               memset (start, 0, size);
-               return;
+       if (sgen_client_array_fill_range (start, size)) {
+               sgen_set_nursery_scan_start (start);
+               SGEN_ASSERT (0, start + sgen_safe_object_get_size ((MonoObject*)start) == end, "Array fill produced wrong size");
        }
-
-       o = (MonoArray*)start;
-       o->obj.vtable = sgen_get_array_fill_vtable ();
-       /* Mark this as not a real object */
-       o->obj.synchronisation = GINT_TO_POINTER (-1);
-       o->bounds = NULL;
-       o->max_length = (mono_array_size_t)(size - sizeof (MonoArray));
-       sgen_set_nursery_scan_start (start);
-       g_assert (start + sgen_safe_object_get_size ((MonoObject*)o) == end);
 }
 
 void