summaryrefslogtreecommitdiff
path: root/object.c
diff options
context:
space:
mode:
authorJean Boussier <[email protected]>2023-11-16 17:50:21 +0100
committerJean Boussier <[email protected]>2023-11-17 09:19:21 +0100
commit94c9f166632a901e563463933efd42e618432d70 (patch)
tree948304c7e1b048d53cba547c49c0bac828066659 /object.c
parent498b086c374608005278c0f7d105df1925e13a22 (diff)
Refactor rb_obj_evacuate_ivs_to_hash_table
That function is a bit too low level to called from multiple places. It's always used in tandem with `rb_shape_set_too_complex` and both have to know how the object is laid out to update the `iv_ptr`. So instead we can provide two higher level function: - `rb_obj_copy_ivs_to_hash_table` to prepare a `st_table` from an arbitrary oject. - `rb_obj_convert_to_too_complex` to assign the new `st_table` to the old object, and safely free the old `iv_ptr`. Unfortunately both can't be combined into one, because `rb_obj_copy_ivar` need `rb_obj_copy_ivs_to_hash_table` to copy from one object to another.
Diffstat (limited to 'object.c')
-rw-r--r--object.c14
1 files changed, 5 insertions, 9 deletions
diff --git a/object.c b/object.c
index f442a562ea..a8090d0763 100644
--- a/object.c
+++ b/object.c
@@ -293,12 +293,10 @@ rb_obj_copy_ivar(VALUE dest, VALUE obj)
rb_shape_t * src_shape = rb_shape_get_shape(obj);
if (rb_shape_obj_too_complex(obj)) {
+ // obj is TOO_COMPLEX so we can copy its iv_hash
st_table * table = rb_st_init_numtable_with_size(rb_st_table_size(ROBJECT_IV_HASH(obj)));
-
- rb_ivar_foreach(obj, rb_obj_evacuate_ivs_to_hash_table, (st_data_t)table);
- rb_shape_set_too_complex(dest);
-
- ROBJECT(dest)->as.heap.ivptr = (VALUE *)table;
+ st_replace(table, ROBJECT_IV_HASH(obj));
+ rb_obj_convert_to_too_complex(dest, table);
return;
}
@@ -328,10 +326,8 @@ rb_obj_copy_ivar(VALUE dest, VALUE obj)
shape_to_set_on_dest = rb_shape_rebuild_shape(initial_shape, src_shape);
if (UNLIKELY(rb_shape_id(shape_to_set_on_dest) == OBJ_TOO_COMPLEX_SHAPE_ID)) {
st_table * table = rb_st_init_numtable_with_size(src_num_ivs);
-
- rb_ivar_foreach(obj, rb_obj_evacuate_ivs_to_hash_table, (st_data_t)table);
- rb_shape_set_too_complex(dest);
- ROBJECT(dest)->as.heap.ivptr = (VALUE *)table;
+ rb_obj_copy_ivs_to_hash_table(obj, table);
+ rb_obj_convert_to_too_complex(dest, table);
return;
}