summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornagachika <nagachika@ruby-lang.org>2023-03-21 12:23:37 +0900
committernagachika <nagachika@ruby-lang.org>2023-03-21 12:23:37 +0900
commit782a9c2ddfcc84c3bd3a1fa153f7ac1f3e92a2e1 (patch)
treef69d79f3fd503b8d387e882e184190664287d4d4
parentc660aaf439dcd609e4e23253372c8ec6d567ce10 (diff)
downloadruby-782a9c2ddfcc84c3bd3a1fa153f7ac1f3e92a2e1.tar.gz
merge revision(s) 90a80eb076429978e720e11fb17a3cbb96de3454: [Backport #19284]
Fix integer underflow when using HEAP_INIT_SLOTS There is an integer underflow when the environment variable RUBY_GC_HEAP_INIT_SLOTS is less than the number of slots currently in the Ruby heap. [Bug #19284] --- gc.c | 25 +++++++++++++------------ test/ruby/test_gc.rb | 5 +++++ 2 files changed, 18 insertions(+), 12 deletions(-)
-rw-r--r--gc.c26
-rw-r--r--test/ruby/test_gc.rb5
-rw-r--r--version.h2
3 files changed, 20 insertions, 13 deletions
diff --git a/gc.c b/gc.c
index 030a4627bd..cb33eb511b 100644
--- a/gc.c
+++ b/gc.c
@@ -10861,24 +10861,25 @@ get_envparam_double(const char *name, double *default_value, double lower_bound,
}
static void
-gc_set_initial_pages(void)
+gc_set_initial_pages(rb_objspace_t *objspace)
{
- size_t min_pages;
- rb_objspace_t *objspace = &rb_objspace;
-
gc_rest(objspace);
- min_pages = gc_params.heap_init_slots / HEAP_PAGE_OBJ_LIMIT;
-
- size_t pages_per_class = (min_pages - heap_eden_total_pages(objspace)) / SIZE_POOL_COUNT;
-
for (int i = 0; i < SIZE_POOL_COUNT; i++) {
rb_size_pool_t *size_pool = &size_pools[i];
- heap_add_pages(objspace, size_pool, SIZE_POOL_EDEN_HEAP(size_pool), pages_per_class);
+ if (gc_params.heap_init_slots > size_pool->eden_heap.total_slots) {
+ size_t slots = gc_params.heap_init_slots - size_pool->eden_heap.total_slots;
+ int multiple = size_pool->slot_size / sizeof(RVALUE);
+ size_pool->allocatable_pages = slots * multiple / HEAP_PAGE_OBJ_LIMIT;
+ }
+ else {
+ /* We already have more slots than heap_init_slots allows, so
+ * prevent creating more pages. */
+ size_pool->allocatable_pages = 0;
+ }
}
-
- heap_add_pages(objspace, &size_pools[0], SIZE_POOL_EDEN_HEAP(&size_pools[0]), min_pages - heap_eden_total_pages(objspace));
+ heap_pages_expand_sorted(objspace);
}
/*
@@ -10926,6 +10927,7 @@ gc_set_initial_pages(void)
void
ruby_gc_set_params(void)
{
+ rb_objspace_t *objspace = &rb_objspace;
/* RUBY_GC_HEAP_FREE_SLOTS */
if (get_envparam_size("RUBY_GC_HEAP_FREE_SLOTS", &gc_params.heap_free_slots, 0)) {
/* ok */
@@ -10933,7 +10935,7 @@ 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();
+ gc_set_initial_pages(objspace);
}
get_envparam_double("RUBY_GC_HEAP_GROWTH_FACTOR", &gc_params.growth_factor, 1.0, 0.0, FALSE);
diff --git a/test/ruby/test_gc.rb b/test/ruby/test_gc.rb
index baf9971c48..c28f450ef1 100644
--- a/test/ruby/test_gc.rb
+++ b/test/ruby/test_gc.rb
@@ -214,6 +214,11 @@ class TestGc < Test::Unit::TestCase
def test_gc_parameter
env = {
+ "RUBY_GC_HEAP_INIT_SLOTS" => "100"
+ }
+ assert_in_out_err([env, "-e", "exit"], "", [], [], "[Bug #19284]")
+
+ env = {
"RUBY_GC_MALLOC_LIMIT" => "60000000",
"RUBY_GC_HEAP_INIT_SLOTS" => "100000"
}
diff --git a/version.h b/version.h
index 679bfeed80..eb8cbb1d24 100644
--- a/version.h
+++ b/version.h
@@ -11,7 +11,7 @@
# define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
#define RUBY_VERSION_TEENY 4
#define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
-#define RUBY_PATCHLEVEL 197
+#define RUBY_PATCHLEVEL 198
#define RUBY_RELEASE_YEAR 2023
#define RUBY_RELEASE_MONTH 3