Eliminate redundant work and branching when marking T_OBJECT (#15274)

This commit is contained in:
Luke Gruber 2025-11-26 16:23:34 -05:00 committed by GitHub
parent 5f55c9c8fb
commit 1660b8145c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
Notes: git 2025-11-26 21:24:03 +00:00
Merged-By: luke-gru <luke.gru@gmail.com>
3 changed files with 21 additions and 7 deletions

6
gc.c
View File

@ -3227,19 +3227,21 @@ rb_gc_mark_children(void *objspace, VALUE obj)
}
case T_OBJECT: {
uint32_t len;
if (rb_shape_obj_too_complex_p(obj)) {
gc_mark_tbl_no_pin(ROBJECT_FIELDS_HASH(obj));
len = ROBJECT_FIELDS_COUNT_COMPLEX(obj);
}
else {
const VALUE * const ptr = ROBJECT_FIELDS(obj);
uint32_t len = ROBJECT_FIELDS_COUNT(obj);
len = ROBJECT_FIELDS_COUNT_NOT_COMPLEX(obj);
for (uint32_t i = 0; i < len; i++) {
gc_mark_internal(ptr[i]);
}
}
attr_index_t fields_count = ROBJECT_FIELDS_COUNT(obj);
attr_index_t fields_count = (attr_index_t)len;
if (fields_count) {
VALUE klass = RBASIC_CLASS(obj);

View File

@ -1796,7 +1796,7 @@ obj_traverse_replace_i(VALUE obj, struct obj_traverse_replace_data *data)
if (d.stop) return 1;
}
else {
uint32_t len = ROBJECT_FIELDS_COUNT(obj);
uint32_t len = ROBJECT_FIELDS_COUNT_NOT_COMPLEX(obj);
VALUE *ptr = ROBJECT_FIELDS(obj);
for (uint32_t i = 0; i < len; i++) {

20
shape.h
View File

@ -367,16 +367,28 @@ ROBJECT_SET_FIELDS_HASH(VALUE obj, const st_table *tbl)
ROBJECT(obj)->as.heap.fields = (VALUE *)tbl;
}
static inline uint32_t
ROBJECT_FIELDS_COUNT_COMPLEX(VALUE obj)
{
return (uint32_t)rb_st_table_size(ROBJECT_FIELDS_HASH(obj));
}
static inline uint32_t
ROBJECT_FIELDS_COUNT_NOT_COMPLEX(VALUE obj)
{
RBIMPL_ASSERT_TYPE(obj, RUBY_T_OBJECT);
RUBY_ASSERT(!rb_shape_obj_too_complex_p(obj));
return RSHAPE(RBASIC_SHAPE_ID(obj))->next_field_index;
}
static inline uint32_t
ROBJECT_FIELDS_COUNT(VALUE obj)
{
if (rb_shape_obj_too_complex_p(obj)) {
return (uint32_t)rb_st_table_size(ROBJECT_FIELDS_HASH(obj));
return ROBJECT_FIELDS_COUNT_COMPLEX(obj);
}
else {
RBIMPL_ASSERT_TYPE(obj, RUBY_T_OBJECT);
RUBY_ASSERT(!rb_shape_obj_too_complex_p(obj));
return RSHAPE(RBASIC_SHAPE_ID(obj))->next_field_index;
return ROBJECT_FIELDS_COUNT_NOT_COMPLEX(obj);
}
}