unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
From: Mark H Weaver <mhw@netris.org>
To: Andy Wingo <wingo@pobox.com>
Cc: "Ludovic Courtès" <ludo@gnu.org>, guile-devel@gnu.org
Subject: Re: Mark procedures and LilyPond
Date: Fri, 06 Nov 2015 07:32:51 -0500	[thread overview]
Message-ID: <87io5ftij0.fsf_-_@netris.org> (raw)
In-Reply-To: <87ziyspp5d.fsf@pobox.com> (Andy Wingo's message of "Thu, 05 Nov 2015 14:11:10 +0100")

Andy Wingo <wingo@pobox.com> writes:

> On Thu 05 Nov 2015 11:29, ludo@gnu.org (Ludovic Courtès) writes:
>
>> What we need above all is to address LilyPond’s use case.  I proposed a
>> solution at <http://debbugs.gnu.org/cgi/bugreport.cgi?bug=19883#23> but
>> never understood whether/why it was considered unfit.
>
> I agree with you that the patch there looks reasonable to me too, though
> AFAIU the original code should work just fine too.
>
> There area few things at play.
>
>  (1) A bug related to SMOB finalization and marking that affects
>      LilyPond
>
>  (2) The utility of mark procedures in general
>
>  (3) The suitability of mark procedures for future uses
>
>  (4) Whether we can get by without mark procedures, and if so, how.
>
> For (1) it seems to me that we just have a bug.  A SMOB mark function
> was called on an object after the finalizer.  ****Note**** that having
> the finalizer called doesn't mean that the GC object was collected -- it
> just means it was collectable, perhaps in a clique of objects.
> Finalization being asynchronous with marking it's possible that a clique
> of objects was only half-finalized when a new mark procedure runs.  The
> mark procedure saw an object on which free() was already called -- this
> is possible.

Yes, exactly.

> We should fix Guile so to "null out" the SMOB typecode when the SMOB
> finalizer is called.  If our mark procedure sees a SMOB that has already
> been finalized, it just returns.

Unfortunately, I doubt this will be sufficient for LilyPond.  The small
example case in <http://bugs.gnu.org/19883>, which is apparently
representative of how things are typically done in LilyPond, has
structures like this:

                   __________                    __________
  Objects in      |          |                  |          |
  GC-managed      |  SMOB 1  |                  |  SMOB 2  |
     heap         |__________|                  |__________|
                     |   ^                         |   ^
.....................|...|.........................|...|..........
                   __v___|___      _________     __v___|___
  Objects in      |          |    |   STL   |   |          |
  normal heap     |C++ object|--->|container|-->|C++ object|
  (not scanned    |__________|    |_________|   |__________|
     by GC)


The SMOB finalizers free the associated C++ objects below them.  Now,
suppose that none of the objects above are reachable, so both SMOBs are
queued for finalization.  Now suppose that SMOB 2 is finalized first,
thus freeing the C++ object below it.  Suppose further that we null out
the SMOB 2 typecode.

Now another GC occurs and the marker is called on SMOB 1.  It's typecode
has not yet been nulled, so the user-specified mark procedure is called.
The mark procedure for SMOB 1 iterates over the STL container, and for
each C++ object within, marks the corresponding SMOB via the upward
pointer, in this case SMOB 2.  Although SMOB 2's typecode has been
zeroed out, the discovery of the fact is too late, because the (freed)
C++ object below it has been referenced.

As far as I can tell, this way of doing things depends on the old 1.8 GC
finalization semantics, where all of the finalizers are called before
the mutator resumes execution.

      Mark



  parent reply	other threads:[~2015-11-06 12:32 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-11-04 10:10 Mark procedures Andy Wingo
2015-11-04 12:01 ` Stefan Israelsson Tampe
2015-11-04 17:01 ` Mark procedures, LilyPond, and backward compatibility Mark H Weaver
2015-11-05 10:16   ` Foreign object API Ludovic Courtès
2016-02-01 22:50     ` Foreign objects removed from ‘stable-2.0’ Ludovic Courtès
2015-11-05 14:46   ` Mark procedures, LilyPond, and backward compatibility Andy Wingo
2015-11-05 10:29 ` Mark procedures Ludovic Courtès
2015-11-05 13:11   ` Andy Wingo
2015-11-05 14:17     ` Ludovic Courtès
2015-11-06 12:32     ` Mark H Weaver [this message]
2015-11-06 13:50       ` Mark procedures and LilyPond Ludovic Courtès
2015-11-06 15:05       ` Stefan Monnier
2016-01-24  8:58       ` Hans Åberg
2016-06-20 10:34     ` Mark procedures Andy Wingo
2016-06-20 12:15       ` Ludovic Courtès
2021-05-18 15:46 ` Ephemerons, self-referentality in weak hashtables Christopher Lemmer Webber
2021-06-20 15:01   ` Maxime Devos
2021-06-21 17:15     ` Maxime Devos
2021-09-08 16:18       ` Christine Lemmer-Webber
2021-09-08 20:11         ` Maxime Devos
2021-09-08 20:50           ` Christine Lemmer-Webber

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/guile/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87io5ftij0.fsf_-_@netris.org \
    --to=mhw@netris.org \
    --cc=guile-devel@gnu.org \
    --cc=ludo@gnu.org \
    --cc=wingo@pobox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).