~ 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