summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2013-10-27 06:35:35 -0700
committerFather Chrysostomos <sprout@cpan.org>2013-10-28 16:15:09 -0700
commit0ca9877d08d37b8bc87c72cc832142c90f929378 (patch)
tree6679beb57c25035ffb0fcb4d4730fba146d85a16
parent4639d557ab77c475c9938688efe6b61bedcecf8b (diff)
downloadperl-0ca9877d08d37b8bc87c72cc832142c90f929378.tar.gz
When deleting via hek, pass the computed hash value
In those cases where the hash key comes from a hek, we already have a computed hash value, so pass that to hv_common. The easiest way to accomplish this is to add a new macro.
-rw-r--r--gv.c7
-rw-r--r--hv.c19
-rw-r--r--hv.h6
-rw-r--r--sv.c4
4 files changed, 16 insertions, 20 deletions
diff --git a/gv.c b/gv.c
index 4e0611b66b..70e638efba 100644
--- a/gv.c
+++ b/gv.c
@@ -2379,9 +2379,7 @@ Perl_gp_free(pTHX_ GV *gv)
const HEK *hvname_hek = HvNAME_HEK(hv);
DEBUG_o(Perl_deb(aTHX_ "gp_free clearing PL_stashcache for '%"HEKf"'\n", hvname_hek));
if (PL_stashcache && hvname_hek)
- (void)hv_delete(PL_stashcache, HEK_KEY(hvname_hek),
- (HEK_UTF8(hvname_hek) ? -HEK_LEN(hvname_hek) : HEK_LEN(hvname_hek)),
- G_DISCARD);
+ (void)hv_deletehek(PL_stashcache, hvname_hek, G_DISCARD);
SvREFCNT_dec(hv);
}
SvREFCNT_dec(io);
@@ -3336,8 +3334,7 @@ Perl_gv_try_downgrade(pTHX_ GV *gv)
cv = GvCV(gv);
if (!cv) {
HEK *gvnhek = GvNAME_HEK(gv);
- (void)hv_delete(stash, HEK_KEY(gvnhek),
- HEK_UTF8(gvnhek) ? -HEK_LEN(gvnhek) : HEK_LEN(gvnhek), G_DISCARD);
+ (void)hv_deletehek(stash, gvnhek, G_DISCARD);
} else if (GvMULTI(gv) && cv &&
!SvOBJECT(cv) && !SvMAGICAL(cv) && !SvREADONLY(cv) &&
CvSTASH(cv) == stash && CvGV(cv) == gv &&
diff --git a/hv.c b/hv.c
index 3cb0b079f8..45ee0a4d93 100644
--- a/hv.c
+++ b/hv.c
@@ -1752,7 +1752,6 @@ Perl_hv_undef_flags(pTHX_ HV *hv, U32 flags)
{
dVAR;
XPVHV* xhv;
- const char *name;
const bool save = !!SvREFCNT(hv);
if (!hv)
@@ -1770,14 +1769,11 @@ Perl_hv_undef_flags(pTHX_ HV *hv, U32 flags)
if they will be freed anyway. */
/* note that the code following prior to hfreeentries is duplicated
* in sv_clear(), and changes here should be done there too */
- if (PL_phase != PERL_PHASE_DESTRUCT && (name = HvNAME(hv))) {
+ if (PL_phase != PERL_PHASE_DESTRUCT && HvNAME(hv)) {
if (PL_stashcache) {
DEBUG_o(Perl_deb(aTHX_ "hv_undef_flags clearing PL_stashcache for '%"
HEKf"'\n", HvNAME_HEK(hv)));
- (void)hv_delete(PL_stashcache, name,
- HEK_UTF8(HvNAME_HEK(hv)) ? -HvNAMELEN_get(hv) : HvNAMELEN_get(hv),
- G_DISCARD
- );
+ (void)hv_deletehek(PL_stashcache, HvNAME_HEK(hv), G_DISCARD);
}
hv_name_set(hv, NULL, 0, 0);
}
@@ -1789,18 +1785,15 @@ Perl_hv_undef_flags(pTHX_ HV *hv, U32 flags)
if (SvOOK(hv)) {
struct xpvhv_aux * const aux = HvAUX(hv);
struct mro_meta *meta;
+ const char *name;
- if ((name = HvENAME_get(hv))) {
+ if (HvENAME_get(hv)) {
if (PL_phase != PERL_PHASE_DESTRUCT)
mro_isa_changed_in(hv);
if (PL_stashcache) {
DEBUG_o(Perl_deb(aTHX_ "hv_undef_flags clearing PL_stashcache for effective name '%"
HEKf"'\n", HvENAME_HEK(hv)));
- (void)hv_delete(
- PL_stashcache, name,
- HEK_UTF8(HvENAME_HEK(hv)) ? -HvENAMELEN_get(hv) : HvENAMELEN_get(hv),
- G_DISCARD
- );
+ (void)hv_deletehek(PL_stashcache, HvENAME_HEK(hv), G_DISCARD);
}
}
@@ -1811,7 +1804,7 @@ Perl_hv_undef_flags(pTHX_ HV *hv, U32 flags)
if (name && PL_stashcache) {
DEBUG_o(Perl_deb(aTHX_ "hv_undef_flags clearing PL_stashcache for name '%"
HEKf"'\n", HvNAME_HEK(hv)));
- (void)hv_delete(PL_stashcache, name, (HEK_UTF8(HvNAME_HEK(hv)) ? -HvNAMELEN_get(hv) : HvNAMELEN_get(hv)), G_DISCARD);
+ (void)hv_deletehek(PL_stashcache, HvNAME_HEK(hv), G_DISCARD);
}
hv_name_set(hv, NULL, 0, flags);
}
diff --git a/hv.h b/hv.h
index fa13a84230..d5632be03c 100644
--- a/hv.h
+++ b/hv.h
@@ -470,6 +470,12 @@ C<SV*>.
(MUTABLE_SV(hv_common_key_len((hv), (key), (klen), \
(flags) | HV_DELETE, NULL, 0)))
+#ifdef PERL_CORE
+# define hv_deletehek(hv, hek, flags) \
+ hv_common(hv, NULL, HEK_KEY(hek), HEK_LEN(hek), HEK_UTF8(hek), \
+ (flags)|HV_DELETE, NULL, HEK_HASH(hek))
+#endif
+
/* This refcounted he structure is used for storing the hints used for lexical
pragmas. Without threads, it's basically struct he + refcount.
With threads, life gets more complex as the structure needs to be shared
diff --git a/sv.c b/sv.c
index 45853f65e9..f649ad9f03 100644
--- a/sv.c
+++ b/sv.c
@@ -6301,8 +6301,8 @@ Perl_sv_clear(pTHX_ SV *const orig_sv)
if (PL_stashcache) {
DEBUG_o(Perl_deb(aTHX_ "sv_clear clearing PL_stashcache for '%"SVf"'\n",
sv));
- (void)hv_delete(PL_stashcache, name,
- HvNAMEUTF8((HV*)sv) ? -HvNAMELEN_get((HV*)sv) : HvNAMELEN_get((HV*)sv), G_DISCARD);
+ (void)hv_deletehek(PL_stashcache,
+ HvNAME_HEK((HV*)sv), G_DISCARD);
}
hv_name_set((HV*)sv, NULL, 0, 0);
}