diff options
| author | Jean Boussier <jean.boussier@gmail.com> | 2025-05-27 15:53:45 +0200 |
|---|---|---|
| committer | Jean Boussier <jean.boussier@gmail.com> | 2025-06-04 07:59:20 +0200 |
| commit | 625d6a9cbb0ed617b28115e4e3cb063e52481635 (patch) | |
| tree | 610cfd170759de7e0b65369dfe4e3421a2f699bf /object.c | |
| parent | 6b7e3395a4ab69f5eaefb983243a8e4cad7f8abf (diff) | |
Get rid of frozen shapes.
Instead `shape_id_t` higher bits contain flags, and the first one
tells whether the shape is frozen.
This has multiple benefits:
- Can check if a shape is frozen with a single bit check instead of
dereferencing a pointer.
- Guarantees it is always possible to transition to frozen.
- This allow reclaiming `FL_FREEZE` (not done yet).
The downside is you have to be careful to preserve these flags
when transitioning.
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/13289
Diffstat (limited to 'object.c')
| -rw-r--r-- | object.c | 16 |
1 files changed, 2 insertions, 14 deletions
@@ -496,12 +496,7 @@ rb_obj_clone_setup(VALUE obj, VALUE clone, VALUE kwfreeze) if (RB_OBJ_FROZEN(obj)) { shape_id_t next_shape_id = rb_shape_transition_frozen(clone); - if (!rb_shape_obj_too_complex_p(clone) && rb_shape_too_complex_p(next_shape_id)) { - rb_evict_ivars_to_hash(clone); - } - else { - rb_obj_set_shape_id(clone, next_shape_id); - } + rb_obj_set_shape_id(clone, next_shape_id); } break; case Qtrue: { @@ -518,14 +513,7 @@ rb_obj_clone_setup(VALUE obj, VALUE clone, VALUE kwfreeze) rb_funcallv_kw(clone, id_init_clone, 2, argv, RB_PASS_KEYWORDS); RBASIC(clone)->flags |= FL_FREEZE; shape_id_t next_shape_id = rb_shape_transition_frozen(clone); - // If we're out of shapes, but we want to freeze, then we need to - // evacuate this clone to a hash - if (!rb_shape_obj_too_complex_p(clone) && rb_shape_too_complex_p(next_shape_id)) { - rb_evict_ivars_to_hash(clone); - } - else { - rb_obj_set_shape_id(clone, next_shape_id); - } + rb_obj_set_shape_id(clone, next_shape_id); break; } case Qfalse: { |
