diff options
| author | Jean Boussier <jean.boussier@gmail.com> | 2026-05-02 06:55:30 +0200 |
|---|---|---|
| committer | Jean Boussier <jean.boussier@gmail.com> | 2026-05-02 08:46:36 +0200 |
| commit | 45d586ad60ba807dbb8c5f17b0ac156095eb4fbf (patch) | |
| tree | da3403fc52f4e4d4ded5b57a6231c84d54c1941b /test | |
| parent | f2845eab29cf4e52af447a4041b5888c0e582882 (diff) | |
Never increment `max_iv_count` on Object / BasicObject.
Otherwise some code defining ivars on a naked object early during
program boot can cause all objects to be larger than needed.
This seem like it was always the intention, but wasn't quite
properly prevented.
Also stop updating `max_iv_count` during GC marking as it is
redundant.
Diffstat (limited to 'test')
| -rw-r--r-- | test/ruby/test_shapes.rb | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/test/ruby/test_shapes.rb b/test/ruby/test_shapes.rb index 67e2c543a3..b3333b1660 100644 --- a/test/ruby/test_shapes.rb +++ b/test/ruby/test_shapes.rb @@ -131,6 +131,48 @@ class TestShapes < Test::Unit::TestCase assert_operator obj["variation_count"], :<, RubyVM::Shape::SHAPE_MAX_VARIATIONS end + def test_max_iv_count + klass = Class.new + object = klass.new + + assert_equal 0, RubyVM::Shape.class_max_iv_count(klass) + 8.times do |i| + object.instance_variable_set("@ivar_#{i}", i) + end + assert_equal 8, RubyVM::Shape.class_max_iv_count(klass) + + subklass = Class.new(klass) + assert_equal 8, RubyVM::Shape.class_max_iv_count(subklass) + end + + def test_max_iv_count_on_Object + object = Object.new + + assert_equal 0, RubyVM::Shape.class_max_iv_count(Object) + 8.times do |i| + object.instance_variable_set("@ivar_#{i}", i) + end + assert_equal 0, RubyVM::Shape.class_max_iv_count(Object) + end + + def test_max_iv_count_on_BasicObject + object = BasicObject.new + + assert_equal 0, RubyVM::Shape.class_max_iv_count(BasicObject) + 8.times do |i| + Object.instance_method(:instance_variable_set).bind_call(object, "@ivar_#{i}", i) + end + assert_equal 0, RubyVM::Shape.class_max_iv_count(BasicObject) + + subklass = Class.new(BasicObject) + object = subklass.new + assert_equal 0, RubyVM::Shape.class_max_iv_count(subklass) + 8.times do |i| + Object.instance_method(:instance_variable_set).bind_call(object, "@ivar_#{i}", i) + end + assert_equal 8, RubyVM::Shape.class_max_iv_count(subklass) + end + def test_too_many_ivs_on_obj assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}") begin; |
