Avoid calling RCLASS_SUPER in rb_class_superclass

This commit is contained in:
John Hawthorn 2025-05-22 16:07:22 -07:00
parent 11ad7f5f47
commit e01e89f55c
Notes: git 2025-05-23 17:22:37 +00:00
2 changed files with 31 additions and 9 deletions

View File

@ -0,0 +1,23 @@
prelude: |
class SimpleClass; end
class OneModuleClass
1.times { include Module.new }
end
class MediumClass
10.times { include Module.new }
end
class LargeClass
100.times { include Module.new }
end
benchmark:
object_class_superclass: |
Object.superclass
simple_class_superclass: |
SimpleClass.superclass
one_module_class: |
OneModuleClass.superclass
medium_class_superclass: |
MediumClass.superclass
large_class_superclass: |
LargeClass.superclass
loop_count: 20000000

View File

@ -2259,23 +2259,22 @@ rb_class_superclass(VALUE klass)
{
RUBY_ASSERT(RB_TYPE_P(klass, T_CLASS));
VALUE super = RCLASS_SUPER(klass);
VALUE *superclasses;
size_t superclasses_depth;
VALUE *superclasses = RCLASS_SUPERCLASSES(klass);
size_t superclasses_depth = RCLASS_SUPERCLASS_DEPTH(klass);
if (!super) {
if (klass == rb_cBasicObject) return Qnil;
if (klass == rb_cBasicObject) return Qnil;
if (!superclasses) {
RUBY_ASSERT(!RCLASS_SUPER(klass));
rb_raise(rb_eTypeError, "uninitialized class");
}
superclasses_depth = RCLASS_SUPERCLASS_DEPTH(klass);
if (!superclasses_depth) {
return Qnil;
}
else {
superclasses = RCLASS_SUPERCLASSES(klass);
super = superclasses[superclasses_depth - 1];
RUBY_ASSERT(RB_TYPE_P(klass, T_CLASS));
VALUE super = superclasses[superclasses_depth - 1];
RUBY_ASSERT(RB_TYPE_P(super, T_CLASS));
return super;
}
}