Fix wrong GENIV WB on too_complex Ractor traversal

WBCHECK ERROR: Missed write barrier detected!
      Parent object: 0x7c4a5f1f66c0 (wb_protected: true)
        rb_obj_info_dump: 0x00007c4a5f1f66c0 T_IMEMO/<fields>
      Reference counts - snapshot: 2, writebarrier: 0, current: 2, missed: 1
      Missing reference to: 0x7b6a5f2f7010
        rb_obj_info_dump: 0x00007b6a5f2f7010 T_ARRAY/Array [E ] len: 1 (embed)
This commit is contained in:
John Hawthorn 2025-07-04 12:10:45 -07:00
parent 12b0ce3875
commit 365317f6ba
2 changed files with 55 additions and 1 deletions

View file

@ -1923,6 +1923,60 @@ assert_equal 'ok', %q{
roundtripped_obj.instance_variable_get(:@array) == [1] ? :ok : roundtripped_obj
}
# move object with many generic ivars
assert_equal 'ok', %q{
ractor = Ractor.new { Ractor.receive }
obj = Array.new(10, 42)
0.upto(300) do |i|
obj.instance_variable_set(:"@array#{i}", [i])
end
ractor.send(obj, move: true)
roundtripped_obj = ractor.value
roundtripped_obj.instance_variable_get(:@array1) == [1] ? :ok : roundtripped_obj
}
# move object with complex generic ivars
assert_equal 'ok', %q{
# Make Array too_complex
30.times { |i| [].instance_variable_set(:"@complex#{i}", 1) }
ractor = Ractor.new { Ractor.receive }
obj = Array.new(10, 42)
obj.instance_variable_set(:@array1, [1])
ractor.send(obj, move: true)
roundtripped_obj = ractor.value
roundtripped_obj.instance_variable_get(:@array1) == [1] ? :ok : roundtripped_obj
}
# copy object with complex generic ivars
assert_equal 'ok', %q{
# Make Array too_complex
30.times { |i| [].instance_variable_set(:"@complex#{i}", 1) }
ractor = Ractor.new { Ractor.receive }
obj = Array.new(10, 42)
obj.instance_variable_set(:@array1, [1])
ractor.send(obj)
roundtripped_obj = ractor.value
roundtripped_obj.instance_variable_get(:@array1) == [1] ? :ok : roundtripped_obj
}
# copy object with many generic ivars
assert_equal 'ok', %q{
ractor = Ractor.new { Ractor.receive }
obj = Array.new(10, 42)
0.upto(300) do |i|
obj.instance_variable_set(:"@array#{i}", [i])
end
ractor.send(obj)
roundtripped_obj = ractor.value
roundtripped_obj.instance_variable_get(:@array1) == [1] ? :ok : roundtripped_obj
}
# moved composite types move their non-shareable parts properly
assert_equal 'ok', %q{
k, v = String.new("key"), String.new("value")

View file

@ -1667,7 +1667,7 @@ obj_traverse_replace_i(VALUE obj, struct obj_traverse_replace_data *data)
struct obj_traverse_replace_callback_data d = {
.stop = false,
.data = data,
.src = obj,
.src = fields_obj,
};
rb_st_foreach_with_replace(
rb_imemo_fields_complex_tbl(fields_obj),