summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2021-09-03 08:56:18 +0000
committerNicholas Clark <nick@ccl4.org>2021-09-03 10:37:55 +0000
commite5a468d33677d8d809b0b67b8f21b9ad022c96c9 (patch)
tree660e21442007ee899c1f242c3f9ba32fb9783110
parentec7598c64132341ffec3934a78bad178846da36b (diff)
downloadperl-e5a468d33677d8d809b0b67b8f21b9ad022c96c9.tar.gz
Only call S_mro_clean_isarev() if HvTOTALKEYS() is non-zero
Two callers already had an "is it empty?" check. Add this to the third caller, and hence remove the duplicated internal check.
-rw-r--r--mro_core.c36
1 files changed, 19 insertions, 17 deletions
diff --git a/mro_core.c b/mro_core.c
index 04b9060c89..947326eb0f 100644
--- a/mro_core.c
+++ b/mro_core.c
@@ -639,7 +639,7 @@ Perl_mro_isa_changed_in(pTHX_ HV* stash)
hv_storehek(mroisarev, namehek, &PL_sv_yes);
}
- if ((SV *)isa != &PL_sv_undef) {
+ if ((SV *)isa != &PL_sv_undef && HvTOTALKEYS(isa)) {
assert(namehek);
mro_clean_isarev(
isa, HEK_KEY(namehek), HEK_LEN(namehek),
@@ -683,12 +683,13 @@ Perl_mro_isa_changed_in(pTHX_ HV* stash)
}
/* Delete our name from our former parents' isarevs. */
- if(isa && HvARRAY(isa))
+ if(isa && HvTOTALKEYS(isa))
mro_clean_isarev(isa, stashname, stashname_len, meta->isa,
HEK_HASH(stashhek), HEK_UTF8(stashhek));
}
-/* Deletes name from all the isarev entries listed in isa */
+/* Deletes name from all the isarev entries listed in isa.
+ Don't call this if isa is already empty. */
STATIC void
S_mro_clean_isarev(pTHX_ HV * const isa, const char * const name,
const STRLEN len, HV * const exceptions, U32 hash,
@@ -698,21 +699,22 @@ S_mro_clean_isarev(pTHX_ HV * const isa, const char * const name,
PERL_ARGS_ASSERT_MRO_CLEAN_ISAREV;
+ assert(HvTOTALKEYS(isa));
/* Delete our name from our former parents' isarevs. */
- if(HvARRAY(isa) && hv_iterinit(isa)) {
+
+ hv_iterinit(isa);
+ while((iter = hv_iternext(isa))) {
SV **svp;
- while((iter = hv_iternext(isa))) {
- HEK *key = HeKEY_hek(iter);
- if(exceptions && hv_existshek(exceptions, key))
- continue;
- svp = hv_fetchhek(PL_isarev, key, 0);
- if(svp) {
- HV * const isarev = (HV *)*svp;
- (void)hv_common(isarev, NULL, name, len, flags,
- G_DISCARD|HV_DELETE, NULL, hash);
- if(!HvARRAY(isarev) || !HvUSEDKEYS(isarev))
- (void)hv_deletehek(PL_isarev, key, G_DISCARD);
- }
+ HEK *key = HeKEY_hek(iter);
+ if(exceptions && hv_existshek(exceptions, key))
+ continue;
+ svp = hv_fetchhek(PL_isarev, key, 0);
+ if(svp) {
+ HV * const isarev = (HV *)*svp;
+ (void)hv_common(isarev, NULL, name, len, flags,
+ G_DISCARD|HV_DELETE, NULL, hash);
+ if(!HvTOTALKEYS(isarev))
+ (void)hv_deletehek(PL_isarev, key, G_DISCARD);
}
}
}
@@ -975,7 +977,7 @@ S_mro_gather_and_rename(pTHX_ HV * const stashes, HV * const seen_stashes,
* PL_isarev, since we still need it. hv_delete morti-
* fies it for us, so sv_2mortal is not necessary. */
if(HvENAME_HEK(oldstash) != enamehek) {
- if(meta->isa && HvARRAY(meta->isa))
+ if(meta->isa && HvTOTALKEYS(meta->isa))
mro_clean_isarev(meta->isa, name, len, 0, 0,
name_utf8 ? HVhek_UTF8 : 0);
isarev = (HV *)hv_delete_ent(PL_isarev, *svp, 0, 0);