From 400ccb16eefe4e21c4e3eacab4fd0f208fc5e151 Mon Sep 17 00:00:00 2001 From: "NARUSE, Yui" Date: Thu, 23 Mar 2023 08:11:23 +0900 Subject: merge revision(s) cb22d78354e201ca74eba68a8b4edefb593e6754: [Backport #19536] Fix frozen status loss when moving objects [Bug #19536] When objects are moved between size pools, their frozen status is lost in the shape. This will cause the frozen check to be bypassed when there is an inline cache. For example, the following script should raise a FrozenError, but doesn't on Ruby 3.2 and master. class A def add_ivars @a = @b = @c = @d = 1 end def set_a @a = 10 end end a = A.new a.add_ivars a.freeze b = A.new b.add_ivars b.set_a # Set the inline cache in set_a GC.verify_compaction_references(expand_heap: true, toward: :empty) a.set_a --- shape.c | 2 +- test/ruby/test_gc_compact.rb | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) --- test/ruby/test_gc_compact.rb | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'test') diff --git a/test/ruby/test_gc_compact.rb b/test/ruby/test_gc_compact.rb index 4d7bb8f7ae..d53e61d252 100644 --- a/test/ruby/test_gc_compact.rb +++ b/test/ruby/test_gc_compact.rb @@ -415,4 +415,32 @@ class TestGCCompact < Test::Unit::TestCase assert_include(ObjectSpace.dump(ary[0]), '"embedded":true') end; end + + def test_moving_objects_between_size_pools_keeps_shape_frozen_status + # [Bug #19536] + assert_separately([], "#{<<~"begin;"}\n#{<<~"end;"}") + begin; + class A + def add_ivars + @a = @b = @c = @d = 1 + end + + def set_a + @a = 10 + end + end + + a = A.new + a.add_ivars + a.freeze + + b = A.new + b.add_ivars + b.set_a # Set the inline cache in set_a + + GC.verify_compaction_references(expand_heap: true, toward: :empty) + + assert_raise(FrozenError) { a.set_a } + end; + end end -- cgit v1.2.3