Speed up class allocator search

This rewrites the class allocator search to be faster. Instead of using
RCLASS_SUPER, which is now even slower due to Box, we can scan the
superclasses list to find a class where the allocator is defined.

This also disallows allocating from an ICLASS. Previously I believe that
was only done for FrozenCore, and that was changed in
e596cf6e93dbf121e197cccfec8a69902e00eda3.
This commit is contained in:
John Hawthorn 2025-12-05 23:31:33 -08:00
parent 459c377222
commit 32e6dc0f31
Notes: git 2025-12-11 17:53:39 +00:00
2 changed files with 15 additions and 5 deletions

View File

@ -658,8 +658,8 @@ RCLASS_SET_REFINED_CLASS(VALUE klass, VALUE refined)
static inline rb_alloc_func_t
RCLASS_ALLOCATOR(VALUE klass)
{
RUBY_ASSERT(RB_TYPE_P(klass, T_CLASS) || RB_TYPE_P(klass, T_ICLASS));
if (RCLASS_SINGLETON_P(klass) || RB_TYPE_P(klass, T_ICLASS)) {
RBIMPL_ASSERT_TYPE(klass, T_CLASS);
if (RCLASS_SINGLETON_P(klass)) {
return 0;
}
return RCLASS_EXT_PRIME(klass)->as.class.allocator;

View File

@ -1635,10 +1635,20 @@ rb_undef_alloc_func(VALUE klass)
rb_alloc_func_t
rb_get_alloc_func(VALUE klass)
{
Check_Type(klass, T_CLASS);
RBIMPL_ASSERT_TYPE(klass, T_CLASS);
for (; klass; klass = RCLASS_SUPER(klass)) {
rb_alloc_func_t allocator = RCLASS_ALLOCATOR(klass);
rb_alloc_func_t allocator = RCLASS_ALLOCATOR(klass);
if (allocator == UNDEF_ALLOC_FUNC) return 0;
if (allocator) return allocator;
VALUE *superclasses = RCLASS_SUPERCLASSES(klass);
size_t depth = RCLASS_SUPERCLASS_DEPTH(klass);
for (size_t i = depth; i > 0; i--) {
klass = superclasses[i - 1];
RBIMPL_ASSERT_TYPE(klass, T_CLASS);
allocator = RCLASS_ALLOCATOR(klass);
if (allocator == UNDEF_ALLOC_FUNC) break;
if (allocator) return allocator;
}