diff options
author | nagachika <nagachika@ruby-lang.org> | 2023-03-21 12:23:37 +0900 |
---|---|---|
committer | nagachika <nagachika@ruby-lang.org> | 2023-03-21 12:23:37 +0900 |
commit | 782a9c2ddfcc84c3bd3a1fa153f7ac1f3e92a2e1 (patch) | |
tree | f69d79f3fd503b8d387e882e184190664287d4d4 | |
parent | c660aaf439dcd609e4e23253372c8ec6d567ce10 (diff) | |
download | ruby-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.c | 26 | ||||
-rw-r--r-- | test/ruby/test_gc.rb | 5 | ||||
-rw-r--r-- | version.h | 2 |
3 files changed, 20 insertions, 13 deletions
@@ -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" } @@ -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 |