summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--object.c16
-rw-r--r--shape.c19
-rw-r--r--shape.h24
-rw-r--r--test/ruby/test_shapes.rb4
4 files changed, 47 insertions, 16 deletions
@@ -339,17 +339,15 @@ rb_obj_copy_ivar(VALUE dest, VALUE obj)
shape_id_t dest_shape_id = src_shape_id;
shape_id_t initial_shape_id = RBASIC_SHAPE_ID(dest);
- if (RSHAPE(initial_shape_id)->heap_index != RSHAPE(src_shape_id)->heap_index || !rb_shape_canonical_p(src_shape_id)) {
- RUBY_ASSERT(RSHAPE(initial_shape_id)->type == SHAPE_T_OBJECT);
- dest_shape_id = rb_shape_rebuild(initial_shape_id, src_shape_id);
- if (UNLIKELY(rb_shape_too_complex_p(dest_shape_id))) {
- st_table *table = rb_st_init_numtable_with_size(src_num_ivs);
- rb_obj_copy_ivs_to_hash_table(obj, table);
- rb_obj_init_too_complex(dest, table);
- return;
- }
}
VALUE *src_buf = ROBJECT_FIELDS(obj);
@@ -1092,7 +1092,10 @@ rb_shape_traverse_from_new_root(shape_id_t initial_shape_id, shape_id_t dest_sha
{
rb_shape_t *initial_shape = RSHAPE(initial_shape_id);
rb_shape_t *dest_shape = RSHAPE(dest_shape_id);
- return shape_id(shape_traverse_from_new_root(initial_shape, dest_shape), dest_shape_id);
}
// Rebuild a similar shape with the same ivars but starting from
@@ -1136,7 +1139,7 @@ rb_shape_rebuild(shape_id_t initial_shape_id, shape_id_t dest_shape_id)
RUBY_ASSERT(!rb_shape_too_complex_p(initial_shape_id));
RUBY_ASSERT(!rb_shape_too_complex_p(dest_shape_id));
- return raw_shape_id(shape_rebuild(RSHAPE(initial_shape_id), RSHAPE(dest_shape_id)));
}
void
@@ -1238,6 +1241,14 @@ rb_shape_verify_consistency(VALUE obj, shape_id_t shape_id)
}
}
return true;
}
#endif
@@ -1288,6 +1299,7 @@ shape_id_t_to_rb_cShape(shape_id_t shape_id)
VALUE obj = rb_struct_new(rb_cShape,
INT2NUM(shape_id),
INT2NUM(shape->parent_id),
rb_shape_edge_name(shape),
INT2NUM(shape->next_field_index),
@@ -1528,7 +1540,7 @@ Init_default_shapes(void)
for (int i = 0; sizes[i] > 0; i++) {
rb_shape_t *t_object_shape = rb_shape_alloc_with_parent_id(0, INVALID_SHAPE_ID);
t_object_shape->type = SHAPE_T_OBJECT;
- t_object_shape->heap_index = i;
t_object_shape->capacity = (uint32_t)((sizes[i] - offsetof(struct RObject, as.ary)) / sizeof(VALUE));
t_object_shape->edges = rb_managed_id_table_new(256);
t_object_shape->ancestor_index = LEAF;
@@ -1552,6 +1564,7 @@ Init_shape(void)
* :nodoc: */
VALUE rb_cShape = rb_struct_define_under(rb_cRubyVM, "Shape",
"id",
"parent_id",
"edge_name",
"next_field_index",
@@ -16,8 +16,18 @@ STATIC_ASSERT(shape_id_num_bits, SHAPE_ID_NUM_BITS == sizeof(shape_id_t) * CHAR_
#define SHAPE_ID_FL_FROZEN (SHAPE_FL_FROZEN << SHAPE_ID_OFFSET_NUM_BITS)
#define SHAPE_ID_FL_HAS_OBJECT_ID (SHAPE_FL_HAS_OBJECT_ID << SHAPE_ID_OFFSET_NUM_BITS)
#define SHAPE_ID_FL_TOO_COMPLEX (SHAPE_FL_TOO_COMPLEX << SHAPE_ID_OFFSET_NUM_BITS)
#define SHAPE_ID_FL_NON_CANONICAL_MASK (SHAPE_FL_NON_CANONICAL_MASK << SHAPE_ID_OFFSET_NUM_BITS)
-#define SHAPE_ID_READ_ONLY_MASK (~SHAPE_ID_FL_FROZEN)
typedef uint32_t redblack_id_t;
@@ -72,6 +82,7 @@ enum shape_flags {
SHAPE_FL_FROZEN = 1 << 0,
SHAPE_FL_HAS_OBJECT_ID = 1 << 1,
SHAPE_FL_TOO_COMPLEX = 1 << 2,
SHAPE_FL_NON_CANONICAL_MASK = SHAPE_FL_FROZEN | SHAPE_FL_HAS_OBJECT_ID,
};
@@ -189,10 +200,19 @@ rb_shape_canonical_p(shape_id_t shape_id)
return !(shape_id & SHAPE_ID_FL_NON_CANONICAL_MASK);
}
static inline shape_id_t
rb_shape_root(size_t heap_id)
{
- return (shape_id_t)(heap_id + FIRST_T_OBJECT_SHAPE_ID);
}
static inline bool
@@ -976,7 +976,7 @@ class TestShapes < Test::Unit::TestCase
example.add_foo # makes a transition
add_foo_shape = RubyVM::Shape.of(example)
assert_equal([:@foo], example.instance_variables)
- assert_equal(initial_shape.id, add_foo_shape.parent.id)
assert_equal(1, add_foo_shape.next_field_index)
example.remove_foo # makes a transition
@@ -987,7 +987,7 @@ class TestShapes < Test::Unit::TestCase
example.add_bar # makes a transition
bar_shape = RubyVM::Shape.of(example)
assert_equal([:@bar], example.instance_variables)
- assert_equal(initial_shape.id, bar_shape.parent_id)
assert_equal(1, bar_shape.next_field_index)
end