]> granicus.if.org Git - gc/commitdiff
Fix mark stack excessive growth during parallel mark
authorAndrew Horton <andrew.j.horton@gmail.com>
Sat, 21 Dec 2013 13:06:36 +0000 (13:06 +0000)
committerIvan Maidanski <ivmai@mail.ru>
Mon, 23 Dec 2013 13:20:51 +0000 (17:20 +0400)
(The growth observed in applications that implement things like weak
hash tables and iterate over the members marking entries using the
supplied GC_MARK_AND_PUSH macro.)

When overflow is signaled, only set GC_mark_stack_too_small if we
are using the global mark stack.  In parallel mode, local mark stack
is used, so the global mark stack is grown by GC_return_mark_stack
mainly.

* mark.c (GC_signal_mark_stack_overflow): Do not set
GC_mark_stack_too_small if GC_parallel.

mark.c

diff --git a/mark.c b/mark.c
index 60a1a1e48dfcb956236667e62b1fbc0b826e040a..6e594804513ddcb147ad3c04f7c6b1a28c25158c 100644 (file)
--- a/mark.c
+++ b/mark.c
@@ -576,7 +576,15 @@ GC_INNER void GC_invalidate_mark_state(void)
 GC_INNER mse * GC_signal_mark_stack_overflow(mse *msp)
 {
     GC_mark_state = MS_INVALID;
-    GC_mark_stack_too_small = TRUE;
+#   ifdef PARALLEL_MARK
+      /* We are using a local_mark_stack in parallel mode, so   */
+      /* do not signal the global mark stack to be resized.     */
+      /* That will be done if required in GC_return_mark_stack. */
+      if (!GC_parallel)
+        GC_mark_stack_too_small = TRUE;
+#   else
+      GC_mark_stack_too_small = TRUE;
+#   endif
     GC_COND_LOG_PRINTF("Mark stack overflow; current size = %lu entries\n",
                        (unsigned long)GC_mark_stack_size);
     return(msp - GC_MARK_STACK_DISCARDS);