summaryrefslogtreecommitdiff
path: root/ractor.c
diff options
context:
space:
mode:
Diffstat (limited to 'ractor.c')
-rw-r--r--ractor.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/ractor.c b/ractor.c
index cce376c543..317b24dca2 100644
--- a/ractor.c
+++ b/ractor.c
@@ -1188,6 +1188,7 @@ obj_traverse_i(VALUE obj, struct obj_traverse_data *data)
// already traversed
return 0;
}
+ RB_OBJ_WRITTEN(data->rec_hash, Qundef, obj);
struct obj_traverse_callback_data d = {
.stop = false,
@@ -1644,6 +1645,8 @@ obj_traverse_replace_i(VALUE obj, struct obj_traverse_replace_data *data)
}
else {
st_insert(obj_traverse_replace_rec(data), (st_data_t)obj, replacement);
+ RB_OBJ_WRITTEN(data->rec_hash, Qundef, obj);
+ RB_OBJ_WRITTEN(data->rec_hash, Qundef, replacement);
}
if (!data->move) {
@@ -1657,8 +1660,8 @@ obj_traverse_replace_i(VALUE obj, struct obj_traverse_replace_data *data)
} while (0)
if (UNLIKELY(rb_obj_exivar_p(obj))) {
- struct gen_fields_tbl *fields_tbl;
- rb_ivar_generic_fields_tbl_lookup(obj, &fields_tbl);
+ VALUE fields_obj;
+ rb_ivar_generic_fields_tbl_lookup(obj, &fields_obj);
if (UNLIKELY(rb_shape_obj_too_complex_p(obj))) {
struct obj_traverse_replace_callback_data d = {
@@ -1667,7 +1670,7 @@ obj_traverse_replace_i(VALUE obj, struct obj_traverse_replace_data *data)
.src = obj,
};
rb_st_foreach_with_replace(
- fields_tbl->as.complex.table,
+ rb_imemo_fields_complex_tbl(fields_obj),
obj_iv_hash_traverse_replace_foreach_i,
obj_iv_hash_traverse_replace_i,
(st_data_t)&d
@@ -1676,8 +1679,9 @@ obj_traverse_replace_i(VALUE obj, struct obj_traverse_replace_data *data)
}
else {
uint32_t fields_count = RSHAPE_LEN(RBASIC_SHAPE_ID(obj));
+ VALUE *fields = rb_imemo_fields_ptr(fields_obj);
for (uint32_t i = 0; i < fields_count; i++) {
- CHECK_AND_REPLACE(fields_tbl->as.shape.fields[i]);
+ CHECK_AND_REPLACE(fields[i]);
}
}
}
@@ -1881,6 +1885,9 @@ move_leave(VALUE obj, struct obj_traverse_replace_data *data)
rb_gc_obj_slot_size(obj) - sizeof(VALUE)
);
+ // We've copied obj's references to the replacement
+ rb_gc_writebarrier_remember(data->replacement);
+
void rb_replace_generic_ivar(VALUE clone, VALUE obj); // variable.c
rb_gc_obj_id_moved(data->replacement);