Skip to content

Commit f0c31c5

Browse files
committed
Get rid of RSHAPE_PARENT in favor of RSHAPE_DIRECT_CHILD_P
`RSHAPE_PARENT` is error prone because it returns a raw untagged shape_id. To check if a shape is a direct parent of another, tags should be discarded. So providing a comparison function is better than exposing untagged ids.
1 parent 84ee71d commit f0c31c5

File tree

3 files changed

+11
-7
lines changed

3 files changed

+11
-7
lines changed

ext/objspace/objspace_dump.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -801,7 +801,7 @@ shape_id_i(shape_id_t shape_id, void *data)
801801

802802
if (RSHAPE_TYPE(shape_id) != SHAPE_ROOT) {
803803
dump_append(dc, ", \"parent_id\":");
804-
dump_append_lu(dc, RSHAPE_PARENT(shape_id));
804+
dump_append_lu(dc, RSHAPE_PARENT_RAW_ID(shape_id));
805805
}
806806

807807
dump_append(dc, ", \"depth\":");

shape.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,11 +271,18 @@ rb_shape_root(size_t heap_id)
271271
}
272272

273273
static inline shape_id_t
274-
RSHAPE_PARENT(shape_id_t shape_id)
274+
RSHAPE_PARENT_RAW_ID(shape_id_t shape_id)
275275
{
276276
return RSHAPE(shape_id)->parent_id;
277277
}
278278

279+
static inline bool
280+
RSHAPE_DIRECT_CHILD_P(shape_id_t parent_id, shape_id_t child_id)
281+
{
282+
return (parent_id & SHAPE_ID_FLAGS_MASK) == (child_id & SHAPE_ID_FLAGS_MASK) &&
283+
RSHAPE(child_id)->parent_id == (parent_id & SHAPE_ID_OFFSET_MASK);
284+
}
285+
279286
static inline enum shape_type
280287
RSHAPE_TYPE(shape_id_t shape_id)
281288
{

vm_insnhelper.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1473,7 +1473,7 @@ vm_setivar_default(VALUE obj, ID id, VALUE val, shape_id_t dest_shape_id, attr_i
14731473
RUBY_ASSERT(dest_shape_id != INVALID_SHAPE_ID && shape_id != INVALID_SHAPE_ID);
14741474
}
14751475
else if (dest_shape_id != INVALID_SHAPE_ID) {
1476-
if (shape_id == RSHAPE_PARENT(dest_shape_id) && RSHAPE_EDGE_NAME(dest_shape_id) == id && RSHAPE_CAPACITY(shape_id) == RSHAPE_CAPACITY(dest_shape_id)) {
1476+
if (RSHAPE_DIRECT_CHILD_P(shape_id, dest_shape_id) && RSHAPE_EDGE_NAME(dest_shape_id) == id && RSHAPE_CAPACITY(shape_id) == RSHAPE_CAPACITY(dest_shape_id)) {
14771477
RUBY_ASSERT(index < RSHAPE_CAPACITY(dest_shape_id));
14781478
}
14791479
else {
@@ -1514,14 +1514,11 @@ vm_setivar(VALUE obj, ID id, VALUE val, shape_id_t dest_shape_id, attr_index_t i
15141514
VM_ASSERT(!rb_ractor_shareable_p(obj));
15151515
}
15161516
else if (dest_shape_id != INVALID_SHAPE_ID) {
1517-
shape_id_t source_shape_id = RSHAPE_PARENT(dest_shape_id);
1518-
1519-
if (shape_id == source_shape_id && RSHAPE_EDGE_NAME(dest_shape_id) == id && RSHAPE_CAPACITY(shape_id) == RSHAPE_CAPACITY(dest_shape_id)) {
1517+
if (RSHAPE_DIRECT_CHILD_P(shape_id, dest_shape_id) && RSHAPE_EDGE_NAME(dest_shape_id) == id && RSHAPE_CAPACITY(shape_id) == RSHAPE_CAPACITY(dest_shape_id)) {
15201518
RUBY_ASSERT(dest_shape_id != INVALID_SHAPE_ID && shape_id != INVALID_SHAPE_ID);
15211519

15221520
RBASIC_SET_SHAPE_ID(obj, dest_shape_id);
15231521

1524-
RUBY_ASSERT(rb_shape_get_next_iv_shape(source_shape_id, id) == dest_shape_id);
15251522
RUBY_ASSERT(index < RSHAPE_CAPACITY(dest_shape_id));
15261523
}
15271524
else {

0 commit comments

Comments
 (0)