summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorJean Boussier <jean.boussier@gmail.com>2026-05-02 06:55:30 +0200
committerJean Boussier <jean.boussier@gmail.com>2026-05-02 08:46:36 +0200
commit45d586ad60ba807dbb8c5f17b0ac156095eb4fbf (patch)
treeda3403fc52f4e4d4ded5b57a6231c84d54c1941b /test
parentf2845eab29cf4e52af447a4041b5888c0e582882 (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.rb42
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;