From: Ivan Maidanski Date: Tue, 17 Dec 2013 06:02:05 +0000 (+0400) Subject: Make heap growth more conservative after GC_gcollect_and_unmap call X-Git-Tag: gc7_6_0~302 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=09304d190755782866524aa9b6d06ea83f69a023;p=gc Make heap growth more conservative after GC_gcollect_and_unmap call (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. --- diff --git a/alloc.c b/alloc.c index bd3002d9..9db21d10 100644 --- 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(); diff --git a/include/private/gc_priv.h b/include/private/gc_priv.h index f80cd94e..54309a96 100644 --- a/include/private/gc_priv.h +++ b/include/private/gc_priv.h @@ -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;