aboutsummaryrefslogtreecommitdiffstats
path: root/gc.c
diff options
context:
space:
mode:
authorPeter Zhu <peter@peterzhu.ca>2022-05-06 10:53:48 -0400
committerPeter Zhu <peter@peterzhu.ca>2022-05-09 08:45:24 -0400
commite28e9c63c64fc501751ae726e31c28b83fa08b4d (patch)
tree7e15326d402731086a6bb501659c4753649e3111 /gc.c
parentf7d480378adcb1452daf767d8cc6960f881f356b (diff)
downloadruby-e28e9c63c64fc501751ae726e31c28b83fa08b4d.tar.gz
Fix heap_extend_pages when total_slots is 0
Some size pools may not have any pages/slots, so total_slots is 0. This causes a divide-by-zero in the calculation. This commit adds a special case to catch the case when total_slots is 0 and returns the number of pages for heap_init_slots.
Diffstat (limited to 'gc.c')
-rw-r--r--gc.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/gc.c b/gc.c
index 20c13979eb..3f4903d836 100644
--- a/gc.c
+++ b/gc.c
@@ -2251,7 +2251,7 @@ heap_add_pages(rb_objspace_t *objspace, rb_size_pool_t *size_pool, rb_heap_t *he
}
static size_t
-heap_extend_pages(rb_objspace_t *objspace, size_t free_slots, size_t total_slots, size_t used)
+heap_extend_pages(rb_objspace_t *objspace, rb_size_pool_t *size_pool, size_t free_slots, size_t total_slots, size_t used)
{
double goal_ratio = gc_params.heap_free_slots_goal_ratio;
size_t next_used;
@@ -2259,6 +2259,10 @@ heap_extend_pages(rb_objspace_t *objspace, size_t free_slots, size_t total_slots
if (goal_ratio == 0.0) {
next_used = (size_t)(used * gc_params.growth_factor);
}
+ else if (total_slots == 0) {
+ int multiple = size_pool->slot_size / BASE_SLOT_SIZE;
+ next_used = (gc_params.heap_init_slots * multiple) / HEAP_PAGE_OBJ_LIMIT;
+ }
else {
/* Find `f' where free_slots = f * total_slots * goal_ratio
* => f = (total_slots - free_slots) / ((1 - goal_ratio) * total_slots)
@@ -5650,7 +5654,7 @@ gc_sweep_finish_size_pool(rb_objspace_t *objspace, rb_size_pool_t *size_pool)
}
if (grow_heap) {
- size_t extend_page_count = heap_extend_pages(objspace, swept_slots, total_slots, total_pages);
+ size_t extend_page_count = heap_extend_pages(objspace, size_pool, swept_slots, total_slots, total_pages);
if (extend_page_count > size_pool->allocatable_pages) {
size_pool_allocatable_pages_set(objspace, size_pool, extend_page_count);
@@ -8119,7 +8123,7 @@ gc_marks_finish(rb_objspace_t *objspace)
/* increment: */
gc_report(1, objspace, "gc_marks_finish: heap_set_increment!!\n");
rb_size_pool_t *size_pool = &size_pools[0];
- size_pool_allocatable_pages_set(objspace, size_pool, heap_extend_pages(objspace, sweep_slots, total_slots, heap_allocated_pages + heap_allocatable_pages(objspace)));
+ size_pool_allocatable_pages_set(objspace, size_pool, heap_extend_pages(objspace, size_pool, sweep_slots, total_slots, heap_allocated_pages + heap_allocatable_pages(objspace)));
heap_increment(objspace, size_pool, SIZE_POOL_EDEN_HEAP(size_pool));
}