From 70173a72a29474b6fd8fdc629954a95a4b0a3793 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 1 Nov 2022 12:31:24 -0700 Subject: Ivar copy needs to happen _before_ setting the shape When we copy instance variables, it is possible for the GC to be kicked off. The GC looks at the shape to determine what slots to mark inside the object. If the shape is set too soon, the GC could think that there are more instance variables on the object than there actually are at that moment. --- object.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'object.c') diff --git a/object.c b/object.c index 5f8568e3b4..aa337ea2ce 100644 --- a/object.c +++ b/object.c @@ -298,6 +298,10 @@ init_copy(VALUE dest, VALUE obj) rb_copy_generic_ivar(dest, obj); rb_gc_copy_finalizer(dest, obj); + if (RB_TYPE_P(obj, T_OBJECT)) { + rb_obj_copy_ivar(dest, obj); + } + if (!RB_TYPE_P(obj, T_CLASS) && !RB_TYPE_P(obj, T_MODULE)) { rb_shape_t *shape_to_set = rb_shape_get_shape(obj); @@ -310,10 +314,6 @@ init_copy(VALUE dest, VALUE obj) // shape ids are different rb_shape_set_shape(dest, shape_to_set); } - - if (RB_TYPE_P(obj, T_OBJECT)) { - rb_obj_copy_ivar(dest, obj); - } } static VALUE immutable_obj_clone(VALUE obj, VALUE kwfreeze); -- cgit v1.2.1