wingo pushed a commit to branch wip-whippet
in repository guile.

commit b2f4083f913d8b155cafe0cdc986b34dbf96fb05
Author: Andy Wingo <wi...@igalia.com>
AuthorDate: Thu Aug 7 11:40:17 2025 +0200

    Change growable heap sizer to use sqrt sizing
    
    Instead of heap-size-multiplier, it's heap-double-threshold: the heap
    size at which there is a 2x multiplier of live data.
---
 api/gc-options.h          |  2 +-
 src/gc-options-internal.h |  2 +-
 src/gc-options.c          |  4 ++--
 src/growable-heap-sizer.h | 27 +++++++++++++++------------
 src/heap-sizer.h          |  2 +-
 5 files changed, 20 insertions(+), 17 deletions(-)

diff --git a/api/gc-options.h b/api/gc-options.h
index 2f3f7f792..609b350bd 100644
--- a/api/gc-options.h
+++ b/api/gc-options.h
@@ -13,7 +13,7 @@ enum {
   GC_OPTION_HEAP_SIZE_POLICY,
   GC_OPTION_HEAP_SIZE,
   GC_OPTION_MAXIMUM_HEAP_SIZE,
-  GC_OPTION_HEAP_SIZE_MULTIPLIER,
+  GC_OPTION_HEAP_DOUBLE_THRESHOLD,
   GC_OPTION_HEAP_EXPANSIVENESS,
   GC_OPTION_PARALLELISM
 };
diff --git a/src/gc-options-internal.h b/src/gc-options-internal.h
index 9e9fbca22..ac0d7e704 100644
--- a/src/gc-options-internal.h
+++ b/src/gc-options-internal.h
@@ -11,7 +11,7 @@ struct gc_common_options {
   enum gc_heap_size_policy heap_size_policy;
   size_t heap_size;
   size_t maximum_heap_size;
-  double heap_size_multiplier;
+  double heap_double_threshold;
   double heap_expansiveness;
   int parallelism;
 };
diff --git a/src/gc-options.c b/src/gc-options.c
index 31de02745..07d8fdd37 100644
--- a/src/gc-options.c
+++ b/src/gc-options.c
@@ -19,12 +19,12 @@
 #define FOR_EACH_SIZE_GC_OPTION(M)                                      \
   M(HEAP_SIZE, heap_size, "heap-size",                                  \
     size, size, 6 * 1024 * 1024, 0, -1)                                 \
+  M(HEAP_DOUBLE_THRESHOLD, heap_double_threshold, "heap-double-threshold", \
+    size, size, 60 * 1024 * 1024, 1, -1)                                \
   M(MAXIMUM_HEAP_SIZE, maximum_heap_size, "maximum-heap-size",          \
     size, size, 0, 0, -1)
 
 #define FOR_EACH_DOUBLE_GC_OPTION(M)                                    \
-  M(HEAP_SIZE_MULTIPLIER, heap_size_multiplier, "heap-size-multiplier", \
-    double, double, 1.75, 1.0, 1e6)                                     \
   M(HEAP_EXPANSIVENESS, heap_expansiveness, "heap-expansiveness",       \
     double, double, 1.0, 0.0, 50.0)
 
diff --git a/src/growable-heap-sizer.h b/src/growable-heap-sizer.h
index 1ac761660..90f7ba632 100644
--- a/src/growable-heap-sizer.h
+++ b/src/growable-heap-sizer.h
@@ -1,6 +1,7 @@
 #ifndef GROWABLE_HEAP_SIZER_H
 #define GROWABLE_HEAP_SIZER_H
 
+#include <math.h>
 #include <pthread.h>
 #include <stdlib.h>
 #include <string.h>
@@ -9,29 +10,30 @@
 #include "heap-sizer.h"
 
 // This is a simple heap-sizing algorithm that will grow the heap if it is
-// smaller than a given multiplier of the live data size.  It does not shrink
-// the heap.
+// smaller than a multiplier of the live data size, where the multiplier 
depends
+// on the square root of the live data size.  It does not shrink the heap.
 
 struct gc_growable_heap_sizer {
   struct gc_heap *heap;
-  double multiplier;
+  double sqrt_multiplier;
   pthread_mutex_t lock;
 };
 
 static void
-gc_growable_heap_sizer_set_multiplier(struct gc_growable_heap_sizer *sizer,
-                                      double multiplier) {
+gc_growable_heap_sizer_set_double_threshold(struct gc_growable_heap_sizer 
*sizer,
+                                            size_t threshold) {
   pthread_mutex_lock(&sizer->lock);
-  sizer->multiplier = multiplier;
+  GC_ASSERT(threshold);
+  sizer->sqrt_multiplier = sqrt(threshold / 2);
   pthread_mutex_unlock(&sizer->lock);
 }
 
 static size_t
 gc_growable_heap_sizer_target_size(struct gc_growable_heap_sizer *sizer,
                                    size_t heap_size, size_t live_bytes) {
-  pthread_mutex_lock(&sizer->lock);
-  size_t target_size = live_bytes * sizer->multiplier;
-  pthread_mutex_unlock(&sizer->lock);
+  size_t target_size = live_bytes;
+  if (live_bytes)
+    target_size += sqrt(live_bytes) * sizer->sqrt_multiplier;
   return target_size;
 }
 
@@ -41,7 +43,8 @@ gc_growable_heap_sizer_on_gc(struct gc_growable_heap_sizer 
*sizer,
                              uint64_t pause_ns,
                              void (*set_heap_size)(struct gc_heap*, size_t)) {
   pthread_mutex_lock(&sizer->lock);
-  size_t target_size = live_bytes * sizer->multiplier;
+  size_t target_size =
+    gc_growable_heap_sizer_target_size(sizer, heap_size, live_bytes);
   if (target_size > heap_size) {
     fprintf(stderr, "resize (multiplier): %zu -> %zu\n", heap_size, 
target_size);
     set_heap_size(sizer->heap, target_size);
@@ -50,15 +53,15 @@ gc_growable_heap_sizer_on_gc(struct gc_growable_heap_sizer 
*sizer,
 }
 
 static struct gc_growable_heap_sizer*
-gc_make_growable_heap_sizer(struct gc_heap *heap, double multiplier) {
+gc_make_growable_heap_sizer(struct gc_heap *heap, size_t threshold) {
   struct gc_growable_heap_sizer *sizer;
   sizer = malloc(sizeof(*sizer));
   if (!sizer)
     GC_CRASH();
   memset(sizer, 0, sizeof(*sizer));
   sizer->heap = heap;
-  sizer->multiplier = multiplier;
   pthread_mutex_init(&sizer->lock, NULL);
+  gc_growable_heap_sizer_set_double_threshold(sizer, threshold);
   return sizer;
 }
 
diff --git a/src/heap-sizer.h b/src/heap-sizer.h
index 9515a51c8..194c284e7 100644
--- a/src/heap-sizer.h
+++ b/src/heap-sizer.h
@@ -28,7 +28,7 @@ gc_make_heap_sizer(struct gc_heap *heap,
 
     case GC_HEAP_SIZE_GROWABLE:
       ret.growable =
-        gc_make_growable_heap_sizer(heap, options->heap_size_multiplier);
+        gc_make_growable_heap_sizer(heap, options->heap_double_threshold);
       break;
 
     case GC_HEAP_SIZE_ADAPTIVE:

Reply via email to