[sgen] Enqueue objects allocated during minor collections for concurrent.
authorMark Probst <mark.probst@gmail.com>
Sun, 28 Oct 2012 11:21:10 +0000 (12:21 +0100)
committerMark Probst <mark.probst@gmail.com>
Sun, 9 Dec 2012 14:02:43 +0000 (15:02 +0100)
mono/metadata/sgen-gc.c
mono/metadata/sgen-gc.h
mono/metadata/sgen-los.c
mono/metadata/sgen-marksweep.c

index 347b8ee080f9d11c4b79549f2ff5cd6b97effa25..32416bd40863da850309ce214f5c0d92f684155b 100644 (file)
@@ -575,6 +575,30 @@ sgen_workers_get_job_gray_queue (WorkerData *worker_data)
        return worker_data ? &worker_data->private_gray_queue : WORKERS_DISTRIBUTE_GRAY_QUEUE;
 }
 
+static LOCK_DECLARE (workers_distribute_gray_queue_mutex);
+
+void
+sgen_remember_major_object_for_concurrent_mark (char *obj)
+{
+       gboolean need_lock = current_collection_generation != GENERATION_NURSERY;
+
+       if (!major_collector.is_concurrent)
+               return;
+
+       g_assert (current_collection_generation == GENERATION_NURSERY || current_collection_generation == -1);
+
+       if (!concurrent_collection_in_progress)
+               return;
+
+       if (need_lock)
+               mono_mutex_lock (&workers_distribute_gray_queue_mutex);
+
+       sgen_gray_object_enqueue (sgen_workers_get_distribute_gray_queue (), obj);
+
+       if (need_lock)
+               mono_mutex_unlock (&workers_distribute_gray_queue_mutex);
+}
+
 static gboolean
 is_xdomain_ref_allowed (gpointer *ptr, char *obj, MonoDomain *domain)
 {
@@ -4743,6 +4767,9 @@ mono_gc_base_init (void)
        if (minor_collector_opt)
                g_free (minor_collector_opt);
 
+       if (major_collector.is_concurrent)
+               LOCK_INIT (workers_distribute_gray_queue_mutex);
+
        alloc_nursery ();
 
        if ((env = getenv ("MONO_GC_DEBUG"))) {
index 7062274df7aed6f30e5ac109763a9f58770620b2..447bbcce597f215233d4ad3882287fbfc3d8e732 100644 (file)
@@ -548,6 +548,8 @@ gboolean sgen_collection_is_parallel (void) MONO_INTERNAL;
 gboolean sgen_collection_is_concurrent (void) MONO_INTERNAL;
 gboolean sgen_concurrent_collection_in_progress (void) MONO_INTERNAL;
 
+void sgen_remember_major_object_for_concurrent_mark (char *obj) MONO_INTERNAL;
+
 typedef struct {
        CopyOrMarkObjectFunc copy_or_mark_object;
        ScanObjectFunc scan_object;
index 198704f942c2e4bb3cd3d82f3b1148f03c68e1aa..a138d48270157edb9bf8100f5f03f0a48917b518 100644 (file)
@@ -384,6 +384,8 @@ sgen_los_alloc_large_inner (MonoVTable *vtable, size_t size)
        los_consistency_check ();
 #endif
 
+       sgen_remember_major_object_for_concurrent_mark (obj->data);
+
        return obj->data;
 }
 
index 797a3043a7b614700ed02bf951d13ff428934aa9..c42c742bb3cb014d41c5eb98b83c01e5dd275ece 100644 (file)
@@ -764,6 +764,11 @@ alloc_obj (int size, gboolean pinned, gboolean has_references)
         */
        *(void**)obj = NULL;
 
+#ifdef SGEN_CONCURRENT_MARK
+        if (obj)
+                sgen_remember_major_object_for_concurrent_mark (obj);
+#endif
+
        return obj;
 }