aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorPeter Zhu <peter@peterzhu.ca>2023-12-06 07:37:57 -0500
committerPeter Zhu <peter@peterzhu.ca>2023-12-06 11:34:07 -0500
commit12e3b07455fea0e99e6aaf1893a7883fb2b0197e (patch)
treeca60535e2dc5ca4ef37b2884fc29c3dd0ade2183 /test
parentf80262b14d01a977ce386a5a377e911a90ce328d (diff)
downloadruby-12e3b07455fea0e99e6aaf1893a7883fb2b0197e.tar.gz
Re-embed when removing Object instance variables
Objects with the same shape must always have the same "embeddedness" (either embedded or heap allocated) because YJIT assumes so. However, using remove_instance_variable, it's possible that some objects are embedded and some are heap allocated because it does not re-embed heap allocated objects. This commit changes remove_instance_variable to re-embed Object instance variables when it becomes small enough.
Diffstat (limited to 'test')
-rw-r--r--test/ruby/test_object.rb35
1 files changed, 35 insertions, 0 deletions
diff --git a/test/ruby/test_object.rb b/test/ruby/test_object.rb
index 3c5b6424ba..acc913b9c0 100644
--- a/test/ruby/test_object.rb
+++ b/test/ruby/test_object.rb
@@ -355,6 +355,41 @@ class TestObject < Test::Unit::TestCase
end
end
+ def test_remove_instance_variable_re_embed
+ require "objspace"
+
+ c = Class.new do
+ def a = @a
+
+ def b = @b
+
+ def c = @c
+ end
+
+ o1 = c.new
+ o2 = c.new
+
+ o1.instance_variable_set(:@foo, 5)
+ o1.instance_variable_set(:@a, 0)
+ o1.instance_variable_set(:@b, 1)
+ o1.instance_variable_set(:@c, 2)
+ refute_includes ObjectSpace.dump(o1), '"embedded":true'
+ o1.remove_instance_variable(:@foo)
+ assert_includes ObjectSpace.dump(o1), '"embedded":true'
+
+ o2.instance_variable_set(:@a, 0)
+ o2.instance_variable_set(:@b, 1)
+ o2.instance_variable_set(:@c, 2)
+ assert_includes ObjectSpace.dump(o2), '"embedded":true'
+
+ assert_equal(0, o1.a)
+ assert_equal(1, o1.b)
+ assert_equal(2, o1.c)
+ assert_equal(0, o2.a)
+ assert_equal(1, o2.b)
+ assert_equal(2, o2.c)
+ end
+
def test_convert_string
o = Object.new
def o.to_s; 1; end