Make every initial size pool shape a root shape

This commit makes every initial size pool shape a root shape and assigns
it a capacity of 0.
This commit is contained in:
Peter Zhu 2023-11-02 09:49:23 -04:00
parent ad4f973ecd
commit 38ba040d8b
8 changed files with 7 additions and 29 deletions

View File

@ -776,11 +776,6 @@ shape_i(rb_shape_t *shape, void *data)
dump_append(dc, ", \"capacity\":");
dump_append_sizet(dc, shape->capacity);
break;
case SHAPE_INITIAL_CAPACITY:
dump_append(dc, "\"INITIAL_CAPACITY\"");
dump_append(dc, ", \"capacity\":");
dump_append_sizet(dc, shape->capacity);
break;
case SHAPE_T_OBJECT:
dump_append(dc, "\"T_OBJECT\"");
break;

3
gc.c
View File

@ -2980,8 +2980,7 @@ rb_class_instance_allocate_internal(VALUE klass, VALUE flags, bool wb_protected)
}
VALUE obj = newobj_of(GET_RACTOR(), klass, flags, 0, 0, 0, wb_protected, size);
RUBY_ASSERT(rb_shape_get_shape(obj)->type == SHAPE_ROOT ||
rb_shape_get_shape(obj)->type == SHAPE_INITIAL_CAPACITY);
RUBY_ASSERT(rb_shape_get_shape(obj)->type == SHAPE_ROOT);
// Set the shape to the specific T_OBJECT shape which is always
// SIZE_POOL_COUNT away from the root shape.

View File

@ -416,7 +416,6 @@ module RubyVM::RJIT # :nodoc: all
C::SHAPE_FLAG_SHIFT = Primitive.cexpr! %q{ SIZET2NUM(SHAPE_FLAG_SHIFT) }
C::SHAPE_FROZEN = Primitive.cexpr! %q{ SIZET2NUM(SHAPE_FROZEN) }
C::SHAPE_ID_NUM_BITS = Primitive.cexpr! %q{ SIZET2NUM(SHAPE_ID_NUM_BITS) }
C::SHAPE_INITIAL_CAPACITY = Primitive.cexpr! %q{ SIZET2NUM(SHAPE_INITIAL_CAPACITY) }
C::SHAPE_IVAR = Primitive.cexpr! %q{ SIZET2NUM(SHAPE_IVAR) }
C::SHAPE_MASK = Primitive.cexpr! %q{ SIZET2NUM(SHAPE_MASK) }
C::SHAPE_ROOT = Primitive.cexpr! %q{ SIZET2NUM(SHAPE_ROOT) }

14
shape.c
View File

