diff options
Diffstat (limited to 'ractor.c')
-rw-r--r-- | ractor.c | 15 |
1 files changed, 11 insertions, 4 deletions
@@ -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); |