Fix compaction for generic ivars
When generic instance variable has a shape, it is marked movable. If it it transitions to too complex, it needs to update references otherwise it may have incorrect references.
This commit is contained in:
parent
e201b81f79
commit
269c705f93
10
gc.c
10
gc.c
@ -7255,7 +7255,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_and_update_generic_ivar(obj);
|
rb_mark_generic_ivar(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (BUILTIN_TYPE(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
|
static void
|
||||||
gc_update_table_refs(rb_objspace_t * objspace, st_table *tbl)
|
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);
|
gc_report(4, objspace, "update-refs: %p ->\n", (void *)obj);
|
||||||
|
|
||||||
if (FL_TEST(obj, FL_EXIVAR)) {
|
if (FL_TEST(obj, FL_EXIVAR)) {
|
||||||
rb_mark_and_update_generic_ivar(obj);
|
rb_ref_update_generic_ivar(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (BUILTIN_TYPE(obj)) {
|
switch (BUILTIN_TYPE(obj)) {
|
||||||
|
@ -250,6 +250,8 @@ void rb_gc_mark_and_move(VALUE *ptr);
|
|||||||
void rb_gc_mark_weak(VALUE *ptr);
|
void rb_gc_mark_weak(VALUE *ptr);
|
||||||
void rb_gc_remove_weak(VALUE parent_obj, 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 { \
|
#define rb_gc_mark_and_move_ptr(ptr) do { \
|
||||||
VALUE _obj = (VALUE)*(ptr); \
|
VALUE _obj = (VALUE)*(ptr); \
|
||||||
rb_gc_mark_and_move(&_obj); \
|
rb_gc_mark_and_move(&_obj); \
|
||||||
|
@ -53,7 +53,8 @@ void rb_evict_ivars_to_hash(VALUE obj);
|
|||||||
|
|
||||||
RUBY_SYMBOL_EXPORT_BEGIN
|
RUBY_SYMBOL_EXPORT_BEGIN
|
||||||
/* variable.c (export) */
|
/* 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);
|
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);
|
||||||
|
23
variable.c
23
variable.c
@ -1066,17 +1066,34 @@ gen_ivtbl_resize(struct gen_ivtbl *old, uint32_t n)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rb_mark_and_update_generic_ivar(VALUE obj)
|
rb_mark_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)) {
|
||||||
if (rb_shape_obj_too_complex(obj)) {
|
if (rb_shape_obj_too_complex(obj)) {
|
||||||
rb_mark_tbl(ivtbl->as.complex.table);
|
rb_mark_tbl_no_pin(ivtbl->as.complex.table);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for (uint32_t i = 0; i < ivtbl->as.shape.numiv; i++) {
|
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]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user