Merge pull request #3809 from lateralusX/jlorenss/win-api-family-support-cleanup
[mono.git] / mono / sgen / sgen-gray.c
index 809215136f9799d817b0b157d6c1ac972f085f93..f8f04c145807db19fb27a7676f73d36f77555a05 100644 (file)
@@ -38,13 +38,17 @@ guint64 stat_gray_queue_dequeue_slow_path;
 #define STATE_ASSERT(s,v)
 #endif
 
+/*
+ * Whenever we dispose a gray queue, we save its free list.  Then, in the next collection,
+ * we reuse that free list for the new gray queue.
+ */
+static GrayQueueSection *last_gray_queue_free_list;
+
 void
 sgen_gray_object_alloc_queue_section (SgenGrayQueue *queue)
 {
        GrayQueueSection *section;
 
-       HEAVY_STAT (stat_gray_queue_section_alloc ++);
-
        if (queue->alloc_prepare_func)
                queue->alloc_prepare_func (queue);
 
@@ -54,6 +58,8 @@ sgen_gray_object_alloc_queue_section (SgenGrayQueue *queue)
                queue->free_list = section->next;
                STATE_TRANSITION (section, GRAY_QUEUE_SECTION_STATE_FREE_LIST, GRAY_QUEUE_SECTION_STATE_FLOATING);
        } else {
+               HEAVY_STAT (stat_gray_queue_section_alloc ++);
+
                /* Allocate a new section */
                section = (GrayQueueSection *)sgen_alloc_internal (INTERNAL_MEM_GRAY_QUEUE);
                STATE_SET (section, GRAY_QUEUE_SECTION_STATE_FLOATING);
@@ -212,48 +218,40 @@ sgen_gray_object_queue_trim_free_list (SgenGrayQueue *queue)
 }
 
 void
-sgen_gray_object_queue_init (SgenGrayQueue *queue, GrayQueueEnqueueCheckFunc enqueue_check_func)
+sgen_gray_object_queue_init (SgenGrayQueue *queue, GrayQueueEnqueueCheckFunc enqueue_check_func, gboolean reuse_free_list)
 {
-       g_assert (sgen_gray_object_queue_is_empty (queue));
+       memset (queue, 0, sizeof (SgenGrayQueue));
 
-       queue->alloc_prepare_func = NULL;
-       queue->alloc_prepare_data = NULL;
 #ifdef SGEN_CHECK_GRAY_OBJECT_ENQUEUE
        queue->enqueue_check_func = enqueue_check_func;
 #endif
 
-       /* Free the extra sections allocated during the last collection */
-       sgen_gray_object_queue_trim_free_list (queue);
-}
-
-static void
-invalid_prepare_func (SgenGrayQueue *queue)
-{
-       g_assert_not_reached ();
+       if (reuse_free_list) {
+               queue->free_list = last_gray_queue_free_list;
+               last_gray_queue_free_list = NULL;
+       }
 }
 
 void
-sgen_gray_object_queue_init_invalid (SgenGrayQueue *queue)
+sgen_gray_object_queue_dispose (SgenGrayQueue *queue)
 {
-       sgen_gray_object_queue_init (queue, NULL);
-       queue->alloc_prepare_func = invalid_prepare_func;
-       queue->alloc_prepare_data = NULL;
-}
+       SGEN_ASSERT (0, sgen_gray_object_queue_is_empty (queue), "Why are we disposing a gray queue that's not empty?");
 
-void
-sgen_gray_queue_set_alloc_prepare (SgenGrayQueue *queue, GrayQueueAllocPrepareFunc alloc_prepare_func, void *data)
-{
-       SGEN_ASSERT (0, !queue->alloc_prepare_func && !queue->alloc_prepare_data, "Can't set gray queue alloc-prepare twice");
-       queue->alloc_prepare_func = alloc_prepare_func;
-       queue->alloc_prepare_data = data;
+       /* Free the extra sections allocated during the last collection */
+       sgen_gray_object_queue_trim_free_list (queue);
+
+       SGEN_ASSERT (0, !last_gray_queue_free_list, "Are we disposing two gray queues after another?");
+       last_gray_queue_free_list = queue->free_list;
+
+       /* just to make sure */
+       memset (queue, 0, sizeof (SgenGrayQueue));
 }
 
 void
-sgen_gray_object_queue_init_with_alloc_prepare (SgenGrayQueue *queue, GrayQueueEnqueueCheckFunc enqueue_check_func,
-               GrayQueueAllocPrepareFunc alloc_prepare_func, void *data)
+sgen_gray_queue_set_alloc_prepare (SgenGrayQueue *queue, GrayQueueAllocPrepareFunc alloc_prepare_func)
 {
-       sgen_gray_object_queue_init (queue, enqueue_check_func);
-       sgen_gray_queue_set_alloc_prepare (queue, alloc_prepare_func, data);
+       SGEN_ASSERT (0, !queue->alloc_prepare_func, "Can't set gray queue alloc-prepare twice");
+       queue->alloc_prepare_func = alloc_prepare_func;
 }
 
 void
@@ -268,13 +266,6 @@ sgen_gray_object_queue_deinit (SgenGrayQueue *queue)
        }
 }
 
-void
-sgen_gray_object_queue_disable_alloc_prepare (SgenGrayQueue *queue)
-{
-       queue->alloc_prepare_func = NULL;
-       queue->alloc_prepare_data = NULL;
-}
-
 static void
 lock_section_queue (SgenSectionGrayQueue *queue)
 {