Skip to content

Commit 6c53ed3

Browse files
luke-gruberjacob-shops
authored andcommitted
Fix ractor move of object with generic ivars (ruby#15056)
This bug was happening only when the `id2ref` table exists. We need to replace the generic fields before replacing the object id of the newly moved object. Fixes [Bug #21664]
1 parent 7289364 commit 6c53ed3

2 files changed

Lines changed: 15 additions & 3 deletions

File tree

bootstraptest/test_ractor.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1969,6 +1969,19 @@ def ==(o)
19691969
roundtripped_obj.instance_variable_get(:@array1) == [1] ? :ok : roundtripped_obj
19701970
}
19711971

1972+
# move object with generic ivars and existing id2ref table
1973+
# [Bug #21664]
1974+
assert_equal 'ok', %q{
1975+
obj = [1]
1976+
obj.instance_variable_set("@field", :ok)
1977+
ObjectSpace._id2ref(obj.object_id) # build id2ref table
1978+
1979+
ractor = Ractor.new { Ractor.receive }
1980+
ractor.send(obj, move: true)
1981+
obj = ractor.value
1982+
obj.instance_variable_get("@field")
1983+
}
1984+
19721985
# copy object with complex generic ivars
19731986
assert_equal 'ok', %q{
19741987
# Make Array too_complex

ractor.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1973,13 +1973,12 @@ move_leave(VALUE obj, struct obj_traverse_replace_data *data)
19731973
rb_gc_writebarrier_remember(data->replacement);
19741974

19751975
void rb_replace_generic_ivar(VALUE clone, VALUE obj); // variable.c
1976-
1977-
rb_gc_obj_id_moved(data->replacement);
1978-
19791976
if (UNLIKELY(rb_obj_exivar_p(obj))) {
19801977
rb_replace_generic_ivar(data->replacement, obj);
19811978
}
19821979

1980+
rb_gc_obj_id_moved(data->replacement);
1981+
19831982
VALUE flags = T_OBJECT | FL_FREEZE | (RBASIC(obj)->flags & FL_PROMOTED);
19841983

19851984
// Avoid mutations using bind_call, etc.

0 commit comments

Comments
 (0)