From e6974be5458907d4e809a84d775c3e6b7f4fcea9 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 29 Apr 2025 11:33:42 -0700 Subject: [PATCH] Don't call hash tombstone compaction from GC compaction Tombstone removal may possibly require allocation, and we're not allowed to allocate during GC. This commit also renames `set_compact` to `set_update_references` to differentiate tombstone removal compaction with GC object compaction. Co-Authored-By: Max Bernstein Co-authored-by: Jean Boussier --- set.c | 5 ++--- test/ruby/test_set.rb | 13 +++++++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/set.c b/set.c index 120e2c3465..221b9a07e1 100644 --- a/set.c +++ b/set.c @@ -179,10 +179,9 @@ set_replace_ref(st_data_t *key, st_data_t argp, int existing) } static void -set_compact(void *ptr) +set_update_references(void *ptr) { struct set_object *sobj = ptr; - set_compact_table(&sobj->table); set_foreach_with_replace(&sobj->table, set_foreach_replace, set_replace_ref, 0); } @@ -192,7 +191,7 @@ static const rb_data_type_t set_data_type = { .dmark = set_mark, .dfree = set_free, .dsize = set_size, - .dcompact = set_compact, + .dcompact = set_update_references, }, .flags = RUBY_TYPED_EMBEDDABLE | RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FROZEN_SHAREABLE }; diff --git a/test/ruby/test_set.rb b/test/ruby/test_set.rb index fd3ac4d9b6..5d77c502e0 100644 --- a/test/ruby/test_set.rb +++ b/test/ruby/test_set.rb @@ -864,6 +864,19 @@ class TC_Set < Test::Unit::TestCase assert_equal(klass.new([a]), set, klass.name) } end + + def test_set_gc_compact_does_not_allocate + assert_in_out_err([], <<-"end;", [], []) + def x + s = Set.new + s << Object.new + s + end + + x + GC.compact + end; + end end class TC_Enumerable < Test::Unit::TestCase