summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Gruber <luke.gruber@shopify.com>2025-11-26 16:23:34 -0500
committerGitHub <noreply@github.com>2025-11-26 16:23:34 -0500
commit1660b8145c30f53771671dec343fa7025a953fb5 (patch)
treeaa422384ef2c5924a155639cc00236a934272355
parent5f55c9c8fb8f401537e7121171747196e66c3ba0 (diff)
Eliminate redundant work and branching when marking T_OBJECT (#15274)
-rw-r--r--gc.c6
-rw-r--r--ractor.c2
-rw-r--r--shape.h20
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
@@ -368,15 +368,27 @@ ROBJECT_SET_FIELDS_HASH(VALUE obj, const st_table *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);
}
}