Skip to content

Commit 808724c

Browse files
syberdemerphq
syber
authored andcommitted
introduce gv_stashsvpvn_cached()
Wrap gv_stashpvn_internal() with a routine which caches what it does, and rework gv_stashsv() and gv_stashpvn() to use the cached codepath. Also rework the documentation of gv_stashsv() and gv_stashpvn() that the gv_stashsv() is prefered as there is a mechanism to cache the hash value associated with the name which requires an SV to passed in as an argument for caching purposes. Note this is a reworked version of sybers original patch.
1 parent 0eadbda commit 808724c

File tree

4 files changed

+53
-9
lines changed

4 files changed

+53
-9
lines changed

embed.fnc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,7 @@ Apd |HV* |gv_stashpv |NN const char* name|I32 flags
550550
Apd |HV* |gv_stashpvn |NN const char* name|U32 namelen|I32 flags
551551
#if defined(PERL_IN_GV_C)
552552
i |HV* |gv_stashpvn_internal|NN const char* name|U32 namelen|I32 flags
553+
i |HV* |gv_stashsvpvn_cached|NULLOK SV *namesv|NULLOK const char* name|U32 namelen|I32 flags
553554
#endif
554555
Apd |HV* |gv_stashsv |NN SV* sv|I32 flags
555556
Apd |void |hv_clear |NULLOK HV *hv

embed.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1440,6 +1440,7 @@
14401440
#define gv_magicalize(a,b,c,d,e,f) S_gv_magicalize(aTHX_ a,b,c,d,e,f)
14411441
#define gv_magicalize_isa(a) S_gv_magicalize_isa(aTHX_ a)
14421442
#define gv_stashpvn_internal(a,b,c) S_gv_stashpvn_internal(aTHX_ a,b,c)
1443+
#define gv_stashsvpvn_cached(a,b,c,d) S_gv_stashsvpvn_cached(aTHX_ a,b,c,d)
14431444
#define maybe_multimagic_gv(a,b,c) S_maybe_multimagic_gv(aTHX_ a,b,c)
14441445
#define parse_gv_stash_name(a,b,c,d,e,f,g,h) S_parse_gv_stash_name(aTHX_ a,b,c,d,e,f,g,h)
14451446
#define require_tie_mod(a,b,c,d,e) S_require_tie_mod(aTHX_ a,b,c,d,e)

gv.c

Lines changed: 50 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1313,6 +1313,9 @@ Flags may be one of:
13131313
13141314
The most important of which are probably GV_ADD and SVf_UTF8.
13151315
1316+
Note, use of C<gv_stashsv> instead of C<gv_stashpvn> where possible is strongly
1317+
recommended for performance reasons.
1318+
13161319
=cut
13171320
*/
13181321

@@ -1362,44 +1365,82 @@ S_gv_stashpvn_internal(pTHX_ const char *name, U32 namelen, I32 flags)
13621365
return stash;
13631366
}
13641367

1365-
HV*
1366-
Perl_gv_stashpvn(pTHX_ const char *name, U32 namelen, I32 flags)
1368+
/*
1369+
gv_stashsvpvn_cached
1370+
1371+
Returns a pointer to the stash for a specified package, possibly
1372+
cached. Implements both C<gv_stashpvn> and C<gc_stashsv>.
1373+
1374+
Requires one of either namesv or namepv to be non-null.
1375+
1376+
See C<gv_stashpvn> for details on "flags".
1377+
1378+
Note the sv interface is strongly preferred for performance reasons.
1379+
1380+
*/
1381+
1382+
#define PERL_ARGS_ASSERT_GV_STASHSVPVN_CACHED \
1383+
assert(namesv || name)
1384+
1385+
PERL_STATIC_INLINE HV*
1386+
S_gv_stashsvpvn_cached(pTHX_ SV *namesv, const char *name, U32 namelen, I32 flags)
13671387
{
13681388
HV* stash;
1369-
const HE* const he = (const HE *)hv_common(
1370-
PL_stashcache, NULL, name, namelen,
1389+
HE* he;
1390+
1391+
PERL_ARGS_ASSERT_GV_STASHSVPVN_CACHED;
1392+
1393+
he = (HE *)hv_common(
1394+
PL_stashcache, namesv, name, namelen,
13711395
(flags & SVf_UTF8) ? HVhek_UTF8 : 0, 0, NULL, 0
13721396
);
1397+
13731398
if (he) return INT2PTR(HV*,SvIVX(HeVAL(he)));
13741399
else if (flags & GV_CACHE_ONLY) return NULL;
13751400

1401+
if (namesv) {
1402+
if (SvOK(namesv)) { /* prevent double uninit warning */
1403+
STRLEN len;
1404+
name = SvPV_const(namesv, len);
1405+
namelen = len;
1406+
flags |= SvUTF8(namesv);
1407+
} else {
1408+
name = ""; namelen = 0;
1409+
}
1410+
}
13761411
stash = gv_stashpvn_internal(name, namelen, flags);
13771412

13781413
if (stash && namelen) {
13791414
SV* const ref = newSViv(PTR2IV(stash));
13801415
(void)hv_store(PL_stashcache, name,
13811416
(flags & SVf_UTF8) ? -(I32)namelen : (I32)namelen, ref, 0);
13821417
}
1418+
13831419
return stash;
13841420
}
13851421

1422+
HV*
1423+
Perl_gv_stashpvn(pTHX_ const char *name, U32 namelen, I32 flags)
1424+
{
1425+
PERL_ARGS_ASSERT_GV_STASHPVN;
1426+
return gv_stashsvpvn_cached(NULL, name, namelen, flags);
1427+
}
1428+
13861429
/*
13871430
=for apidoc gv_stashsv
13881431
13891432
Returns a pointer to the stash for a specified package. See C<gv_stashpvn>.
13901433
1434+
Note this interface is strongly preferred over C<gv_stashpvn> for performance reasons.
1435+
13911436
=cut
13921437
*/
13931438

13941439
HV*
13951440
Perl_gv_stashsv(pTHX_ SV *sv, I32 flags)
13961441
{
1397-
STRLEN len;
1398-
const char * const ptr = SvPV_const(sv,len);
1399-
14001442
PERL_ARGS_ASSERT_GV_STASHSV;
1401-
1402-
return gv_stashpvn(ptr, len, flags | SvUTF8(sv));
1443+
return gv_stashsvpvn_cached(sv, NULL, 0, flags);
14031444
}
14041445

14051446

proto.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5912,6 +5912,7 @@ PERL_STATIC_INLINE HV* S_gv_stashpvn_internal(pTHX_ const char* name, U32 namele
59125912
#define PERL_ARGS_ASSERT_GV_STASHPVN_INTERNAL \
59135913
assert(name)
59145914

5915+
PERL_STATIC_INLINE HV* S_gv_stashsvpvn_cached(pTHX_ SV *namesv, const char* name, U32 namelen, I32 flags);
59155916
STATIC void S_maybe_multimagic_gv(pTHX_ GV *gv, const char *name, const svtype sv_type)
59165917
__attribute__nonnull__(pTHX_1)
59175918
__attribute__nonnull__(pTHX_2);

0 commit comments

Comments
 (0)