[sgen] Parallel precleaning of los objects
authorVlad Brezae <brezaevlad@gmail.com>
Wed, 1 Jun 2016 19:32:12 +0000 (22:32 +0300)
committerVlad Brezae <brezaevlad@gmail.com>
Thu, 19 Jan 2017 22:45:10 +0000 (00:45 +0200)
In the future we should consider splitting large objects.

mono/sgen/sgen-cardtable.c
mono/sgen/sgen-gc.c
mono/sgen/sgen-gc.h
mono/sgen/sgen-los.c

index 3bb55f57da1c88dc71fb3a0a5e29b2ea7aa60012..cf89aedad4f5f7e10c46216141c0bc81ae4d8a9a 100644 (file)
@@ -442,7 +442,7 @@ sgen_card_table_scan_remsets (ScanCopyContext ctx)
        SGEN_TV_GETTIME (btv);
        last_major_scan_time = SGEN_TV_ELAPSED (atv, btv); 
        major_card_scan_time += last_major_scan_time;
-       sgen_los_scan_card_table (CARDTABLE_SCAN_GLOBAL, ctx);
+       sgen_los_scan_card_table (CARDTABLE_SCAN_GLOBAL, ctx, 0, 1);
        SGEN_TV_GETTIME (atv);
        last_los_scan_time = SGEN_TV_ELAPSED (btv, atv);
        los_card_scan_time += last_los_scan_time;
index 133e2e747c75de21569da8725c7a66e5977e5420..cfe50a1afc8af0a4ea96d158dba66258c89b9a95 100644 (file)
@@ -1405,7 +1405,7 @@ job_scan_los_mod_union_card_table (void *worker_data_untyped, SgenThreadPoolJob
        ScanCopyContext ctx = scan_copy_context_for_scan_job (worker_data_untyped, job_data);
 
        g_assert (concurrent_collection_in_progress);
-       sgen_los_scan_card_table (CARDTABLE_SCAN_MOD_UNION, ctx);
+       sgen_los_scan_card_table (CARDTABLE_SCAN_MOD_UNION, ctx, 0, 1);
 }
 
 static void
@@ -1422,12 +1422,12 @@ job_major_mod_union_preclean (void *worker_data_untyped, SgenThreadPoolJob *job)
 static void
 job_los_mod_union_preclean (void *worker_data_untyped, SgenThreadPoolJob *job)
 {
-       ScanJob *job_data = (ScanJob*)job;
-       ScanCopyContext ctx = scan_copy_context_for_scan_job (worker_data_untyped, job_data);
+       ParallelScanJob *job_data = (ParallelScanJob*)job;
+       ScanCopyContext ctx = scan_copy_context_for_scan_job (worker_data_untyped, (ScanJob*)job_data);
 
        g_assert (concurrent_collection_in_progress);
 
-       sgen_los_scan_card_table (CARDTABLE_SCAN_MOD_UNION_PRECLEAN, ctx);
+       sgen_los_scan_card_table (CARDTABLE_SCAN_MOD_UNION_PRECLEAN, ctx, job_data->job_index, sgen_workers_get_job_split_count ());
 }
 
 static void
@@ -1444,12 +1444,12 @@ job_scan_last_pinned (void *worker_data_untyped, SgenThreadPoolJob *job)
 static void
 workers_finish_callback (void)
 {
+       ParallelScanJob *psj;
        ScanJob *sj;
        int split_count = sgen_workers_get_job_split_count ();
        int i;
        /* Mod union preclean jobs */
        for (i = 0; i < split_count; i++) {
-               ParallelScanJob *psj;
                psj = (ParallelScanJob*)sgen_thread_pool_job_alloc ("preclean major mod union cardtable", job_major_mod_union_preclean, sizeof (ParallelScanJob));
                psj->scan_job.ops = sgen_workers_get_idle_func_object_ops ();
                psj->scan_job.gc_thread_gray_queue = NULL;
@@ -1457,10 +1457,13 @@ workers_finish_callback (void)
                sgen_workers_enqueue_job (&psj->scan_job.job, TRUE);
        }
 
-       sj = (ScanJob*)sgen_thread_pool_job_alloc ("preclean los mod union cardtable", job_los_mod_union_preclean, sizeof (ScanJob));
-       sj->ops = sgen_workers_get_idle_func_object_ops ();
-       sj->gc_thread_gray_queue = NULL;
-       sgen_workers_enqueue_job (&sj->job, TRUE);
+       for (i = 0; i < split_count; i++) {
+               psj = (ParallelScanJob*)sgen_thread_pool_job_alloc ("preclean los mod union cardtable", job_los_mod_union_preclean, sizeof (ParallelScanJob));
+               psj->scan_job.ops = sgen_workers_get_idle_func_object_ops ();
+               psj->scan_job.gc_thread_gray_queue = NULL;
+               psj->job_index = i;
+               sgen_workers_enqueue_job (&psj->scan_job.job, TRUE);
+       }
 
        sj = (ScanJob*)sgen_thread_pool_job_alloc ("scan last pinned", job_scan_last_pinned, sizeof (ScanJob));
        sj->ops = sgen_workers_get_idle_func_object_ops ();
index 89afb69e06986882dc51886af2f2f3eb28ce3a53..08f1fece1cf003c68d4368f7bcee2372d089dd55 100644 (file)
@@ -866,7 +866,7 @@ void sgen_los_sweep (void);
 gboolean sgen_ptr_is_in_los (char *ptr, char **start);
 void sgen_los_iterate_objects (IterateObjectCallbackFunc cb, void *user_data);
 void sgen_los_iterate_live_block_ranges (sgen_cardtable_block_callback callback);
-void sgen_los_scan_card_table (CardTableScanType scan_type, ScanCopyContext ctx);
+void sgen_los_scan_card_table (CardTableScanType scan_type, ScanCopyContext ctx, int job_index, int job_split_count);
 void sgen_los_update_cardtable_mod_union (void);
 void sgen_los_count_cards (long long *num_total_cards, long long *num_marked_cards);
 gboolean sgen_los_is_valid_object (char *object);
index b1205cdcf0cd90935f6588395b11b165bf9dee0e..68f5b933f12eed386fb751e1de38a274f69c15bf 100644 (file)
@@ -624,15 +624,19 @@ get_cardtable_mod_union_for_object (LOSObject *obj)
 }
 
 void
-sgen_los_scan_card_table (CardTableScanType scan_type, ScanCopyContext ctx)
+sgen_los_scan_card_table (CardTableScanType scan_type, ScanCopyContext ctx, int job_index, int job_split_count)
 {
        LOSObject *obj;
+       int i = 0;
 
        binary_protocol_los_card_table_scan_start (sgen_timestamp (), scan_type & CARDTABLE_SCAN_MOD_UNION);
-       for (obj = los_object_list; obj; obj = obj->next) {
+       for (obj = los_object_list; obj; obj = obj->next, i++) {
                mword num_cards = 0;
                guint8 *cards;
 
+               if (i % job_split_count != job_index)
+                       continue;
+
                if (!SGEN_OBJECT_HAS_REFERENCES (obj->data))
                        continue;