Skip to content

Commit

Permalink
rb_evict_ivars_to_hash: get rid of the sahpe paramater
Browse files Browse the repository at this point in the history
It's only used to allocate the table with the right size,
but in some case we were passing `rb_shape_get_shape_by_id(SHAPE_OBJ_TOO_COMPLEX)`
which `next_iv_index` is a bit undefined.

So overall we're better to just allocate a table the size of the existing
object, it should be close enough in the vast majority of cases,
and that's already a de-optimizaton path anyway.
  • Loading branch information
byroot committed Nov 16, 2023
1 parent b92a92a commit 81b35fe
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 10 deletions.
2 changes: 1 addition & 1 deletion internal/variable.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ VALUE rb_mod_set_temporary_name(VALUE, VALUE);
struct gen_ivtbl;
int rb_gen_ivtbl_get(VALUE obj, ID id, struct gen_ivtbl **ivtbl);
int rb_obj_evacuate_ivs_to_hash_table(ID key, VALUE val, st_data_t arg);
void rb_evict_ivars_to_hash(VALUE obj, rb_shape_t * shape);
void rb_evict_ivars_to_hash(VALUE obj);

RUBY_SYMBOL_EXPORT_BEGIN
/* variable.c (export) */
Expand Down
4 changes: 2 additions & 2 deletions object.c
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,7 @@ mutable_obj_clone(VALUE obj, VALUE kwfreeze)
if (RB_OBJ_FROZEN(obj)) {
rb_shape_t * next_shape = rb_shape_transition_shape_frozen(clone);
if (!rb_shape_obj_too_complex(clone) && next_shape->type == SHAPE_OBJ_TOO_COMPLEX) {
rb_evict_ivars_to_hash(clone, rb_shape_get_shape(clone));
rb_evict_ivars_to_hash(clone);
}
else {
rb_shape_set_shape(clone, next_shape);
Expand All @@ -498,7 +498,7 @@ mutable_obj_clone(VALUE obj, VALUE kwfreeze)
// 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(clone) && next_shape->type == SHAPE_OBJ_TOO_COMPLEX) {
rb_evict_ivars_to_hash(clone, rb_shape_get_shape(clone));
rb_evict_ivars_to_hash(clone);
}
else {
rb_shape_set_shape(clone, next_shape);
Expand Down
14 changes: 7 additions & 7 deletions variable.c
Original file line number Diff line number Diff line change
Expand Up @@ -1331,7 +1331,7 @@ rb_ivar_delete(VALUE obj, ID id, VALUE undef)

if (!rb_shape_transition_shape_remove_ivar(obj, id, shape, &val)) {
if (!rb_shape_obj_too_complex(obj)) {
rb_evict_ivars_to_hash(obj, shape);
rb_evict_ivars_to_hash(obj);
}

st_table *table = NULL;
Expand Down Expand Up @@ -1371,11 +1371,11 @@ rb_attr_delete(VALUE obj, ID id)
}

void
rb_evict_ivars_to_hash(VALUE obj, rb_shape_t * shape)
rb_evict_ivars_to_hash(VALUE obj)
{
RUBY_ASSERT(!rb_shape_obj_too_complex(obj));

st_table *table = st_init_numtable_with_size(shape->next_iv_index);
st_table *table = st_init_numtable_with_size(rb_ivar_count(obj));

// Evacuate all previous values from shape into id_table
rb_ivar_foreach(obj, rb_obj_evacuate_ivs_to_hash_table, (st_data_t)table);
Expand Down Expand Up @@ -1570,7 +1570,7 @@ generic_ivar_set_set_shape(VALUE obj, rb_shape_t *shape, void *data)
static void
generic_ivar_set_transition_too_complex(VALUE obj, void *_data)
{
rb_evict_ivars_to_hash(obj, rb_shape_get_shape_by_id(SHAPE_OBJ_TOO_COMPLEX));
rb_evict_ivars_to_hash(obj);
FL_SET_RAW(obj, FL_EXIVAR);
}

Expand Down Expand Up @@ -1666,7 +1666,7 @@ obj_ivar_set_set_shape(VALUE obj, rb_shape_t *shape, void *_data)
static void
obj_ivar_set_transition_too_complex(VALUE obj, void *_data)
{
rb_evict_ivars_to_hash(obj, rb_shape_get_shape_by_id(SHAPE_OBJ_TOO_COMPLEX));
rb_evict_ivars_to_hash(obj);
}

static st_table *
Expand Down Expand Up @@ -1756,7 +1756,7 @@ void rb_obj_freeze_inline(VALUE x)
// If we're transitioning from "not complex" to "too complex"
// then evict ivars. This can happen if we run out of shapes
if (!rb_shape_obj_too_complex(x) && next_shape->type == SHAPE_OBJ_TOO_COMPLEX) {
rb_evict_ivars_to_hash(x, rb_shape_get_shape(x));
rb_evict_ivars_to_hash(x);
}
rb_shape_set_shape(x, next_shape);

Expand Down Expand Up @@ -4185,7 +4185,7 @@ class_ivar_set_set_shape(VALUE obj, rb_shape_t *shape, void *_data)
static void
class_ivar_set_transition_too_complex(VALUE obj, void *_data)
{
rb_evict_ivars_to_hash(obj, rb_shape_get_shape_by_id(SHAPE_OBJ_TOO_COMPLEX));
rb_evict_ivars_to_hash(obj);
}

static st_table *
Expand Down

0 comments on commit 81b35fe

Please sign in to comment.