@ -442,7 +442,6 @@ rb_shape_alloc_new_child(ID id, rb_shape_t * shape, enum shape_type shape_type)
new_shape->next_iv_index = shape->next_iv_index;
break;
case SHAPE_OBJ_TOO_COMPLEX:
case SHAPE_INITIAL_CAPACITY:
case SHAPE_ROOT:
rb_bug("Unreachable");
break;
@ -756,7 +755,6 @@ rb_shape_get_iv_index(rb_shape_t * shape, ID id, attr_index_t *value)
return true;
case SHAPE_CAPACITY_CHANGE:
case SHAPE_ROOT:
case SHAPE_INITIAL_CAPACITY:
case SHAPE_T_OBJECT:
return false;
case SHAPE_OBJ_TOO_COMPLEX:
@ -823,7 +821,6 @@ rb_shape_traverse_from_new_root(rb_shape_t *initial_shape, rb_shape_t *dest_shap
break;
case SHAPE_ROOT:
case SHAPE_CAPACITY_CHANGE:
case SHAPE_INITIAL_CAPACITY:
case SHAPE_T_OBJECT:
break;
case SHAPE_OBJ_TOO_COMPLEX:
@ -868,7 +865,6 @@ rb_shape_rebuild_shape(rb_shape_t * initial_shape, rb_shape_t * dest_shape)
case SHAPE_ROOT:
case SHAPE_FROZEN:
case SHAPE_CAPACITY_CHANGE:
case SHAPE_INITIAL_CAPACITY:
case SHAPE_T_OBJECT:
break;
case SHAPE_OBJ_TOO_COMPLEX:
@ -1149,8 +1145,8 @@ Init_default_shapes(void)
}
// Root shape
rb_shape_t * root = rb_shape_alloc_with_parent_id(0, INVALID_SHAPE_ID);
root->capacity = (uint32_t)((rb_size_pool_slot_size(0) - offsetof(struct RObject, as.ary)) / sizeof(VALUE));
rb_shape_t *root = rb_shape_alloc_with_parent_id(0, INVALID_SHAPE_ID);
root->capacity = 0;
root->type = SHAPE_ROOT;
root->size_pool_index = 0;
GET_SHAPE_TREE()->root_shape = root;
@ -1158,9 +1154,8 @@ Init_default_shapes(void)
// Shapes by size pool
for (int i = 1; i < SIZE_POOL_COUNT; i++) {
size_t capa = ((rb_size_pool_slot_size(i) - offsetof(struct RObject, as.ary)) / sizeof(VALUE));
rb_shape_t * new_shape = rb_shape_transition_shape_capa_create(root, capa);
new_shape->type = SHAPE_INITIAL_CAPACITY;
rb_shape_t *new_shape = rb_shape_alloc_with_parent_id(0, INVALID_SHAPE_ID);
new_shape->type = SHAPE_ROOT;
new_shape->size_pool_index = i;
new_shape->ancestor_index = LEAF;
RUBY_ASSERT(rb_shape_id(new_shape) == (shape_id_t)i);
@ -1172,6 +1167,7 @@ Init_default_shapes(void)
bool dont_care;
rb_shape_t * t_object_shape =
get_next_shape_internal(shape, id_t_object, SHAPE_T_OBJECT, &dont_care, true);
t_object_shape->capacity = (uint32_t)((rb_size_pool_slot_size(i) - offsetof(struct RObject, as.ary)) / sizeof(VALUE));
t_object_shape->edges = rb_id_table_create(0);
t_object_shape->ancestor_index = LEAF;
RUBY_ASSERT(rb_shape_id(t_object_shape) == (shape_id_t)(i + SIZE_POOL_COUNT));

View File

@ -65,7 +65,6 @@ enum shape_type {
SHAPE_IVAR,
SHAPE_FROZEN,
SHAPE_CAPACITY_CHANGE,
SHAPE_INITIAL_CAPACITY,
SHAPE_T_OBJECT,
SHAPE_OBJ_TOO_COMPLEX,
};

View File

@ -691,14 +691,6 @@ class TestShapes < Test::Unit::TestCase
assert_shape_equal(RubyVM::Shape.root_shape, RubyVM::Shape.of([]))
end
def test_hash_has_correct_pool_shape
omit "SHAPE_IN_BASIC_FLAGS == 0" unless RbConfig::SIZEOF["uint64_t"] <= RbConfig::SIZEOF["void*"]
# All hashes are now allocated their own ar_table, so start in a
# larger pool, and have already transitioned once.
assert_shape_equal(RubyVM::Shape.root_shape, RubyVM::Shape.of({}).parent)
end
def test_true_has_special_const_shape_id
assert_equal(RubyVM::Shape::SPECIAL_CONST_SHAPE_ID, RubyVM::Shape.of(true).id)
end

View File

@ -439,7 +439,6 @@ generator = BindingGenerator.new(
SHAPE_FLAG_SHIFT
SHAPE_FROZEN
SHAPE_ID_NUM_BITS
SHAPE_INITIAL_CAPACITY
SHAPE_IVAR
SHAPE_MASK
SHAPE_ROOT

View File

@ -1870,7 +1870,6 @@ iterate_over_shapes_with_callback(rb_shape_t *shape, rb_ivar_foreach_callback_fu
}
}
return false;
case SHAPE_INITIAL_CAPACITY:
case SHAPE_CAPACITY_CHANGE:
case SHAPE_FROZEN:
case SHAPE_T_OBJECT:
@ -4210,7 +4209,7 @@ rb_iv_tbl_copy(VALUE dst, VALUE src)
RUBY_ASSERT(rb_type(dst) == rb_type(src));
RUBY_ASSERT(RB_TYPE_P(dst, T_CLASS) || RB_TYPE_P(dst, T_MODULE));
RUBY_ASSERT(RCLASS_SHAPE_ID(dst) == ROOT_SHAPE_ID || rb_shape_get_shape_by_id(RCLASS_SHAPE_ID(dst))->type == SHAPE_INITIAL_CAPACITY);
RUBY_ASSERT(rb_shape_get_shape(dst)->type == SHAPE_ROOT);
RUBY_ASSERT(!RCLASS_IVPTR(dst));
rb_ivar_foreach(src, tbl_copy_i, dst);