Thanks to visit codestin.com
Credit goes to git.ruby-lang.org

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hawthorn <[email protected]>2025-07-04 12:10:45 -0700
committerJohn Hawthorn <[email protected]>2025-07-04 14:54:49 -0700
commit365317f6baa375a07ee11ad585d8c4ec55b46fcb (patch)
treea1cf3e48eb0c976a7956c1d0bc015a21ef889160
parent12b0ce3875806f7f6a14f3d92cedb132bb57f6b4 (diff)
Fix wrong GENIV WB on too_complex Ractor traversalHEADmaster
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)
-rw-r--r--bootstraptest/test_ractor.rb54
-rw-r--r--ractor.c2
2 files changed, 55 insertions, 1 deletions
diff --git a/bootstraptest/test_ractor.rb b/bootstraptest/test_ractor.rb
index 834c7ceebb..461c2c3954 100644
--- a/bootstraptest/test_ractor.rb
+++ b/bootstraptest/test_ractor.rb
@@ -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")
diff --git a/ractor.c b/ractor.c
index a1ce7967c8..5e4d10e8c8 100644
--- a/ractor.c
+++ b/ractor.c
@@ -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),