summaryrefslogtreecommitdiff
path: root/gc.c
diff options
context:
space:
mode:
authorJemma Issroff <jemmaissroff@gmail.com>2022-11-04 10:49:00 -0400
committerPeter Zhu <peter@peterzhu.ca>2022-11-04 11:41:10 -0400
commit6e4b97f1daf2a6e60dcfb5df4136ce5681095849 (patch)
treede23d1f14c8fc4a5fe21c7c48f9cb811d554f766 /gc.c
parent6b9091097360988dce7b4190fef1602536ddff34 (diff)
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.
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/6673
Diffstat (limited to 'gc.c')
-rw-r--r--gc.c21
1 files 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);