]> granicus.if.org Git - gc/commitdiff
Fix min_bytes_allocd preventing potential infinite loop in GC_allocobj
authorIvan Maidanski <ivmai@mail.ru>
Tue, 11 Sep 2012 04:30:25 +0000 (08:30 +0400)
committerIvan Maidanski <ivmai@mail.ru>
Tue, 11 Sep 2012 17:54:04 +0000 (21:54 +0400)
* alloc.c (min_bytes_allocd): Do not return zero in case of big
GC_free_space_divisor value (return 1 instead to prevent infinite loop
in GC_allocobj if GC_adj_bytes_allocd returns zero); update comment.

alloc.c

diff --git a/alloc.c b/alloc.c
index 28d78e44a873436b883007ab7c6e6796bba5e1bc..aca7980d7fc6b654022f5eeeca38d4746270b202 100644 (file)
--- a/alloc.c
+++ b/alloc.c
@@ -197,9 +197,10 @@ GC_API GC_stop_func GC_CALL GC_get_stop_func(void)
 #endif
 
 /* Return the minimum number of words that must be allocated between    */
-/* collections to amortize the collection cost.                         */
+/* collections to amortize the collection cost.  Should be non-zero.    */
 static word min_bytes_allocd(void)
 {
+    word result;
 #   ifdef STACK_GROWS_UP
       word stack_size = GC_approx_sp() - GC_stackbottom;
             /* GC_stackbottom is used only for a single-threaded case.  */
@@ -228,11 +229,11 @@ static word min_bytes_allocd(void)
     total_root_size = 2 * stack_size + GC_root_size;
     scan_size = 2 * GC_composite_in_use + GC_atomic_in_use / 4
                 + total_root_size;
+    result = scan_size / GC_free_space_divisor;
     if (GC_incremental) {
-        return scan_size / (2 * GC_free_space_divisor);
-    } else {
-        return scan_size / GC_free_space_divisor;
+      result /= 2;
     }
+    return result > 0 ? result : 1;
 }
 
 STATIC word GC_non_gc_bytes_at_gc = 0;