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.
This commit is contained in:
parent
d92289f633
commit
de724487f0
Notes:
git
2023-01-31 14:24:46 +00:00
6
gc.c
6
gc.c
@ -7232,7 +7232,7 @@ gc_mark_children(rb_objspace_t *objspace, VALUE obj)
|
|||||||
gc_mark_set_parent(objspace, obj);
|
gc_mark_set_parent(objspace, obj);
|
||||||
|
|
||||||
if (FL_TEST(obj, FL_EXIVAR)) {
|
if (FL_TEST(obj, FL_EXIVAR)) {
|
||||||
rb_mark_generic_ivar(obj);
|
rb_mark_and_update_generic_ivar(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (BUILTIN_TYPE(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);
|
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)) {
|
switch (BUILTIN_TYPE(obj)) {
|
||||||
case T_CLASS:
|
case T_CLASS:
|
||||||
case T_MODULE:
|
case T_MODULE:
|
||||||
|
@ -42,7 +42,7 @@ int rb_obj_evacuate_ivs_to_hash_table(ID key, VALUE val, st_data_t arg);
|
|||||||
|
|
||||||
RUBY_SYMBOL_EXPORT_BEGIN
|
RUBY_SYMBOL_EXPORT_BEGIN
|
||||||
/* variable.c (export) */
|
/* 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);
|
void rb_mv_generic_ivar(VALUE src, VALUE dst);
|
||||||
VALUE rb_const_missing(VALUE klass, VALUE name);
|
VALUE rb_const_missing(VALUE klass, VALUE name);
|
||||||
int rb_class_ivar_set(VALUE klass, ID vid, VALUE value);
|
int rb_class_ivar_set(VALUE klass, ID vid, VALUE value);
|
||||||
|
@ -1020,22 +1020,22 @@ generic_ivar_update(st_data_t *k, st_data_t *v, st_data_t u, int existing)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gen_ivtbl_mark(const struct gen_ivtbl *ivtbl)
|
gen_ivtbl_mark_and_update(struct gen_ivtbl *ivtbl)
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|
||||||
for (i = 0; i < ivtbl->numiv; i++) {
|
for (i = 0; i < ivtbl->numiv; i++) {
|
||||||
rb_gc_mark(ivtbl->ivptr[i]);
|
rb_gc_mark_and_move(&ivtbl->ivptr[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rb_mark_generic_ivar(VALUE obj)
|
rb_mark_and_update_generic_ivar(VALUE obj)
|
||||||
{
|
{
|
||||||
struct gen_ivtbl *ivtbl;
|
struct gen_ivtbl *ivtbl;
|
||||||
|
|
||||||
if (rb_gen_ivtbl_get(obj, 0, &ivtbl)) {
|
if (rb_gen_ivtbl_get(obj, 0, &ivtbl)) {
|
||||||
gen_ivtbl_mark(ivtbl);
|
gen_ivtbl_mark_and_update(ivtbl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user