diff options
| author | Peter Zhu <peter@peterzhu.ca> | 2023-03-17 10:12:37 -0400 |
|---|---|---|
| committer | Peter Zhu <peter@peterzhu.ca> | 2023-03-18 09:07:05 -0400 |
| commit | cb22d78354e201ca74eba68a8b4edefb593e6754 (patch) | |
| tree | d67779338e1182ff6c5a28432bbaabb3dcde758b /test/ruby | |
| parent | dc28ccbb6dd0921a75ed21e9d5a6c6c05a0deecf (diff) | |
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
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/7553
Diffstat (limited to 'test/ruby')
| -rw-r--r-- | test/ruby/test_gc_compact.rb | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/test/ruby/test_gc_compact.rb b/test/ruby/test_gc_compact.rb index 72d79be037..bef2ba9605 100644 --- a/test/ruby/test_gc_compact.rb +++ b/test/ruby/test_gc_compact.rb @@ -416,4 +416,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 |
