diff options
author | Nicholas Clark <nick@ccl4.org> | 2021-09-21 12:10:01 +0000 |
---|---|---|
committer | Nicholas Clark <nick@ccl4.org> | 2021-10-11 19:05:13 +0000 |
commit | 09cd3e1cbb58c83075231a9d80a523ef3631faee (patch) | |
tree | 47a443266c9445df138d5b459a2a84a0129134ff /hv.c | |
parent | e43d289c7c581c1a5094e7bade06b9cdbaeb430f (diff) | |
download | perl-09cd3e1cbb58c83075231a9d80a523ef3631faee.tar.gz |
Eliminate more uses of `XPVHV* xhv;` to cache `(XPVHV*)SvANY(hv)`
Similar to commit 4b6b6165ecccd54b, Perl_hv_clear() should instead read
HvMAX(hv) into a local variable.
Most other remaining uses no longer saved repeated dereferences, so
eliminate the verbosity and replace the explicit dereference with the normal
macro (and in some cases delete the comment which echos the macro).
In S_hv_free_entries() use HvTOTALKEYS(hv) directly. Whilst this is
potentially performing the deference of SvANY(hv) more than once, the
structure of the code is such that this will only happen on the last
iteration of the loop, or on the unlikely event that the hash contained NULL
values. (Such hashes are not legal in "Perl" space, but XS code can create
them.)
Diffstat (limited to 'hv.c')
-rw-r--r-- | hv.c | 20 |
1 files changed, 7 insertions, 13 deletions
@@ -1779,22 +1779,20 @@ Perl_hv_clear(pTHX_ HV *hv) { SSize_t orig_ix; - XPVHV* xhv; if (!hv) return; DEBUG_A(Perl_hv_assert(aTHX_ hv)); - xhv = (XPVHV*)SvANY(hv); - /* avoid hv being freed when calling destructors below */ EXTEND_MORTAL(1); PL_tmps_stack[++PL_tmps_ix] = SvREFCNT_inc_simple_NN(hv); orig_ix = PL_tmps_ix; if (SvREADONLY(hv) && HvTOTALKEYS(hv)) { /* restricted hash: convert all keys to placeholders */ + STRLEN max = HvMAX(hv); STRLEN i; - for (i = 0; i <= xhv->xhv_max; i++) { + for (i = 0; i <= max; i++) { HE *entry = (HvARRAY(hv))[i]; for (; entry; entry = HeNEXT(entry)) { /* not already placeholder */ @@ -1912,12 +1910,11 @@ STATIC void S_hv_free_entries(pTHX_ HV *hv) { STRLEN index = 0; - XPVHV * const xhv = (XPVHV*)SvANY(hv); SV *sv; PERL_ARGS_ASSERT_HV_FREE_ENTRIES; - while ((sv = Perl_hfree_next_entry(aTHX_ hv, &index))||xhv->xhv_keys) { + while ((sv = Perl_hfree_next_entry(aTHX_ hv, &index)) || HvTOTALKEYS(hv)) { SvREFCNT_dec(sv); } } @@ -2010,7 +2007,6 @@ return. void Perl_hv_undef_flags(pTHX_ HV *hv, U32 flags) { - XPVHV* xhv; bool save; SSize_t orig_ix = PL_tmps_ix; /* silence compiler warning about unitialized vars */ @@ -2018,7 +2014,6 @@ Perl_hv_undef_flags(pTHX_ HV *hv, U32 flags) return; save = cBOOL(SvREFCNT(hv)); DEBUG_A(Perl_hv_assert(aTHX_ hv)); - xhv = (XPVHV*)SvANY(hv); /* The name must be deleted before the call to hv_free_entries so that CVs are anonymised properly. But the effective name must be pre- @@ -2091,7 +2086,7 @@ Perl_hv_undef_flags(pTHX_ HV *hv, U32 flags) } if (!SvOOK(hv)) { Safefree(HvARRAY(hv)); - xhv->xhv_max = PERL_HASH_DEFAULT_HvMAX; /* HvMAX(hv) = 7 (it's a normal hash) */ + HvMAX(hv) = PERL_HASH_DEFAULT_HvMAX; /* 7 (it's a normal hash) */ HvARRAY(hv) = 0; } /* if we're freeing the HV, the SvMAGIC field has been reused for @@ -2907,7 +2902,6 @@ Perl_unshare_hek(pTHX_ HEK *hek) STATIC void S_unshare_hek_or_pvn(pTHX_ const HEK *hek, const char *str, I32 len, U32 hash) { - XPVHV* xhv; HE *entry; HE **oentry; bool is_utf8 = FALSE; @@ -2948,7 +2942,7 @@ S_unshare_hek_or_pvn(pTHX_ const HEK *hek, const char *str, I32 len, U32 hash) if (--*Svp == NULL) hv_delete(PL_strtab, str, len, G_DISCARD, hash); } */ - xhv = (XPVHV*)SvANY(PL_strtab); + /* assert(xhv_array != 0) */ oentry = &(HvARRAY(PL_strtab))[hash & (I32) HvMAX(PL_strtab)]; if (he) { @@ -2976,7 +2970,7 @@ S_unshare_hek_or_pvn(pTHX_ const HEK *hek, const char *str, I32 len, U32 hash) if (--entry->he_valu.hent_refcount == 0) { *oentry = HeNEXT(entry); Safefree(entry); - xhv->xhv_keys--; /* HvTOTALKEYS(hv)-- */ + HvTOTALKEYS(PL_strtab)--; } } @@ -3031,7 +3025,6 @@ S_share_hek_flags(pTHX_ const char *str, STRLEN len, U32 hash, int flags) HE *entry; const int flags_masked = flags & HVhek_MASK; const U32 hindex = hash & (I32) HvMAX(PL_strtab); - XPVHV * const xhv = (XPVHV*)SvANY(PL_strtab); PERL_ARGS_ASSERT_SHARE_HEK_FLAGS; @@ -3071,6 +3064,7 @@ S_share_hek_flags(pTHX_ const char *str, STRLEN len, U32 hash, int flags) char *k; HE **const head = &HvARRAY(PL_strtab)[hindex]; HE *const next = *head; + XPVHV * const xhv = (XPVHV*)SvANY(PL_strtab); /* We don't actually store a HE from the arena and a regular HEK. Instead we allocate one chunk of memory big enough for both, |