summaryrefslogtreecommitdiff
path: root/gv.c
diff options
context:
space:
mode:
authorsyber <syber@crazypanda.ru>2014-08-08 19:03:03 +0400
committerSteffen Mueller <smueller@cpan.org>2014-08-20 09:12:01 +0200
commit4e7ebec5b38b722121a7df00ce087bb49f1c6d43 (patch)
tree5a5e862f19b63fde37e97d0021bca0ce3262e504 /gv.c
parentf88f10f50706154dd7828ac8abe4a02f99a5e280 (diff)
downloadperl-4e7ebec5b38b722121a7df00ce087bb49f1c6d43.tar.gz
Make gv_stashpvn() use PL_stashcache
perl has a stash name lookup cache, which is currently just used for looking up up class names in Some::Class->method calls. This means that a lookup of the class name 'A::B::C' gets reduced from doing several stash lookups (e.g. $::{'A::'}{'B::'}{'C::'}) to a single cache lookup (e.g. $PL_stashcache{'A::B::C::'}, so to speak). Make gv_stashpvn() use this cache too, which means that all package name lookups benefit, not just class method calls. Among other things, this also indirectly affects bless operations both from Perl (OP_BLESS) and XS.
Diffstat (limited to 'gv.c')
-rw-r--r--gv.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/gv.c b/gv.c
index 8b43d91ef8..47793eff2a 100644
--- a/gv.c
+++ b/gv.c
@@ -1313,8 +1313,8 @@ The most important of which are probably GV_ADD and SVf_UTF8.
=cut
*/
-HV*
-Perl_gv_stashpvn(pTHX_ const char *name, U32 namelen, I32 flags)
+PERL_STATIC_INLINE HV*
+S_stashpvn(pTHX_ const char *name, U32 namelen, I32 flags)
{
char smallbuf[128];
char *tmpbuf;
@@ -1351,6 +1351,25 @@ Perl_gv_stashpvn(pTHX_ const char *name, U32 namelen, I32 flags)
return stash;
}
+HV*
+Perl_gv_stashpvn(pTHX_ const char *name, U32 namelen, I32 flags)
+{
+ HV* stash;
+ const HE* const he = (const HE *)hv_common(
+ PL_stashcache, NULL, name, namelen,
+ (flags & SVf_UTF8) ? HVhek_UTF8 : 0, 0, NULL, 0
+ );
+ if (he) return INT2PTR(HV*,SvIVX(HeVAL(he)));
+
+ stash = S_stashpvn(aTHX_ name, namelen, flags);
+ if (stash && namelen) {
+ SV* const ref = newSViv(PTR2IV(stash));
+ hv_store(PL_stashcache, name,
+ (flags & SVf_UTF8) ? -(I32)namelen : (I32)namelen, ref, 0);
+ }
+ return stash;
+}
+
/*
=for apidoc gv_stashsv