~ chicken-core (chicken-5) 160fb5198a9cf24c2bee79a0058034824a275abf
commit 160fb5198a9cf24c2bee79a0058034824a275abf
Author: Peter Bex <peter@more-magic.net>
AuthorDate: Sun Dec 1 15:36:36 2019 +0100
Commit: felix <felix@call-with-current-continuation.org>
CommitDate: Sun Dec 1 23:11:36 2019 +0100
Improve heap shrinkage factor.
The old calculation was confused because it took a percentage
of a percentage.
This adds a new option to set heap shrinkage watermark and uses
that as-is to decide when to change the heap size.
By default, the heap will be shrunk by 50% when the used amount
is at 25% of the heap. This looks closest to what seems to be
the intended behaviour of the code, and is also what was suggested
in #1379 by Sven Hartrumpf.
Signed-off-by: felix <felix@call-with-current-continuation.org>
diff --git a/NEWS b/NEWS
index 0890e8fd..05b4dfe9 100644
--- a/NEWS
+++ b/NEWS
@@ -30,6 +30,9 @@
an error instead of hanging forever (fixes #1586).
- define-record-type will now give an error if the constructor
definition refers to field that's not listed elsewhere (see #1633)
+ - Added new -:hu option to set the memory usage low watermark
+ percentage at which the heap should be shrunk, and changed the
+ calculation to actually reflect this (see #1379).
- Compiler
- Fixed a bug in lfa2 pass which caused "if" or "cond" nodes to be
diff --git a/manual/Using the compiler b/manual/Using the compiler
index da9f1808..9b096153 100644
--- a/manual/Using the compiler
+++ b/manual/Using the compiler
@@ -219,11 +219,13 @@ by the startup code and will not be contained in the result of
; {{-:hgPERCENTAGE}} : Sets the growth rate of the heap in percent. If the heap is exhausted, then it will grow by {{PERCENTAGE}}. The default is 200.
-; {{-:hiNUMBER}} : Specifies the initial heap size
+; {{-:hiNUMBER}} : Specifies the initial heap size (this number includes both heap semispaces, therefore only half of it is actually available to the program).
-; {{-:hmNUMBER}} : Specifies a maximal heap size. The default is (2GB - 15).
+; {{-:hmNUMBER}} : Specifies a maximal heap size (including both semispaces). The default is (2GB - 15).
-; {{-:hsPERCENTAGE}} : Sets the shrink rate of the heap in percent. If no more than a quarter of {{PERCENTAGE}} of the heap is used, then it will shrink to {{PERCENTAGE}}. The default is 50. Note: If you want to make sure that the heap never shrinks, specify a value of {{0}}. (this can be useful in situations where an optimal heap-size is known in advance).
+; {{-:hsPERCENTAGE}} : Sets the shrink rate of the heap in percent. The heap is shrunk to {{PERCENTAGE}} when the watermark is reached. The default is 50. Note: If you want to make sure that the heap never shrinks, specify a value of {{0}}. (this can be useful in situations where an optimal heap-size is known in advance).
+
+; {{-:huPERCENTAGE}} : Sets the memory usage watermark below which heap shrinking is triggered. The default is 25.
; {{-:o}} : Disables detection of stack overflows at run-time.
diff --git a/runtime.c b/runtime.c
index a3cffeb6..4a190df5 100644
--- a/runtime.c
+++ b/runtime.c
@@ -358,7 +358,8 @@ C_TLS int
C_main_argc;
C_TLS C_uword
C_heap_growth,
- C_heap_shrinkage;
+ C_heap_shrinkage,
+ C_heap_shrinkage_used;
C_TLS C_uword C_maximal_heap_size;
C_TLS time_t
C_startup_time_seconds,
@@ -782,6 +783,8 @@ int CHICKEN_initialize(int heap, int stack, int symbols, void *toplevel)
if(C_heap_shrinkage <= 0) C_heap_shrinkage = DEFAULT_HEAP_SHRINKAGE;
+ if(C_heap_shrinkage_used <= 0) C_heap_shrinkage_used = DEFAULT_HEAP_SHRINKAGE_USED;
+
if(C_maximal_heap_size <= 0) C_maximal_heap_size = DEFAULT_MAXIMAL_HEAP_SIZE;
#if !defined(NO_DLOAD2) && defined(HAVE_DLFCN_H)
@@ -1370,6 +1373,7 @@ void CHICKEN_parse_command_line(int argc, char *argv[], C_word *heap, C_word *st
" -:hmSIZE set maximal heap size\n"
" -:hgPERCENTAGE set heap growth percentage\n"
" -:hsPERCENTAGE set heap shrink percentage\n"
+ " -:huPERCENTAGE set percentage of memory used at which heap will be shrunk\n"
" -:hSIZE set fixed heap size\n"
" -:r write trace output to stderr\n"
" -:p collect statistical profile and write to file at exit\n"
@@ -1404,6 +1408,9 @@ void CHICKEN_parse_command_line(int argc, char *argv[], C_word *heap, C_word *st
case 's':
C_heap_shrinkage = arg_val(ptr + 1);
goto next;
+ case 'u':
+ C_heap_shrinkage_used = arg_val(ptr + 1);
+ goto next;
default:
*heap = arg_val(ptr);
heap_size_changed = 1;
@@ -3605,8 +3612,9 @@ C_regparm void C_fcall C_reclaim(void *trampoline, C_word c)
count = (C_uword)tospace_top - (C_uword)tospace_start;
/*** isn't gc_mode always GC_MAJOR here? */
+ /* NOTE: count is actual usage, heap_size is both halves */
if(gc_mode == GC_MAJOR &&
- count < percentage(percentage(heap_size, C_heap_shrinkage), DEFAULT_HEAP_SHRINKAGE_USED) &&
+ count < percentage(heap_size/2, C_heap_shrinkage_used) &&
heap_size > MINIMAL_HEAP_SIZE && !C_heap_size_is_fixed)
C_rereclaim2(percentage(heap_size, C_heap_shrinkage), 0);
else {
Trap