1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Increment max_iv_count on class in gc marking, not gc freeing

We were previously incrementing the max_iv_count on a class in gc
freeing. By the time we free an object though, we're not guaranteed its
class is still valid. Instead, we can do this when marking and we're
guaranteed the object still knows its class.
This commit is contained in:
Jemma Issroff 2022-11-04 10:49:00 -04:00 committed by Peter Zhu
parent 6b90910973
commit 6e4b97f1da
Notes: git 2022-11-04 15:41:28 +00:00

21
gc.c
View file

@ -3429,16 +3429,6 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
RB_DEBUG_COUNTER_INC(obj_obj_transient);
}
else {
rb_shape_t *shape = rb_shape_get_shape_by_id(ROBJECT_SHAPE_ID(obj));
if (shape) {
VALUE klass = RBASIC_CLASS(obj);
// Increment max_iv_count if applicable, used to determine size pool allocation
uint32_t num_of_ivs = shape->next_iv_index;
if (RCLASS_EXT(klass)->max_iv_count < num_of_ivs) {
RCLASS_EXT(klass)->max_iv_count = num_of_ivs;
}
}
xfree(RANY(obj)->as.object.as.heap.ivptr);
RB_DEBUG_COUNTER_INC(obj_obj_ptr);
}
@ -7281,6 +7271,17 @@ gc_mark_children(rb_objspace_t *objspace, VALUE obj)
gc_mark(objspace, ptr[i]);
}
rb_shape_t *shape = rb_shape_get_shape_by_id(ROBJECT_SHAPE_ID(obj));
if (shape) {
VALUE klass = RBASIC_CLASS(obj);
// Increment max_iv_count if applicable, used to determine size pool allocation
uint32_t num_of_ivs = shape->next_iv_index;
if (RCLASS_EXT(klass)->max_iv_count < num_of_ivs) {
RCLASS_EXT(klass)->max_iv_count = num_of_ivs;
}
}
if (LIKELY(during_gc) &&
ROBJ_TRANSIENT_P(obj)) {
rb_transient_heap_mark(obj, ptr);