develooper Front page | perl.perl5.porters | Postings from September 2012

[perl #59882] Variable falls out of scope but is not garbage-collected

From:
Father Chrysostomos via RT
Date:
September 24, 2012 22:16
Subject:
[perl #59882] Variable falls out of scope but is not garbage-collected
Message ID:
rt-3.6.HEAD-11172-1348550163-423.59882-15-0@perl.org
On Tue Oct 14 06:32:35 2008, nicholas wrote:
> On Tue, Oct 14, 2008 at 02:00:57PM +0100, Dave Mitchell wrote:
> > On Tue, Oct 14, 2008 at 01:30:35PM +0100, Nicholas Clark wrote:
> > > On Tue, Oct 14, 2008 at 01:05:34PM +0100, Dave Mitchell wrote:
> > > > Inherited method calls cache their lookup, so after the call to
> Child->dummy,
> > > > the sub is cached within the Child package. Thus just removing
> it from the
> > > > Parent package is no longer sufficient.
> > >
> > > But that's an artefact of caching, isn't it? And a caching system
> should not
> > > affect any behaviour (apart from performance)
> >
> > In an ideal world, yes.
> >
> > > Right now, if I understand it correctly, the implementation of
> caching is
> > > "lazy" isn't it? In that it uses what-MRO-expanded-
> PL_sub_generation-into
> > > to flag that the method cached in the child is invalid, but
> doesn't actually
> > > do any work until it finds that it has to (when the method is next
> called)
> >
> > Yes (modulo my general lack of awareness of how MRO has changed
> things).
> 
> The cache invalidation being this part of Perl_gv_fetchmeth() ?
> 
>         if ((cand_cv = GvCV(topgv))) {
>             /* If genuine method or valid cache entry, use it */
>             if (!GvCVGEN(topgv) || GvCVGEN(topgv) == topgen_cmp) {
>                 return topgv;
>             }
>             else {
>                 /* stale cache entry, junk it and move on */
> 	        SvREFCNT_dec(cand_cv);
> 	        GvCV(topgv) = cand_cv = NULL;
> 	        GvCVGEN(topgv) = 0;
>             }
>         }
>         else if (GvCVGEN(topgv) == topgen_cmp) {
>             /* cache indicates no such method definitively */
>             return 0;
>         }
> 
> 
> > I can't see any obvious way to "fix" this while maintaining caching,
> > and I think the caching is more important.
> 
> So, I think to "work" (at least for the example in the bug report) it
> would
> mean that there would need to be a hook into deleting GVs, so that if
> you
> delete a subroutine in GvCV(), then you need to take the list of all
> child
> classes, seek out the corresponding GV, and perform that "stale cache
> entry"
> code above. I believe that the MRO code already caches the list of all
> child classes, so that part isn't a (big) problem.

Think about speed, though.  Just incrementing a generation number in
each child class (what currently happens) is much faster.

Perl has never made any guarantees about exactly when things are freed
(I’ve read that in the docs, but I can’t find it right now), so I am
closing this as not-a-bug.

-- 

Father Chrysostomos


---
via perlbug:  queue: perl5 status: open
https://rt.perl.org:443/rt3/Ticket/Display.html?id=59882



nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About