From 1660b8145c30f53771671dec343fa7025a953fb5 Mon Sep 17 00:00:00 2001 From: Luke Gruber Date: Wed, 26 Nov 2025 16:23:34 -0500 Subject: [PATCH] Eliminate redundant work and branching when marking T_OBJECT (#15274) --- gc.c | 6 ++++-- ractor.c | 2 +- shape.h | 20 ++++++++++++++++---- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/gc.c b/gc.c index 26afb4e718..4f6751316f 100644 --- a/gc.c +++ b/gc.c @@ -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); diff --git a/ractor.c b/ractor.c index 3fc507128c..41c32b79de 100644 --- a/ractor.c +++ b/ractor.c @@ -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++) { diff --git a/shape.h b/shape.h index 6e4a1f079b..ec5c25b32f 100644 --- a/shape.h +++ b/shape.h @@ -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); } }