Skip to content

Commit 365317f

Browse files
committed
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)
1 parent 12b0ce3 commit 365317f

2 files changed

Lines changed: 55 additions & 1 deletion

File tree

bootstraptest/test_ractor.rb

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1923,6 +1923,60 @@ def ==(o)
19231923
roundtripped_obj.instance_variable_get(:@array) == [1] ? :ok : roundtripped_obj
19241924
}
19251925

1926+
# move object with many generic ivars
1927+
assert_equal 'ok', %q{
1928+
ractor = Ractor.new { Ractor.receive }
1929+
obj = Array.new(10, 42)
1930+
0.upto(300) do |i|
1931+
obj.instance_variable_set(:"@array#{i}", [i])
1932+
end
1933+
1934+
ractor.send(obj, move: true)
1935+
roundtripped_obj = ractor.value
1936+
roundtripped_obj.instance_variable_get(:@array1) == [1] ? :ok : roundtripped_obj
1937+
}
1938+
1939+
# move object with complex generic ivars
1940+
assert_equal 'ok', %q{
1941+
# Make Array too_complex
1942+
30.times { |i| [].instance_variable_set(:"@complex#{i}", 1) }
1943+
1944+
ractor = Ractor.new { Ractor.receive }
1945+
obj = Array.new(10, 42)
1946+
obj.instance_variable_set(:@array1, [1])
1947+
1948+
ractor.send(obj, move: true)
1949+
roundtripped_obj = ractor.value
1950+
roundtripped_obj.instance_variable_get(:@array1) == [1] ? :ok : roundtripped_obj
1951+
}
1952+
1953+
# copy object with complex generic ivars
1954+
assert_equal 'ok', %q{
1955+
# Make Array too_complex
1956+
30.times { |i| [].instance_variable_set(:"@complex#{i}", 1) }
1957+
1958+
ractor = Ractor.new { Ractor.receive }
1959+
obj = Array.new(10, 42)
1960+
obj.instance_variable_set(:@array1, [1])
1961+
1962+
ractor.send(obj)
1963+
roundtripped_obj = ractor.value
1964+
roundtripped_obj.instance_variable_get(:@array1) == [1] ? :ok : roundtripped_obj
1965+
}
1966+
1967+
# copy object with many generic ivars
1968+
assert_equal 'ok', %q{
1969+
ractor = Ractor.new { Ractor.receive }
1970+
obj = Array.new(10, 42)
1971+
0.upto(300) do |i|
1972+
obj.instance_variable_set(:"@array#{i}", [i])
1973+
end
1974+
1975+
ractor.send(obj)
1976+
roundtripped_obj = ractor.value
1977+
roundtripped_obj.instance_variable_get(:@array1) == [1] ? :ok : roundtripped_obj
1978+
}
1979+
19261980
# moved composite types move their non-shareable parts properly
19271981
assert_equal 'ok', %q{
19281982
k, v = String.new("key"), String.new("value")

ractor.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1667,7 +1667,7 @@ obj_traverse_replace_i(VALUE obj, struct obj_traverse_replace_data *data)
16671667
struct obj_traverse_replace_callback_data d = {
16681668
.stop = false,
16691669
.data = data,
1670-
.src = obj,
1670+
.src = fields_obj,
16711671
};
16721672
rb_st_foreach_with_replace(
16731673
rb_imemo_fields_complex_tbl(fields_obj),

0 commit comments

Comments
 (0)