diff options
author | Kunshan Wang <wks1986@gmail.com> | 2022-10-27 17:47:47 +0800 |
---|---|---|
committer | Peter Zhu <peter@peterzhu.ca> | 2023-01-31 09:24:26 -0500 |
commit | de724487f0820391e005f11e67ea132cffe3c9d3 (patch) | |
tree | 99d1d6ba3cf30c49f93af16744ac2bd1fdbb8f39 | |
parent | d92289f6330c57b0fe970a654dbf33314bfd6203 (diff) | |
download | ruby-de724487f0820391e005f11e67ea132cffe3c9d3.tar.gz |
Copying GC support for EXIVAR
Instance variables held in gen_ivtbl are marked with rb_gc_mark. It
prevents the referenced objects from moving, which is bad for copying
garbage collectors.
This commit allows those instance variables to be updated during
gc_update_object_references.
-rw-r--r-- | gc.c | 6 | ||||
-rw-r--r-- | internal/variable.h | 2 | ||||
-rw-r--r-- | variable.c | 8 |
3 files changed, 10 insertions, 6 deletions
@@ -7232,7 +7232,7 @@ gc_mark_children(rb_objspace_t *objspace, VALUE obj) gc_mark_set_parent(objspace, obj); if (FL_TEST(obj, FL_EXIVAR)) { - rb_mark_generic_ivar(obj); + rb_mark_and_update_generic_ivar(obj); } switch (BUILTIN_TYPE(obj)) { @@ -10560,6 +10560,10 @@ 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); + } + switch (BUILTIN_TYPE(obj)) { case T_CLASS: case T_MODULE: diff --git a/internal/variable.h b/internal/variable.h index 3933279633..88fa28e1ba 100644 --- a/internal/variable.h +++ b/internal/variable.h @@ -42,7 +42,7 @@ int rb_obj_evacuate_ivs_to_hash_table(ID key, VALUE val, st_data_t arg); RUBY_SYMBOL_EXPORT_BEGIN /* variable.c (export) */ -void rb_mark_generic_ivar(VALUE); +void rb_mark_and_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 f1d89ab615..def22449a5 100644 --- a/variable.c +++ b/variable.c @@ -1020,22 +1020,22 @@ generic_ivar_update(st_data_t *k, st_data_t *v, st_data_t u, int existing) } static void -gen_ivtbl_mark(const struct gen_ivtbl *ivtbl) +gen_ivtbl_mark_and_update(struct gen_ivtbl *ivtbl) { uint32_t i; for (i = 0; i < ivtbl->numiv; i++) { - rb_gc_mark(ivtbl->ivptr[i]); + rb_gc_mark_and_move(&ivtbl->ivptr[i]); } } void -rb_mark_generic_ivar(VALUE obj) +rb_mark_and_update_generic_ivar(VALUE obj) { struct gen_ivtbl *ivtbl; if (rb_gen_ivtbl_get(obj, 0, &ivtbl)) { - gen_ivtbl_mark(ivtbl); + gen_ivtbl_mark_and_update(ivtbl); } } |