From 0ca9877d08d37b8bc87c72cc832142c90f929378 Mon Sep 17 00:00:00 2001 From: Father Chrysostomos Date: Sun, 27 Oct 2013 06:35:35 -0700 Subject: [PATCH] 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. --- gv.c | 7 ++----- hv.c | 19 ++++++------------- hv.h | 6 ++++++ sv.c | 4 ++-- 4 files changed, 16 insertions(+), 20 deletions(-) diff --git a/gv.c b/gv.c index 4e0611b..70e638e 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 3cb0b07..45ee0a4 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 fa13a84..d5632be 100644 --- a/hv.h +++ b/hv.h @@ -470,6 +470,12 @@ C. (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 45853f6..f649ad9 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); } -- 2.7.4