diff options
-rw-r--r-- | gc.c | 10 | ||||
-rw-r--r-- | internal/gc.h | 2 | ||||
-rw-r--r-- | internal/variable.h | 3 | ||||
-rw-r--r-- | variable.c | 23 |
4 files changed, 32 insertions, 6 deletions
@@ -7255,7 +7255,7 @@ gc_mark_children(rb_objspace_t *objspace, VALUE obj) gc_mark_set_parent(objspace, obj); if (FL_TEST(obj, FL_EXIVAR)) { - rb_mark_and_update_generic_ivar(obj); + rb_mark_generic_ivar(obj); } switch (BUILTIN_TYPE(obj)) { @@ -10249,6 +10249,12 @@ gc_ref_update_table_values_only(rb_objspace_t *objspace, st_table *tbl) } } +void +rb_gc_ref_update_table_values_only(st_table *tbl) +{ + gc_ref_update_table_values_only(&rb_objspace, tbl); +} + static void gc_update_table_refs(rb_objspace_t * objspace, st_table *tbl) { @@ -10623,7 +10629,7 @@ gc_update_object_references(rb_objspace_t *objspace, VALUE obj) gc_report(4, objspace, "update-refs: %p ->\n", (void *)obj); if (FL_TEST(obj, FL_EXIVAR)) { - rb_mark_and_update_generic_ivar(obj); + rb_ref_update_generic_ivar(obj); } switch (BUILTIN_TYPE(obj)) { diff --git a/internal/gc.h b/internal/gc.h index 188497b007..34a6043e8a 100644 --- a/internal/gc.h +++ b/internal/gc.h @@ -250,6 +250,8 @@ void rb_gc_mark_and_move(VALUE *ptr); void rb_gc_mark_weak(VALUE *ptr); void rb_gc_remove_weak(VALUE parent_obj, VALUE *ptr); +void rb_gc_ref_update_table_values_only(st_table *tbl); + #define rb_gc_mark_and_move_ptr(ptr) do { \ VALUE _obj = (VALUE)*(ptr); \ rb_gc_mark_and_move(&_obj); \ diff --git a/internal/variable.h b/internal/variable.h index 63b074a308..b2a30c7c58 100644 --- a/internal/variable.h +++ b/internal/variable.h @@ -53,7 +53,8 @@ void rb_evict_ivars_to_hash(VALUE obj); RUBY_SYMBOL_EXPORT_BEGIN /* variable.c (export) */ -void rb_mark_and_update_generic_ivar(VALUE); +void rb_mark_generic_ivar(VALUE obj); +void rb_ref_update_generic_ivar(VALUE); void rb_mv_generic_ivar(VALUE src, VALUE dst); VALUE rb_const_missing(VALUE klass, VALUE name); int rb_class_ivar_set(VALUE klass, ID vid, VALUE value); diff --git a/variable.c b/variable.c index 5eeee636bb..056572cc36 100644 --- a/variable.c +++ b/variable.c @@ -1066,17 +1066,34 @@ gen_ivtbl_resize(struct gen_ivtbl *old, uint32_t n) } void -rb_mark_and_update_generic_ivar(VALUE obj) +rb_mark_generic_ivar(VALUE obj) { struct gen_ivtbl *ivtbl; if (rb_gen_ivtbl_get(obj, 0, &ivtbl)) { if (rb_shape_obj_too_complex(obj)) { - rb_mark_tbl(ivtbl->as.complex.table); + rb_mark_tbl_no_pin(ivtbl->as.complex.table); } else { for (uint32_t i = 0; i < ivtbl->as.shape.numiv; i++) { - rb_gc_mark_and_move(&ivtbl->as.shape.ivptr[i]); + rb_gc_mark_movable(ivtbl->as.shape.ivptr[i]); + } + } + } +} + +void +rb_ref_update_generic_ivar(VALUE obj) +{ + struct gen_ivtbl *ivtbl; + + if (rb_gen_ivtbl_get(obj, 0, &ivtbl)) { + if (rb_shape_obj_too_complex(obj)) { + rb_gc_ref_update_table_values_only(ivtbl->as.complex.table); + } + else { + for (uint32_t i = 0; i < ivtbl->as.shape.numiv; i++) { + ivtbl->as.shape.ivptr[i] = rb_gc_location(ivtbl->as.shape.ivptr[i]); } } } |