lucy-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Marvin Humphrey <>
Subject Re: [lucy-dev] Non-deterministic destruction in Perl 5.15
Date Fri, 09 Dec 2011 03:05:38 GMT
On Fri, Nov 11, 2011 at 02:51:26PM -0800, wrote:
> Perl previously did call DESTROY on objects during global destruction, and
> the order was non-determistic, but a few objects would escape the purge, in
> particular:
> • blessed array elements (bless \$_[0])
> • blessed closure variables (bless my \$x; sub foo { $x ... })
> • any other unreferenced SVs (not referenced by RVs or GVs)
> The VTables belong to the third category.

This is the key.

> Let’s look at the relevant code from the perl source:
> > void
> > Perl_sv_clean_objs(pTHX)
> > {
> >    dVAR;
> >    GV *olddef, *olderr;
> >    PL_in_clean_objs = TRUE;
> This line goes through all scalars that are references to objects and calls
> undef() on them:
> >    visit(do_clean_objs, SVf_ROK, SVf_ROK);

> The next two function calls eliminate all blessed GV slots. I think the GV
> slots are nulled and the SVs in them have their reference count lowered, but
> I haven’t actually read the code.
> >    /* Some barnacles may yet remain, clinging to typeglobs.
> >     * Run the non-IO destructors first: they may want to output
> >     * error messages, close files etc */
> >    visit(do_clean_named_objs, SVt_PVGV|SVpgv_GP, SVTYPEMASK|SVp_POK|SVpgv_GP);
> >    visit(do_clean_named_io_objs, SVt_PVGV|SVpgv_GP, SVTYPEMASK|SVp_POK|SVpgv_GP);
> This is the bit added in 5.15. It looks for any objects remaining. Since
> they may be referenced by other objects (indirectly, through closures or
> array elements), whose destructors have not fired yet, they are not actually
> freed, but simply cursed; that is, they revert to non-object status
> (something you cannot do from Perl or XS, even though the core has the
> facility to do it).

OK, by now every Lucy object created by a direct user action should have gone
away, even if it was stuck in e.g. a Perl hash circular reference.

> >    /* And if there are some very tenacious barnacles clinging to arrays,
> >       closures, or what have you.... */
> >    visit(do_curse, SVs_OBJECT, SVs_OBJECT);

The only Lucy objects remaining at this point should be:

  * Static objects such as the VTables for all compiled classes.
  * Dynamically created VTables for Perl-space subclasses.
  * The VTable_registry (which is a Lucy::Object::LockFreeRegistry).
  * The keys for the VTable_registry, which are all CharBufs.

After examining the relevant destructors, I am satisfied that it doesn't
matter in which order any cached Perl objects associated with those Lucy
objects get reclaimed, so long as we sever the connection between the
Perl-space DESTROY method for Lucy::Object::VTable and VTable_destroy().

> So based on that it looks as though you simply need to remove the destructor
> on VTables, since they will be destroyed last. Or create a destructor that
> makes sure all other Lucy objects have been purged.
> Now I hope I have you thoroughly confused. :-)

It took me a while to understand, but you have persuaded me that your solution
is the right one.

Thank you for sharing your valuable expertise on this subject.

Marvin Humphrey

View raw message