Skip to content

Commit ccf2b7c

Browse files
committed
Refactor rb_shape_too_complex_p to take a shape_id_t.
1 parent a1f72d2 commit ccf2b7c

File tree

8 files changed

+51
-54
lines changed

8 files changed

+51
-54
lines changed

gc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ uint32_t
380380
rb_gc_rebuild_shape(VALUE obj, size_t heap_id)
381381
{
382382
shape_id_t orig_shape_id = rb_obj_shape_id(obj);
383-
if (rb_shape_id_too_complex_p(orig_shape_id)) {
383+
if (rb_shape_too_complex_p(orig_shape_id)) {
384384
return (uint32_t)orig_shape_id;
385385
}
386386

object.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ rb_obj_copy_ivar(VALUE dest, VALUE obj)
331331

332332
shape_id_t src_shape_id = RBASIC_SHAPE_ID(obj);
333333

334-
if (rb_shape_id_too_complex_p(src_shape_id)) {
334+
if (rb_shape_too_complex_p(src_shape_id)) {
335335
rb_shape_copy_complex_ivars(dest, obj, src_shape_id, ROBJECT_FIELDS_HASH(obj));
336336
return;
337337
}
@@ -343,7 +343,7 @@ rb_obj_copy_ivar(VALUE dest, VALUE obj)
343343
RUBY_ASSERT(RSHAPE(initial_shape_id)->type == SHAPE_T_OBJECT);
344344

345345
dest_shape_id = rb_shape_rebuild(initial_shape_id, src_shape_id);
346-
if (UNLIKELY(rb_shape_id_too_complex_p(dest_shape_id))) {
346+
if (UNLIKELY(rb_shape_too_complex_p(dest_shape_id))) {
347347
st_table *table = rb_st_init_numtable_with_size(src_num_ivs);
348348
rb_obj_copy_ivs_to_hash_table(obj, table);
349349
rb_obj_init_too_complex(dest, table);
@@ -496,7 +496,7 @@ rb_obj_clone_setup(VALUE obj, VALUE clone, VALUE kwfreeze)
496496

497497
if (RB_OBJ_FROZEN(obj)) {
498498
shape_id_t next_shape_id = rb_shape_transition_frozen(clone);
499-
if (!rb_shape_obj_too_complex_p(clone) && rb_shape_id_too_complex_p(next_shape_id)) {
499+
if (!rb_shape_obj_too_complex_p(clone) && rb_shape_too_complex_p(next_shape_id)) {
500500
rb_evict_ivars_to_hash(clone);
501501
}
502502
else {
@@ -520,7 +520,7 @@ rb_obj_clone_setup(VALUE obj, VALUE clone, VALUE kwfreeze)
520520
shape_id_t next_shape_id = rb_shape_transition_frozen(clone);
521521
// If we're out of shapes, but we want to freeze, then we need to
522522
// evacuate this clone to a hash
523-
if (!rb_shape_obj_too_complex_p(clone) && rb_shape_id_too_complex_p(next_shape_id)) {
523+
if (!rb_shape_obj_too_complex_p(clone) && rb_shape_too_complex_p(next_shape_id)) {
524524
rb_evict_ivars_to_hash(clone);
525525
}
526526
else {

shape.c

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,12 @@ rb_shape_id(rb_shape_t *shape)
328328
return (shape_id_t)(shape - GET_SHAPE_TREE()->shape_list);
329329
}
330330

331+
static inline bool
332+
shape_too_complex_p(rb_shape_t *shape)
333+
{
334+
return shape->flags & SHAPE_FL_TOO_COMPLEX;
335+
}
336+
331337
void
332338
rb_shape_each_shape_id(each_shape_callback callback, void *data)
333339
{
@@ -494,7 +500,7 @@ get_next_shape_internal(rb_shape_t *shape, ID id, enum shape_type shape_type, bo
494500
rb_shape_t *res = NULL;
495501

496502
// There should never be outgoing edges from "too complex", except for SHAPE_FROZEN and SHAPE_OBJ_ID
497-
RUBY_ASSERT(!rb_shape_too_complex_p(shape) || shape_type == SHAPE_FROZEN || shape_type == SHAPE_OBJ_ID);
503+
RUBY_ASSERT(!shape_too_complex_p(shape) || shape_type == SHAPE_FROZEN || shape_type == SHAPE_OBJ_ID);
498504

499505
*variation_created = false;
500506

@@ -597,13 +603,13 @@ remove_shape_recursive(rb_shape_t *shape, ID id, rb_shape_t **removed_shape)
597603
// We found a new parent. Create a child of the new parent that
598604
// has the same attributes as this shape.
599605
if (new_parent) {
600-
if (UNLIKELY(rb_shape_too_complex_p(new_parent))) {
606+
if (UNLIKELY(shape_too_complex_p(new_parent))) {
601607
return new_parent;
602608
}
603609

604610
bool dont_care;
605611
rb_shape_t *new_child = get_next_shape_internal(new_parent, shape->edge_name, shape->type, &dont_care, true);
606-
if (UNLIKELY(rb_shape_too_complex_p(new_child))) {
612+
if (UNLIKELY(shape_too_complex_p(new_child))) {
607613
return new_child;
608614
}
609615

@@ -626,7 +632,7 @@ rb_shape_transition_remove_ivar(VALUE obj, ID id, shape_id_t *removed_shape_id)
626632
shape_id_t shape_id = rb_obj_shape_id(obj);
627633
rb_shape_t *shape = RSHAPE(shape_id);
628634

629-
RUBY_ASSERT(!rb_shape_too_complex_p(shape));
635+
RUBY_ASSERT(!shape_too_complex_p(shape));
630636

631637
rb_shape_t *removed_shape = NULL;
632638
rb_shape_t *new_shape = remove_shape_recursive(shape, id, &removed_shape);
@@ -770,7 +776,7 @@ static inline rb_shape_t *
770776
shape_get_next(rb_shape_t *shape, VALUE obj, ID id, bool emit_warnings)
771777
{
772778
RUBY_ASSERT(!is_instance_id(id) || RTEST(rb_sym2str(ID2SYM(id))));
773-
if (UNLIKELY(rb_shape_too_complex_p(shape))) {
779+
if (UNLIKELY(shape_too_complex_p(shape))) {
774780
return shape;
775781
}
776782

@@ -921,7 +927,7 @@ rb_shape_get_iv_index(shape_id_t shape_id, ID id, attr_index_t *value)
921927

922928
// It doesn't make sense to ask for the index of an IV that's stored
923929
// on an object that is "too complex" as it uses a hash for storing IVs
924-
RUBY_ASSERT(!rb_shape_too_complex_p(shape));
930+
RUBY_ASSERT(!shape_too_complex_p(shape));
925931

926932
if (!shape_cache_get_iv_index(shape, id, value)) {
927933
// If it wasn't in the ancestor cache, then don't do a linear search
@@ -1091,19 +1097,13 @@ rb_shape_copy_complex_ivars(VALUE dest, VALUE obj, shape_id_t src_shape_id, st_t
10911097
RUBY_FUNC_EXPORTED bool
10921098
rb_shape_obj_too_complex_p(VALUE obj)
10931099
{
1094-
return rb_shape_too_complex_p(obj_shape(obj));
1100+
return shape_too_complex_p(obj_shape(obj));
10951101
}
10961102

10971103
bool
1098-
rb_shape_id_too_complex_p(shape_id_t shape_id)
1104+
rb_shape_too_complex_p(shape_id_t shape_id)
10991105
{
1100-
return rb_shape_too_complex_p(RSHAPE(shape_id));
1101-
}
1102-
1103-
bool
1104-
rb_shape_too_complex_p(rb_shape_t *shape)
1105-
{
1106-
return shape->flags & SHAPE_FL_TOO_COMPLEX;
1106+
return shape_too_complex_p(RSHAPE(shape_id));
11071107
}
11081108

11091109
size_t
@@ -1143,7 +1143,7 @@ shape_too_complex(VALUE self)
11431143
{
11441144
shape_id_t shape_id = NUM2INT(rb_struct_getmember(self, rb_intern("id")));
11451145
rb_shape_t *shape = RSHAPE(shape_id);
1146-
return RBOOL(rb_shape_too_complex_p(shape));
1146+
return RBOOL(shape_too_complex_p(shape));
11471147
}
11481148

11491149
static VALUE

shape.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,7 @@ shape_id_t rb_shape_get_next_iv_shape(shape_id_t shape_id, ID id);
125125
bool rb_shape_get_iv_index(shape_id_t shape_id, ID id, attr_index_t *value);
126126
bool rb_shape_get_iv_index_with_hint(shape_id_t shape_id, ID id, attr_index_t *value, shape_id_t *shape_id_hint);
127127
RUBY_FUNC_EXPORTED bool rb_shape_obj_too_complex_p(VALUE obj);
128-
bool rb_shape_too_complex_p(rb_shape_t *shape);
129-
bool rb_shape_id_too_complex_p(shape_id_t shape_id);
128+
bool rb_shape_too_complex_p(shape_id_t shape_id);
130129
bool rb_shape_has_object_id(shape_id_t shape_id);
131130

132131
shape_id_t rb_shape_transition_frozen(VALUE obj);

variable.c

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1322,7 +1322,7 @@ rb_obj_field_get(VALUE obj, shape_id_t target_shape_id)
13221322
RUBY_ASSERT(!SPECIAL_CONST_P(obj));
13231323
RUBY_ASSERT(RSHAPE(target_shape_id)->type == SHAPE_IVAR || RSHAPE(target_shape_id)->type == SHAPE_OBJ_ID);
13241324

1325-
if (rb_shape_id_too_complex_p(target_shape_id)) {
1325+
if (rb_shape_too_complex_p(target_shape_id)) {
13261326
st_table *fields_hash;
13271327
switch (BUILTIN_TYPE(obj)) {
13281328
case T_CLASS:
@@ -1386,7 +1386,7 @@ rb_ivar_lookup(VALUE obj, ID id, VALUE undef)
13861386
VALUE val;
13871387

13881388
RB_VM_LOCKING() {
1389-
if (rb_shape_id_too_complex_p(shape_id)) {
1389+
if (rb_shape_too_complex_p(shape_id)) {
13901390
st_table * iv_table = RCLASS_FIELDS_HASH(obj);
13911391
if (rb_st_lookup(iv_table, (st_data_t)id, (st_data_t *)&val)) {
13921392
found = true;
@@ -1422,7 +1422,7 @@ rb_ivar_lookup(VALUE obj, ID id, VALUE undef)
14221422
}
14231423
case T_OBJECT:
14241424
{
1425-
if (rb_shape_id_too_complex_p(shape_id)) {
1425+
if (rb_shape_too_complex_p(shape_id)) {
14261426
st_table * iv_table = ROBJECT_FIELDS_HASH(obj);
14271427
VALUE val;
14281428
if (rb_st_lookup(iv_table, (st_data_t)id, (st_data_t *)&val)) {
@@ -1496,7 +1496,7 @@ rb_ivar_delete(VALUE obj, ID id, VALUE undef)
14961496
}
14971497

14981498
shape_id_t old_shape_id = rb_obj_shape_id(obj);
1499-
if (rb_shape_id_too_complex_p(old_shape_id)) {
1499+
if (rb_shape_too_complex_p(old_shape_id)) {
15001500
goto too_complex;
15011501
}
15021502

@@ -1510,7 +1510,7 @@ rb_ivar_delete(VALUE obj, ID id, VALUE undef)
15101510
return undef;
15111511
}
15121512

1513-
if (UNLIKELY(rb_shape_id_too_complex_p(next_shape_id))) {
1513+
if (UNLIKELY(rb_shape_too_complex_p(next_shape_id))) {
15141514
rb_evict_fields_to_hash(obj);
15151515
goto too_complex;
15161516
}
@@ -1714,33 +1714,31 @@ general_ivar_set(VALUE obj, ID id, VALUE val, void *data,
17141714

17151715
shape_id_t current_shape_id = RBASIC_SHAPE_ID(obj);
17161716

1717-
if (UNLIKELY(rb_shape_id_too_complex_p(current_shape_id))) {
1717+
if (UNLIKELY(rb_shape_too_complex_p(current_shape_id))) {
17181718
goto too_complex;
17191719
}
17201720

17211721
attr_index_t index;
17221722
if (!rb_shape_get_iv_index(current_shape_id, id, &index)) {
17231723
result.existing = false;
1724-
rb_shape_t *current_shape = RSHAPE(current_shape_id);
17251724

1726-
index = current_shape->next_field_index;
1725+
index = RSHAPE_LEN(current_shape_id);
17271726
if (index >= SHAPE_MAX_FIELDS) {
17281727
rb_raise(rb_eArgError, "too many instance variables");
17291728
}
17301729

17311730
shape_id_t next_shape_id = rb_shape_transition_add_ivar(obj, id);
1732-
rb_shape_t *next_shape = RSHAPE(next_shape_id);
1733-
if (UNLIKELY(rb_shape_too_complex_p(next_shape))) {
1731+
if (UNLIKELY(rb_shape_too_complex_p(next_shape_id))) {
17341732
transition_too_complex_func(obj, data);
17351733
goto too_complex;
17361734
}
1737-
else if (UNLIKELY(next_shape->capacity != current_shape->capacity)) {
1738-
RUBY_ASSERT(next_shape->capacity > current_shape->capacity);
1739-
shape_resize_fields_func(obj, current_shape->capacity, next_shape->capacity, data);
1735+
else if (UNLIKELY(RSHAPE_CAPACITY(next_shape_id) != RSHAPE_CAPACITY(current_shape_id))) {
1736+
RUBY_ASSERT(RSHAPE_CAPACITY(next_shape_id) > RSHAPE_CAPACITY(current_shape_id));
1737+
shape_resize_fields_func(obj, RSHAPE_CAPACITY(current_shape_id), RSHAPE_CAPACITY(next_shape_id), data);
17401738
}
17411739

1742-
RUBY_ASSERT(next_shape->type == SHAPE_IVAR);
1743-
RUBY_ASSERT(index == (next_shape->next_field_index - 1));
1740+
RUBY_ASSERT(RSHAPE_TYPE_P(next_shape_id, SHAPE_IVAR));
1741+
RUBY_ASSERT(index == (RSHAPE_INDEX(next_shape_id)));
17441742
set_shape_id_func(obj, next_shape_id, data);
17451743
}
17461744

@@ -1772,8 +1770,8 @@ general_field_set(VALUE obj, shape_id_t target_shape_id, VALUE val, void *data,
17721770
{
17731771
shape_id_t current_shape_id = RBASIC_SHAPE_ID(obj);
17741772

1775-
if (UNLIKELY(rb_shape_id_too_complex_p(target_shape_id))) {
1776-
if (UNLIKELY(!rb_shape_id_too_complex_p(current_shape_id))) {
1773+
if (UNLIKELY(rb_shape_too_complex_p(target_shape_id))) {
1774+
if (UNLIKELY(!rb_shape_too_complex_p(current_shape_id))) {
17771775
transition_too_complex_func(obj, data);
17781776
}
17791777

@@ -2062,7 +2060,7 @@ void rb_obj_freeze_inline(VALUE x)
20622060

20632061
// If we're transitioning from "not complex" to "too complex"
20642062
// then evict ivars. This can happen if we run out of shapes
2065-
if (rb_shape_id_too_complex_p(next_shape_id) && !rb_shape_obj_too_complex_p(x)) {
2063+
if (rb_shape_too_complex_p(next_shape_id) && !rb_shape_obj_too_complex_p(x)) {
20662064
rb_evict_fields_to_hash(x);
20672065
}
20682066
rb_shape_set_shape_id(x, next_shape_id);
@@ -2257,7 +2255,7 @@ obj_fields_each(VALUE obj, rb_ivar_foreach_callback_func *func, st_data_t arg, b
22572255
};
22582256

22592257
shape_id_t shape_id = RBASIC_SHAPE_ID(obj);
2260-
if (rb_shape_id_too_complex_p(shape_id)) {
2258+
if (rb_shape_too_complex_p(shape_id)) {
22612259
rb_st_foreach(ROBJECT_FIELDS_HASH(obj), each_hash_iv, (st_data_t)&itr_data);
22622260
}
22632261
else {
@@ -2280,7 +2278,7 @@ gen_fields_each(VALUE obj, rb_ivar_foreach_callback_func *func, st_data_t arg, b
22802278
};
22812279

22822280
shape_id_t shape_id = RBASIC_SHAPE_ID(obj);
2283-
if (rb_shape_id_too_complex_p(shape_id)) {
2281+
if (rb_shape_too_complex_p(shape_id)) {
22842282
rb_st_foreach(fields_tbl->as.complex.table, each_hash_iv, (st_data_t)&itr_data);
22852283
}
22862284
else {
@@ -2301,7 +2299,7 @@ class_fields_each(VALUE obj, rb_ivar_foreach_callback_func *func, st_data_t arg,
23012299
};
23022300

23032301
shape_id_t shape_id = RBASIC_SHAPE_ID(obj);
2304-
if (rb_shape_id_too_complex_p(shape_id)) {
2302+
if (rb_shape_too_complex_p(shape_id)) {
23052303
rb_st_foreach(RCLASS_WRITABLE_FIELDS_HASH(obj), each_hash_iv, (st_data_t)&itr_data);
23062304
}
23072305
else {
@@ -2334,7 +2332,7 @@ rb_copy_generic_ivar(VALUE dest, VALUE obj)
23342332

23352333
FL_SET(dest, FL_EXIVAR);
23362334

2337-
if (rb_shape_id_too_complex_p(src_shape_id)) {
2335+
if (rb_shape_too_complex_p(src_shape_id)) {
23382336
rb_shape_copy_complex_ivars(dest, obj, src_shape_id, obj_fields_tbl->as.complex.table);
23392337
return;
23402338
}
@@ -2346,7 +2344,7 @@ rb_copy_generic_ivar(VALUE dest, VALUE obj)
23462344
RUBY_ASSERT(RSHAPE(initial_shape_id)->type == SHAPE_ROOT);
23472345

23482346
dest_shape_id = rb_shape_rebuild(initial_shape_id, src_shape_id);
2349-
if (UNLIKELY(rb_shape_id_too_complex_p(dest_shape_id))) {
2347+
if (UNLIKELY(rb_shape_too_complex_p(dest_shape_id))) {
23502348
st_table *table = rb_st_init_numtable_with_size(src_num_ivs);
23512349
rb_obj_copy_ivs_to_hash_table(obj, table);
23522350
rb_obj_init_too_complex(dest, table);

vm_insnhelper.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1275,7 +1275,7 @@ vm_getivar(VALUE obj, ID id, const rb_iseq_t *iseq, IVC ic, const struct rb_call
12751275
}
12761276

12771277
if (LIKELY(cached_id == shape_id)) {
1278-
RUBY_ASSERT(!rb_shape_id_too_complex_p(cached_id));
1278+
RUBY_ASSERT(!rb_shape_too_complex_p(cached_id));
12791279

12801280
if (index == ATTR_INDEX_NOT_SET) {
12811281
return default_value;
@@ -1316,7 +1316,7 @@ vm_getivar(VALUE obj, ID id, const rb_iseq_t *iseq, IVC ic, const struct rb_call
13161316
}
13171317
#endif
13181318

1319-
if (rb_shape_id_too_complex_p(shape_id)) {
1319+
if (rb_shape_too_complex_p(shape_id)) {
13201320
st_table *table = NULL;
13211321
switch (BUILTIN_TYPE(obj)) {
13221322
case T_CLASS:
@@ -1394,7 +1394,7 @@ vm_getivar(VALUE obj, ID id, const rb_iseq_t *iseq, IVC ic, const struct rb_call
13941394
static void
13951395
populate_cache(attr_index_t index, shape_id_t next_shape_id, ID id, const rb_iseq_t *iseq, IVC ic, const struct rb_callcache *cc, bool is_attr)
13961396
{
1397-
RUBY_ASSERT(!rb_shape_id_too_complex_p(next_shape_id));
1397+
RUBY_ASSERT(!rb_shape_too_complex_p(next_shape_id));
13981398

13991399
// Cache population code
14001400
if (is_attr) {
@@ -1422,7 +1422,7 @@ vm_setivar_slowpath(VALUE obj, ID id, VALUE val, const rb_iseq_t *iseq, IVC ic,
14221422

14231423
shape_id_t next_shape_id = RBASIC_SHAPE_ID(obj);
14241424

1425-
if (!rb_shape_id_too_complex_p(next_shape_id)) {
1425+
if (!rb_shape_too_complex_p(next_shape_id)) {
14261426
populate_cache(index, next_shape_id, id, iseq, ic, cc, is_attr);
14271427
}
14281428

@@ -1495,7 +1495,7 @@ vm_setivar(VALUE obj, ID id, VALUE val, shape_id_t dest_shape_id, attr_index_t i
14951495
VM_ASSERT(!rb_ractor_shareable_p(obj) || rb_obj_frozen_p(obj));
14961496

14971497
shape_id_t shape_id = RBASIC_SHAPE_ID(obj);
1498-
RUBY_ASSERT(dest_shape_id == INVALID_SHAPE_ID || !rb_shape_id_too_complex_p(dest_shape_id));
1498+
RUBY_ASSERT(dest_shape_id == INVALID_SHAPE_ID || !rb_shape_too_complex_p(dest_shape_id));
14991499

15001500
if (LIKELY(shape_id == dest_shape_id)) {
15011501
RUBY_ASSERT(dest_shape_id != INVALID_SHAPE_ID && shape_id != INVALID_SHAPE_ID);

yjit/src/codegen.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3121,14 +3121,14 @@ fn gen_set_ivar(
31213121
let new_shape = if !shape_too_complex && receiver_t_object && ivar_index.is_none() {
31223122
let current_shape = comptime_receiver.shape_of();
31233123
let next_shape_id = unsafe { rb_shape_transition_add_ivar_no_warnings(comptime_receiver, ivar_name) };
3124-
let next_shape = unsafe { rb_shape_lookup(next_shape_id) };
31253124

31263125
// If the VM ran out of shapes, or this class generated too many leaf,
31273126
// it may be de-optimized into OBJ_TOO_COMPLEX_SHAPE (hash-table).
3128-
new_shape_too_complex = unsafe { rb_shape_too_complex_p(next_shape) };
3127+
new_shape_too_complex = unsafe { rb_shape_too_complex_p(next_shape_id) };
31293128
if new_shape_too_complex {
31303129
Some((next_shape_id, None, 0_usize))
31313130
} else {
3131+
let next_shape = unsafe { rb_shape_lookup(next_shape_id) };
31323132
let current_capacity = unsafe { (*current_shape).capacity };
31333133

31343134
// If the new shape has a different capacity, or is TOO_COMPLEX, we'll have to

yjit/src/cruby_bindings.inc.rs

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)