summaryrefslogtreecommitdiff
path: root/shape.c
diff options
context:
space:
mode:
authorJean Boussier <[email protected]>2025-04-21 12:01:01 +0900
committerJean Boussier <[email protected]>2025-05-08 07:58:05 +0200
commitd34c15054708c84e9d3305ede0752820b42ac498 (patch)
treef961697097f2a560edf636701809e5d1c96e66ee /shape.c
parent6c9b3ac232fc65f6019af28ec836aa59b8657b70 (diff)
shape.c: refactor frozen shape to no longer be final
This opens the door to store more informations in shapes, such as the `object_id` or object address in case it has been observed and the object has to be moved.
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/13159
Diffstat (limited to 'shape.c')
-rw-r--r--shape.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/shape.c b/shape.c
index 2a0fb4033f..13b803c55a 100644
--- a/shape.c
+++ b/shape.c
@@ -50,6 +50,12 @@ static ID id_t_object;
#define BLACK 0x0
#define RED 0x1
+enum shape_flags {
+ SHAPE_FL_FROZEN = 1 << 0,
+
+ SHAPE_FL_NON_CANONICAL_MASK = SHAPE_FL_FROZEN,
+};
+
static redblack_node_t *
redblack_left(redblack_node_t *node)
{
@@ -418,6 +424,7 @@ rb_shape_alloc(ID edge_name, rb_shape_t *parent, enum shape_type type)
{
rb_shape_t *shape = rb_shape_alloc_with_parent_id(edge_name, rb_shape_id(parent));
shape->type = (uint8_t)type;
+ shape->flags = parent->flags;
shape->heap_index = parent->heap_index;
shape->capacity = parent->capacity;
shape->edges = 0;
@@ -478,6 +485,7 @@ rb_shape_alloc_new_child(ID id, rb_shape_t *shape, enum shape_type shape_type)
break;
case SHAPE_FROZEN:
new_shape->next_field_index = shape->next_field_index;
+ new_shape->flags |= SHAPE_FL_FROZEN;
break;
case SHAPE_OBJ_TOO_COMPLEX:
case SHAPE_ROOT:
@@ -576,7 +584,7 @@ get_next_shape_internal(rb_shape_t *shape, ID id, enum shape_type shape_type, bo
bool
rb_shape_frozen_shape_p(rb_shape_t *shape)
{
- return SHAPE_FROZEN == (enum shape_type)shape->type;
+ return SHAPE_FL_FROZEN & shape->flags;
}
static rb_shape_t *
@@ -975,6 +983,9 @@ rb_shape_traverse_from_new_root(rb_shape_t *initial_shape, rb_shape_t *dest_shap
return next_shape;
}
+// Rebuild a similar shape with the same ivars but starting from
+// a different SHAPE_T_OBJECT, and don't cary over non-canonical transitions
+// such as SHAPE_FROZEN.
rb_shape_t *
rb_shape_rebuild_shape(rb_shape_t *initial_shape, rb_shape_t *dest_shape)
{