I think we are trying to accommodate any of several GC systems to be
selected amongst in future.

Ken Fox <[EMAIL PROTECTED]> wrote:
> John Tobey wrote:
> > Picture this.  A Lisp (or Java, ...) structure holds a Perl
> > interpreter.  A Perl variable holds a reference to the Lisp structure.
> > Structure and interpreter become inaccessible to all threads.  Perl
> > will never know it's done with the Lisp structure, neither Perl nor
> > the structure will ever be collected, and we will have defeated
> > mark-and-sweep.
> 
> In the normal case, lisp runs the finalizer when the perl structure
> becomes garbage. In the finalizer, perl can erase the external
> reference and then next time perl collects, the structure may be
> marked as garbage. If you're talking about the situation where
> an object is only reachable through a pointer held by an external
> system, then lisp needs to use a two-phase finalization. First it
> tells the foreign system (perl) that the object is considered
> garbage except for the foreign reference. That allows perl to release
> the reference and then the object really does become garbage. If perl
> decides not to release, then the object remains a weak root. This is
> a really weird situation though and I wouldn't be surprised if most
> systems just ignore the possibility. Did you ever have this problem
> or is it contrived?

I personally guarantee the issue will arise.  :-)

> Foreign references are not swept and can't be swept unless you
> are building a gc system for non-cooperative environments (Boehm's
> collector for example) and they have a *lot* of constraints that
> most lisp systems I know of violate. The theoretical cycle won't
> be found.

Alas, I don't have a CS background.  But I have implemented garbage
collection glue between Perl and Lisp.  Here's my finalizer.  As far
as I know, it is safe and complete, but the code has never been
heavily tested, to my knowledge.  This implementation does not have
the concept of weak roots.  Every blessed Emacs::Lisp::Object holds a
mark slot within the perl-interpreter object, and perl-interpreter's
mark method marks them all.

    /* Called from Fgarbage_collect.  */
    static void
    lisp_sv_destroy (object)
         Lisp_Object object;
    {
      struct emacs_perl_interpreter *perl;
      SV *sv;

      /* Check the interpreter's status to avoid a crash after `perl-destruct'.
         During Emacs destruction, even this is dangerous.
         (The solution is to call `perl-destruct' *before* Emacs starts to
         destruct.)  */
      if (EQ (emacs_phase, Qdestructing))
        return;

      perl = LISP_SV_INTERP (object);
      if (PERL_DEFUNCT_P (perl)
          || EQ (perl->phase, Qdestructing))
        return;

      sv = (SV *) XFOREIGN_OBJECT (object)->data;

      if (SvREFCNT (sv) > 1 || ! perl->frame_p || ! SvROK (sv))
        {
          SvREFCNT_dec (sv);
          return;
        }
      call_perl (SV_FREE, sv);
    }

-John

Reply via email to