[sgen] Check for work sharing every N (currently 32) marks.
authorMark Probst <mark.probst@gmail.com>
Fri, 11 Feb 2011 17:46:56 +0000 (18:46 +0100)
committerMark Probst <mark.probst@gmail.com>
Mon, 21 Feb 2011 14:39:19 +0000 (15:39 +0100)
mono/metadata/sgen-gc.c
mono/metadata/sgen-workers.c

index e746c8d94670988f7b71b7e6cfb54de52422ea9d..b9191c2383e41118751820d772614e2e00978cc5 100644 (file)
@@ -837,7 +837,7 @@ static void optimize_pin_queue (int start_slot);
 static void clear_remsets (void);
 static void clear_tlabs (void);
 static void sort_addresses (void **array, int size);
-static void drain_gray_stack (GrayQueue *queue);
+static gboolean drain_gray_stack (GrayQueue *queue, int max_objs);
 static void finish_gray_stack (char *start_addr, char *end_addr, int generation, GrayQueue *queue);
 static gboolean need_major_collection (mword space_needed);
 static void major_collection (const char *reason);
@@ -1698,8 +1698,8 @@ mono_sgen_add_to_global_remset (gpointer ptr)
  * frequently after each object is copied, to achieve better locality and cache
  * usage.
  */
-static void
-drain_gray_stack (GrayQueue *queue)
+static gboolean
+drain_gray_stack (GrayQueue *queue, int max_objs)
 {
        char *obj;
 
@@ -1707,21 +1707,26 @@ drain_gray_stack (GrayQueue *queue)
                for (;;) {
                        GRAY_OBJECT_DEQUEUE (queue, obj);
                        if (!obj)
-                               break;
+                               return TRUE;
                        DEBUG (9, fprintf (gc_debug_file, "Precise gray object scan %p (%s)\n", obj, safe_name (obj)));
                        major_collector.minor_scan_object (obj, queue);
                }
        } else {
+               int i;
+
                if (major_collector.is_parallel && queue == &workers_distribute_gray_queue)
-                       return;
+                       return TRUE;
 
-               for (;;) {
-                       GRAY_OBJECT_DEQUEUE (queue, obj);
-                       if (!obj)
-                               break;
-                       DEBUG (9, fprintf (gc_debug_file, "Precise gray object scan %p (%s)\n", obj, safe_name (obj)));
-                       major_collector.major_scan_object (obj, queue);
-               }
+               do {
+                       for (i = 0; i != max_objs; ++i) {
+                               GRAY_OBJECT_DEQUEUE (queue, obj);
+                               if (!obj)
+                                       return TRUE;
+                               DEBUG (9, fprintf (gc_debug_file, "Precise gray object scan %p (%s)\n", obj, safe_name (obj)));
+                               major_collector.major_scan_object (obj, queue);
+                       }
+               } while (max_objs < 0);
+               return FALSE;
        }
 }
 
@@ -2099,7 +2104,7 @@ precisely_scan_objects_from (CopyOrMarkObjectFunc copy_func, void** start_root,
                        if ((desc & 1) && *start_root) {
                                copy_func (start_root, queue);
                                DEBUG (9, fprintf (gc_debug_file, "Overwrote root at %p with %p\n", start_root, *start_root));
-                               drain_gray_stack (queue);
+                               drain_gray_stack (queue, -1);
                        }
                        desc >>= 1;
                        start_root++;
@@ -2117,7 +2122,7 @@ precisely_scan_objects_from (CopyOrMarkObjectFunc copy_func, void** start_root,
                                if ((bmap & 1) && *objptr) {
                                        copy_func (objptr, queue);
                                        DEBUG (9, fprintf (gc_debug_file, "Overwrote root at %p with %p\n", objptr, *objptr));
-                                       drain_gray_stack (queue);
+                                       drain_gray_stack (queue, -1);
                                }
                                bmap >>= 1;
                                ++objptr;
@@ -2501,7 +2506,7 @@ finish_gray_stack (char *start_addr, char *end_addr, int generation, GrayQueue *
         *   To achieve better cache locality and cache usage, we drain the gray stack 
         * frequently, after each object is copied, and just finish the work here.
         */
-       drain_gray_stack (queue);
+       drain_gray_stack (queue, -1);
        TV_GETTIME (atv);
        DEBUG (2, fprintf (gc_debug_file, "%s generation done\n", generation_name (generation)));
 
@@ -2538,7 +2543,7 @@ finish_gray_stack (char *start_addr, char *end_addr, int generation, GrayQueue *
                int done_with_ephemerons = 0;
                do {
                        done_with_ephemerons = mark_ephemerons_in_range (copy_func, start_addr, end_addr, queue);
-                       drain_gray_stack (queue);
+                       drain_gray_stack (queue, -1);
                        ++ephemeron_rounds;
                } while (!done_with_ephemerons);
 
@@ -2555,7 +2560,7 @@ finish_gray_stack (char *start_addr, char *end_addr, int generation, GrayQueue *
 
                /* drain the new stack that might have been created */
                DEBUG (6, fprintf (gc_debug_file, "Precise scan of gray area post fin\n"));
-               drain_gray_stack (queue);
+               drain_gray_stack (queue, -1);
        } while (fin_ready != num_ready_finalizers);
 
        if (mono_sgen_need_bridge_processing ())
@@ -2585,7 +2590,7 @@ finish_gray_stack (char *start_addr, char *end_addr, int generation, GrayQueue *
                        null_link_in_range (copy_func, start_addr, end_addr, GENERATION_NURSERY, FALSE, queue);
                if (gray_object_queue_is_empty (queue))
                        break;
-               drain_gray_stack (queue);
+               drain_gray_stack (queue, -1);
        }
 
        g_assert (gray_object_queue_is_empty (queue));
@@ -3066,7 +3071,7 @@ collect_nursery (size_t requested_size)
                time_minor_scan_card_table += TV_ELAPSED_MS (atv, btv);
        }
 
-       drain_gray_stack (&gray_queue);
+       drain_gray_stack (&gray_queue, -1);
 
        if (mono_profiler_get_events () & MONO_PROFILE_GC_ROOTS)
                report_registered_roots ();
index 698cc9b60a7e5dfb553b222d9ebb3cb90a047a21..5b9cad3ee4272966fea85562dd88f930599a07a0 100644 (file)
@@ -227,7 +227,8 @@ workers_thread_func (void *data_untyped)
                g_assert (got_work);
                g_assert (!gray_object_queue_is_empty (&data->private_gray_queue));
 
-               drain_gray_stack (&data->private_gray_queue);
+               while (!drain_gray_stack (&data->private_gray_queue, 32))
+                       workers_gray_queue_share_redirect (&data->private_gray_queue);
                g_assert (gray_object_queue_is_empty (&data->private_gray_queue));
 
                gray_object_queue_init (&data->private_gray_queue, &allocator);