summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Zhu <peter@peterzhu.ca>2025-11-19 17:13:47 -0500
committerPeter Zhu <peter@peterzhu.ca>2025-11-19 15:25:29 -0800
commit83bf05427d882b9d5b9adf500abe3471eef14dd1 (patch)
treead7b932c64306b0673f943ddaf895ea8451ce483
parentfa02d7a01f5e7516de8eb3c7f92ec75c50c06e3f (diff)
Implement heap_free_slots in GC.stat_heap
[Feature #20408]
-rw-r--r--gc/default/default.c3
-rw-r--r--test/ruby/test_gc.rb4
2 files changed, 6 insertions, 1 deletions
diff --git a/gc/default/default.c b/gc/default/default.c
index 7bd9b3c74b..35ca2ec107 100644
--- a/gc/default/default.c
+++ b/gc/default/default.c
@@ -7593,6 +7593,7 @@ rb_gc_impl_stat(void *objspace_ptr, VALUE hash_or_sym)
enum gc_stat_heap_sym {
gc_stat_heap_sym_slot_size,
gc_stat_heap_sym_heap_live_slots,
+ gc_stat_heap_sym_heap_free_slots,
gc_stat_heap_sym_heap_eden_pages,
gc_stat_heap_sym_heap_eden_slots,
gc_stat_heap_sym_total_allocated_pages,
@@ -7612,6 +7613,7 @@ setup_gc_stat_heap_symbols(void)
#define S(s) gc_stat_heap_symbols[gc_stat_heap_sym_##s] = ID2SYM(rb_intern_const(#s))
S(slot_size);
S(heap_live_slots);
+ S(heap_free_slots);
S(heap_eden_pages);
S(heap_eden_slots);
S(total_allocated_pages);
@@ -7634,6 +7636,7 @@ stat_one_heap(rb_heap_t *heap, VALUE hash, VALUE key)
SET(slot_size, heap->slot_size);
SET(heap_live_slots, heap->total_allocated_objects - heap->total_freed_objects - heap->final_slots_count);
+ SET(heap_free_slots, heap->total_slots - (heap->total_allocated_objects - heap->total_freed_objects));
SET(heap_eden_pages, heap->total_pages);
SET(heap_eden_slots, heap->total_slots);
SET(total_allocated_pages, heap->total_allocated_pages);
diff --git a/test/ruby/test_gc.rb b/test/ruby/test_gc.rb
index 38e91366ad..06bacf1b1a 100644
--- a/test/ruby/test_gc.rb
+++ b/test/ruby/test_gc.rb
@@ -232,6 +232,7 @@ class TestGc < Test::Unit::TestCase
assert_equal (GC::INTERNAL_CONSTANTS[:BASE_SLOT_SIZE] + GC::INTERNAL_CONSTANTS[:RVALUE_OVERHEAD]) * (2**i), stat_heap[:slot_size]
assert_operator stat_heap[:heap_live_slots], :<=, stat[:heap_live_slots]
+ assert_operator stat_heap[:heap_free_slots], :<=, stat[:heap_free_slots]
assert_operator stat_heap[:heap_eden_pages], :<=, stat[:heap_eden_pages]
assert_operator stat_heap[:heap_eden_slots], :>=, 0
assert_operator stat_heap[:total_allocated_pages], :>=, 0
@@ -262,7 +263,7 @@ class TestGc < Test::Unit::TestCase
GC.stat_heap(i, stat_heap)
# Remove keys that can vary between invocations
- %i(total_allocated_objects heap_live_slots).each do |sym|
+ %i(total_allocated_objects heap_live_slots heap_free_slots).each do |sym|
stat_heap[sym] = stat_heap_all[i][sym] = 0
end
@@ -288,6 +289,7 @@ class TestGc < Test::Unit::TestCase
end
assert_equal stat[:heap_live_slots], stat_heap_sum[:heap_live_slots]
+ assert_equal stat[:heap_free_slots], stat_heap_sum[:heap_free_slots]
assert_equal stat[:heap_eden_pages], stat_heap_sum[:heap_eden_pages]
assert_equal stat[:heap_available_slots], stat_heap_sum[:heap_eden_slots]
assert_equal stat[:total_allocated_objects], stat_heap_sum[:total_allocated_objects]