summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKunshan Wang <wks1986@gmail.com>2022-10-27 17:47:47 +0800
committerPeter Zhu <peter@peterzhu.ca>2023-01-31 09:24:26 -0500
commitde724487f0820391e005f11e67ea132cffe3c9d3 (patch)
tree99d1d6ba3cf30c49f93af16744ac2bd1fdbb8f39
parentd92289f6330c57b0fe970a654dbf33314bfd6203 (diff)
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.
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/7206
-rw-r--r--gc.c6
-rw-r--r--internal/variable.h2
-rw-r--r--variable.c8
3 files changed, 10 insertions, 6 deletions
diff --git a/gc.c b/gc.c
index 82590b9234..269d46daef 100644
--- a/gc.c
+++ b/gc.c
@@ -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);
}
}