Reset method caches when GPs are shared
authorFather Chrysostomos <sprout@cpan.org>
Wed, 28 Nov 2012 16:36:34 +0000 (08:36 -0800)
committerFather Chrysostomos <sprout@cpan.org>
Thu, 29 Nov 2012 17:11:30 +0000 (09:11 -0800)
commit978a498e17ec54b6f1fc65f3375a62a68f321f99
treecc9f490a623bb40458a8813f59a5bb64af80b188
parent6e1b2de7c59099adaa1866fe94957b98fabcd9c4
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.
gv.h
op.c
scope.c
sv.c
t/mro/method_caching.t