From 6e4b97f1daf2a6e60dcfb5df4136ce5681095849 Mon Sep 17 00:00:00 2001 From: Jemma Issroff Date: Fri, 4 Nov 2022 10:49:00 -0400 Subject: [PATCH] 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. --- gc.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/gc.c b/gc.c index 75b330ede5..f2bccbca16 100644 --- a/gc.c +++ b/gc.c @@ -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);