summaryrefslogtreecommitdiff
path: root/mro.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2010-11-12 18:13:16 -0800
committerFather Chrysostomos <sprout@cpan.org>2010-11-12 18:13:16 -0800
commitbeeda1437785916becc8ab64bf5576025a49b65f (patch)
treeaa7c250babe04f2e537f74c55c6e9d88799a0623 /mro.c
parentf7afb5473b6b3ffb63d7449cc0d82951d25a0886 (diff)
downloadperl-beeda1437785916becc8ab64bf5576025a49b65f.tar.gz
mro_package_moved only needs one loop
We can avoid the double iteration by doing the first iteration’s job (to clear the linearisations) inside gather_and_rename as the items are added to the stash. The important thing is that they all be cleared before *any* calls to mro_isa_changed_in, which will still be the case. Maybe ‘gather_and_rename’ is not such a good name any more....
Diffstat (limited to 'mro.c')
-rw-r--r--mro.c20
1 files changed, 5 insertions, 15 deletions
diff --git a/mro.c b/mro.c
index 4d1c11e0b4..1aac22585c 100644
--- a/mro.c
+++ b/mro.c
@@ -444,7 +444,7 @@ by the C<setisa> magic, should not need to invoke directly.
=cut
*/
-/* Macro to avoid repeating the code three times. */
+/* Macro to avoid repeating the code five times. */
#define CLEAR_LINEAR(mEta) \
if (mEta->mro_linear_all) { \
SvREFCNT_dec(MUTABLE_SV(mEta->mro_linear_all)); \
@@ -744,7 +744,7 @@ Perl_mro_package_moved(pTHX_ HV * const stash, HV * const oldstash,
as neither B nor B::B can be updated before the other, since they
will reset caches on foo, which will see either B or B::B with the
wrong name. The names must be set on *all* affected stashes before
- we do anything else.
+ we do anything else. (And linearisations must be cleared, too.)
*/
stashes = (HV *) sv_2mortal((SV *)newHV());
mro_gather_and_rename(
@@ -752,19 +752,6 @@ Perl_mro_package_moved(pTHX_ HV * const stash, HV * const oldstash,
stash, oldstash, newname, newname_len
);
- /* Iterate through the stashes, wiping isa linearisations, but leaving
- the isa hash (which mro_isa_changed_in needs for adjusting the
- isarev hashes belonging to parent classes). */
- hv_iterinit(stashes);
- while((iter = hv_iternext(stashes))) {
- HV * const stash = *(HV **)HEK_KEY(HeKEY_hek(iter));
- if(HvENAME(stash)) {
- struct mro_meta* meta;
- meta = HvMROMETA(stash);
- CLEAR_LINEAR(meta);
- }
- }
-
/* Once the caches have been wiped on all the classes, call
mro_isa_changed_in on each. */
hv_iterinit(stashes);
@@ -847,6 +834,7 @@ S_mro_gather_and_rename(pTHX_ HV * const stashes, HV * const seen_stashes,
: &PL_sv_yes,
0
);
+ CLEAR_LINEAR(meta);
/* Update the effective name. */
if(HvENAME_get(oldstash)) {
@@ -910,6 +898,7 @@ S_mro_gather_and_rename(pTHX_ HV * const stashes, HV * const seen_stashes,
: &PL_sv_yes,
0
);
+ CLEAR_LINEAR(meta);
}
}
}
@@ -944,6 +933,7 @@ S_mro_gather_and_rename(pTHX_ HV * const stashes, HV * const seen_stashes,
: &PL_sv_yes,
0
);
+ CLEAR_LINEAR(meta);
}
}