diff --git a/gc.c b/gc.c index 402e0acb98..bd3e8aea4d 100644 --- a/gc.c +++ b/gc.c @@ -3441,6 +3441,8 @@ vm_weak_table_gen_ivar_foreach_too_complex_i(st_data_t _key, st_data_t value, st GC_ASSERT(!iter_data->weak_only); + if (SPECIAL_CONST_P((VALUE)value)) return ST_CONTINUE; + return iter_data->callback((VALUE)value, iter_data->data); } diff --git a/test/ruby/test_gc_compact.rb b/test/ruby/test_gc_compact.rb index 4c8aa20215..2a72ecfc5f 100644 --- a/test/ruby/test_gc_compact.rb +++ b/test/ruby/test_gc_compact.rb @@ -452,4 +452,21 @@ class TestGCCompact < Test::Unit::TestCase assert_raise(FrozenError) { a.set_a } end; end + + def test_moving_too_compex_generic_ivar + omit "not compiled with SHAPE_DEBUG" unless defined?(RubyVM::Shape) + + assert_separately([], <<~RUBY) + RubyVM::Shape.exhaust_shapes + + obj = [] + obj.instance_variable_set(:@fixnum, 123) + obj.instance_variable_set(:@str, "hello") + + GC.verify_compaction_references(expand_heap: true, toward: :empty) + + assert_equal(123, obj.instance_variable_get(:@fixnum)) + assert_equal("hello", obj.instance_variable_get(:@str)) + RUBY + end end