summaryrefslogtreecommitdiff
path: root/scope.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2012-11-28 08:36:34 -0800
committerFather Chrysostomos <sprout@cpan.org>2012-11-29 09:11:30 -0800
commit978a498e17ec54b6f1fc65f3375a62a68f321f99 (patch)
treecc9f490a623bb40458a8813f59a5bb64af80b188 /scope.c
parent6e1b2de7c59099adaa1866fe94957b98fabcd9c4 (diff)
downloadperl-978a498e17ec54b6f1fc65f3375a62a68f321f99.tar.gz
Reset method caches when GPs are shared
The new MRO stuff in 5.10 made PL_sub_generation++ mostly unnecessary, and almost all uses of it were replaced with mro_method_changed_in. There is only one problem: That doesn’t actually work properly. After glob-to-glob assignment (*foo = *bar), both globs share the same GP (glob pointer, or list of glob slots). But there is no list of GVs associated with any GP. So there is no way, given a GV whose GP is shared, to find out what other classes might need their method caches reset. sub B::b { "b" } *A::b = *B::b; @C::ISA = "A"; print C->b, "\n"; # should print "b" eval 'sub B::b { "c" }'; print C->b, "\n"; # should print "c" __END__ $ perl5.8.9 foo b c $ perl5.10.0 foo b b And it continues up to 5.16.x. If a GP is shared, then those places where mro_method_changed_in is called after the GP has been modified must do PL_sub_generation++ instead if the GP is shared, which can be detected through its refer- ence count.
Diffstat (limited to 'scope.c')
-rw-r--r--scope.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/scope.c b/scope.c
index cd342d05d3..8eca725f22 100644
--- a/scope.c
+++ b/scope.c
@@ -861,7 +861,7 @@ Perl_leave_scope(pTHX_ I32 base)
GvGP_set(gv, (GP*)ptr);
/* putting a method back into circulation ("local")*/
if (GvCVu(gv) && (hv=GvSTASH(gv)) && HvENAME_get(hv))
- mro_method_changed_in(hv);
+ gv_method_changed(gv);
SvREFCNT_dec(gv);
break;
case SAVEt_FREESV: