]> granicus.if.org Git - gc/commitdiff
Make heap growth more conservative after GC_gcollect_and_unmap call
authorIvan Maidanski <ivmai@mail.ru>
Tue, 17 Dec 2013 06:02:05 +0000 (10:02 +0400)
committerIvan Maidanski <ivmai@mail.ru>
Tue, 17 Dec 2013 13:48:03 +0000 (17:48 +0400)
(Consider heap size growth since latest GC_gcollect_and_unmap
invocation instead of absolute heap size value when computing amount
of extra memory blocks to add to heap in GC_collect_or_expand.)

* alloc.c (GC_heapsize_at_forced_unmap): New static variable.
* alloc.c (GC_gcollect_and_unmap): Store current heap size to
GC_heapsize_at_forced_unmap; add comment.
* alloc.c (GC_collect_or_expand): Change blocks_to_get computation
considering heap size growth since latest GC_heapsize_at_forced_unmap
call (instead of the absolute heap size value); do not call
GC_expand_hp_inner twice with same argument.
* include/private/gc_priv.h (_GC_arrays._heapsize): Refine comment.

alloc.c
include/private/gc_priv.h

diff --git a/alloc.c b/alloc.c
index bd3002d94ddada3f9ed37ff58992e783a8ee801c..9db21d105e24cb9636af19fb408a4907a8a14cf5 100644 (file)
--- a/alloc.c
+++ b/alloc.c
@@ -1014,8 +1014,14 @@ GC_API void GC_CALL GC_gcollect(void)
     if (GC_have_errors) GC_print_all_errors();
 }
 
+STATIC word GC_heapsize_at_forced_unmap = 0;
+
 GC_API void GC_CALL GC_gcollect_and_unmap(void)
 {
+    /* Record current heap size to make heap growth more conservative   */
+    /* afterwards (as if the heap is growing from zero size again).     */
+    GC_heapsize_at_forced_unmap = GC_heapsize;
+    /* Collect and force memory unmapping to OS. */
     (void)GC_try_to_collect_general(GC_never_stop_func, TRUE);
 }
 
@@ -1269,8 +1275,9 @@ GC_INNER GC_bool GC_collect_or_expand(word needed_blocks,
       }
     }
 
-    blocks_to_get = GC_heapsize/(HBLKSIZE*GC_free_space_divisor)
-                        + needed_blocks;
+    blocks_to_get = (GC_heapsize - GC_heapsize_at_forced_unmap)
+                        / (HBLKSIZE * GC_free_space_divisor)
+                    + needed_blocks;
     if (blocks_to_get > MAXHINCR) {
       word slop;
 
@@ -1291,7 +1298,8 @@ GC_INNER GC_bool GC_collect_or_expand(word needed_blocks,
     }
 
     if (!GC_expand_hp_inner(blocks_to_get)
-        && !GC_expand_hp_inner(needed_blocks)) {
+        && (blocks_to_get == needed_blocks \
+            || !GC_expand_hp_inner(needed_blocks))) {
       if (gc_not_stopped == FALSE) {
         /* Don't increment GC_fail_count here (and no warning).     */
         GC_gcollect_inner();
index f80cd94ed733b85e859f5d14bfc5b1c7987eca91..54309a962e5bacc7debfae05729cd34737d2fe60 100644 (file)
@@ -1090,7 +1090,7 @@ typedef struct GC_ms_entry {
 /* compiled.                                    */
 
 struct _GC_arrays {
-  word _heapsize;               /* Heap size in bytes.                  */
+  word _heapsize;       /* Heap size in bytes (value never goes down).  */
   word _requested_heapsize;     /* Heap size due to explicit expansion. */
   ptr_t _last_heap_addr;
   ptr_t _prev_heap_addr;