[sgen] Make sure workers don't have evacuating blocks on the free-lists
authorVlad Brezae <brezaevlad@gmail.com>
Thu, 2 Mar 2017 14:44:56 +0000 (16:44 +0200)
committerVlad Brezae <brezaevlad@gmail.com>
Thu, 30 Mar 2017 11:13:24 +0000 (14:13 +0300)
Double copying of an object during a collection is not allowed. If we allocate from an evacuating block this can happen.

mono/sgen/sgen-marksweep.c

index 450adcf3443a5d504f1dc843b29293ce0c1a95d3..3492ff6058ab709e4b5a04f6ced0861d0a74a7a7 100644 (file)
@@ -1555,6 +1555,25 @@ sgen_worker_clear_free_block_lists (WorkerData *worker)
        }
 }
 
+static void
+sgen_worker_clear_free_block_lists_evac (WorkerData *worker)
+{
+       int i, j;
+
+       if (!worker->free_block_lists)
+               return;
+
+       for (i = 0; i < MS_BLOCK_TYPE_MAX; i++) {
+               for (j = 0; j < num_block_obj_sizes; j++) {
+                       if (((MSBlockInfo***) worker->free_block_lists) [i][j])
+                               SGEN_ASSERT (0, !((MSBlockInfo***) worker->free_block_lists) [i][j]->next_free, "Why do we have linked free blocks on the workers");
+
+                       if (evacuate_block_obj_sizes [j])
+                               ((MSBlockInfo***) worker->free_block_lists) [i][j] = NULL;
+               }
+       }
+}
+
 static void
 sweep_start (void)
 {
@@ -2038,6 +2057,9 @@ major_start_major_collection (void)
                sgen_evacuation_freelist_blocks (&free_block_lists [MS_BLOCK_FLAG_REFS][i], i);
        }
 
+       /* We expect workers to have very few blocks on the freelist, just evacuate them */
+       sgen_workers_foreach (sgen_worker_clear_free_block_lists_evac);
+
        if (lazy_sweep && concurrent_sweep) {
                /*
                 * sweep_blocks_job is created before sweep_finish, which we wait for above