Commit ee37eaeb12 for perl
commit ee37eaeb12fc5d6c67a134b9939eb386c1a692c1
Author: Tony Cook <tony@develop-help.com>
Date: Wed Oct 28 11:53:26 2026 +1100
sv_isa_sv: don't use NOUNIVERSAL
NOUNIVERSAL can't cache the negative lookup of isa() since it doesn't
look in UNIVERSAL, caching the negative lookup without checking
UNIVERSAL has broken normal lookups in the past, so do a normal lookup
instead, which is cached.
This sped up blessed, no isa() override isa checks from around 120ns
per call to around 74ns per call on an i7-10700F, YMMV.
As suggested by LeoNerd, we should always get an isa method now, so
make the condition LIKELY().
Fixes #24997 at least partially
diff --git a/universal.c b/universal.c
index c8cf557682..afd27b7876 100644
--- a/universal.c
+++ b/universal.c
@@ -33,6 +33,7 @@
#if defined(USE_PERLIO)
#include "perliol.h" /* For the PERLIO_F_XXX */
#endif
+#include "XSUB.h"
/*
* Contributed by Graham Barr <Graham.Barr@tiuk.ti.com>
@@ -210,6 +211,8 @@ overloaded C<isa()> method, nor will check subclassing.
*/
+XS(XS_UNIVERSAL_isa); /* defined later */
+
bool
Perl_sv_isa_sv(pTHX_ SV *sv, SV *namesv)
{
@@ -220,10 +223,14 @@ Perl_sv_isa_sv(pTHX_ SV *sv, SV *namesv)
if(!SvROK(sv) || !SvOBJECT(SvRV(sv)))
return FALSE;
- isagv = gv_fetchmeth_pvn(SvSTASH(SvRV(sv)), "isa", 3, -1, GV_NOUNIVERSAL);
- if(isagv) {
+ isagv = gv_fetchmeth_pvn(SvSTASH(SvRV(sv)), "isa", 3, -1, 0);
+ if (LIKELY(isagv)) {
dSP;
CV *isacv = isGV(isagv) ? GvCV(isagv) : (CV *)isagv;
+
+ if (CvISXSUB(isacv) && CvXSUB(isacv) == XS_UNIVERSAL_isa)
+ goto default_isa;
+
SV *retsv;
bool ret;
@@ -253,6 +260,7 @@ Perl_sv_isa_sv(pTHX_ SV *sv, SV *namesv)
/* TODO: Support namesv being an HV ref to the stash directly? */
+ default_isa:
return sv_derived_from_sv(sv, namesv, 0);
}
@@ -292,8 +300,6 @@ XXX extracted in sv_does_sv is more complicated than the hand waving above
*/
-#include "XSUB.h"
-
bool
Perl_sv_does_sv(pTHX_ SV *sv, SV *namesv, U32 flags)
{