From b7d74570bfe1df47e69095b1eaf7e87a8c274026 Mon Sep 17 00:00:00 2001
From: Eric Wong <e@80x24.org>
Date: Mon, 17 Jan 2022 21:48:57 +0000
Subject: [PATCH 3/3] ruby_gc_set_params: do not set initial pages on dynamic
 update

RUBY_GC_INIT_HEAP_SLOTS is only for the initial heap and changing it via
ENV#[]= would be surprising behavior and cause unintended heap growth.
Changing gc_params.heap_init_slots via RUBY_GC_INIT_HEAP_SLOTS still
affects gc_marks_finish(), however, so assigning to
ENV["RUBY_GC_INIT_HEAP_SLOTS"] is not entirely a no-op
---
 gc.c          | 5 +++--
 hash.c        | 2 +-
 internal/gc.h | 2 +-
 ruby.c        | 2 +-
 4 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/gc.c b/gc.c
index 332581c279..14654c5ea8 100644
--- a/gc.c
+++ b/gc.c
@@ -11058,7 +11058,7 @@ gc_set_initial_pages(void)
  */
 
 void
-ruby_gc_set_params(void)
+ruby_gc_set_params(bool initial)
 {
     rb_objspace_t *objspace = &rb_objspace;
     /* RUBY_GC_HEAP_FREE_SLOTS */
@@ -11068,7 +11068,8 @@ ruby_gc_set_params(void)
 
     /* RUBY_GC_HEAP_INIT_SLOTS */
     if (get_envparam_size("RUBY_GC_HEAP_INIT_SLOTS", &gc_params.heap_init_slots, 0)) {
-	gc_set_initial_pages();
+        if (initial)
+            gc_set_initial_pages();
     }
 
     get_envparam_double("RUBY_GC_HEAP_GROWTH_FACTOR", &gc_params.growth_factor, 1.0, 0.0, FALSE);
diff --git a/hash.c b/hash.c
index d7cc797ef5..6a149247e3 100644
--- a/hash.c
+++ b/hash.c
@@ -4922,7 +4922,7 @@ reset_by_modified_env(const char *nam)
         ruby_reset_timezone();
     } else if (ENVNMATCH(nam, gc_var_pfx, sizeof(gc_var_pfx) - 1)) {
         ENV_LOCK();
-        ruby_gc_set_params();
+        ruby_gc_set_params(false);
         ENV_UNLOCK();
     }
 }
diff --git a/internal/gc.h b/internal/gc.h
index baf4f36a10..1fea5768cb 100644
--- a/internal/gc.h
+++ b/internal/gc.h
@@ -90,7 +90,7 @@ void ruby_mimfree(void *ptr);
 void rb_objspace_set_event_hook(const rb_event_flag_t event);
 VALUE rb_objspace_gc_enable(struct rb_objspace *);
 VALUE rb_objspace_gc_disable(struct rb_objspace *);
-void ruby_gc_set_params(void);
+void ruby_gc_set_params(bool);
 void rb_copy_wb_protected_attribute(VALUE dest, VALUE obj);
 #if __has_attribute(alloc_align)
 __attribute__((__alloc_align__(1)))
diff --git a/ruby.c b/ruby.c
index 747934e6d1..d85b7694f0 100644
--- a/ruby.c
+++ b/ruby.c
@@ -1886,7 +1886,7 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
     translit_char(RSTRING_PTR(opt->script_name), '\\', '/');
 #endif
 
-    ruby_gc_set_params();
+    ruby_gc_set_params(true);
     ruby_init_loadpath();
 
 #if USE_MJIT
