GNU bug report logs - #77338
feature/igc: when can we run finalizers?

Previous Next

Package: emacs;

Reported by: Pip Cet <pipcet <at> protonmail.com>

Date: Fri, 28 Mar 2025 15:04:02 UTC

Severity: normal

To reply to this bug, email your comments to 77338 AT debbugs.gnu.org.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#77338; Package emacs. (Fri, 28 Mar 2025 15:04:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Pip Cet <pipcet <at> protonmail.com>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Fri, 28 Mar 2025 15:04:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Pip Cet <pipcet <at> protonmail.com>
To: bug-gnu-emacs <at> gnu.org
Subject: feature/igc: when can we run finalizers?
Date: Fri, 28 Mar 2025 15:03:39 +0000
In https://debbugs.gnu.org/cgi/bugreport.cgi?bug=77325#14, Daniel
writes:

> IGC does GC all the time --- but it's not observable because we pump
> messages from the GC only at dedicated points and run GC hooks only in
> response to these messages. however, notice that on the IGC branch that
> we pump GC messages, including finalizer callbacks, on the allocation
> path for, e.g. various pseudovectors.  That'll cause Lisp to run where
> it wouldn't have before. Is that going to be a problem?  ISTM we can
> either pump messages in maybe_quit() or just rely on igc_on_idle().

That is indeed a bug and one which actually caused a crash for me.  It's
related to changing the new marker structure to use finalizers rather
than attempting to unchain markers in a finalizer rather than doing so
in the fix method.

The problem is that bignums need to be eagerly finalized or we'll run
out of memory running the pidigits benchmark.  I'm not sure whether
there are other objects which also allocate memory that needs to be
freed for correctness.

Another problem is that I'm not sure who uses Lisp finalizers and
whether the slightly weaker semantics of MPS finalizers suffice for
them: IIUC, MPS queues a finalizer when it discovers an object is no
longer reachable except through weak references, and doesn't unqueue it
even if a weak reference is strengthened again (maphash can do this).

So a finalizer can run for an object that actually survived.  Is that
ever acceptable?  Can we prevent it?





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#77338; Package emacs. (Tue, 20 May 2025 16:05:02 GMT) Full text and rfc822 format available.

Message #8 received at 77338 <at> debbugs.gnu.org (full text, mbox):

From: Pip Cet <pipcet <at> protonmail.com>
To: 77338 <at> debbugs.gnu.org
Subject: Re: bug#77338: feature/igc: when can we run finalizers?
Date: Tue, 20 May 2025 16:04:08 +0000
"Pip Cet via \"Bug reports for GNU Emacs, the Swiss army knife of text editors\"" <bug-gnu-emacs <at> gnu.org> writes:

> In https://debbugs.gnu.org/cgi/bugreport.cgi?bug=77325#14, Daniel
> writes:
>
>> IGC does GC all the time --- but it's not observable because we pump
>> messages from the GC only at dedicated points and run GC hooks only in
>> response to these messages. however, notice that on the IGC branch that
>> we pump GC messages, including finalizer callbacks, on the allocation
>> path for, e.g. various pseudovectors.  That'll cause Lisp to run where
>> it wouldn't have before. Is that going to be a problem?  ISTM we can
>> either pump messages in maybe_quit() or just rely on igc_on_idle().
>
> That is indeed a bug and one which actually caused a crash for me.  It's
> related to changing the new marker structure to use finalizers rather
> than attempting to unchain markers in a finalizer rather than doing so
> in the fix method.
>
> The problem is that bignums need to be eagerly finalized or we'll run
> out of memory running the pidigits benchmark.  I'm not sure whether
> there are other objects which also allocate memory that needs to be
> freed for correctness.
>
> Another problem is that I'm not sure who uses Lisp finalizers and
> whether the slightly weaker semantics of MPS finalizers suffice for
> them: IIUC, MPS queues a finalizer when it discovers an object is no
> longer reachable except through weak references, and doesn't unqueue it
> even if a weak reference is strengthened again (maphash can do this).

Some investigation revealed that the old GC's behavior for finalizers is
even more unusual than that: a finalizer reachable only through weak
references will be run (correctly) and left in the weak hash table it
was found in (somewhat confusingly, but perhaps unavoidably).  However,
using a finalizer as a value in a weak-key hash table has the same
effect!

(setq h (make-hash-table :weakness 'key))
(puthash t (make-finalizer (lambda () (message "finalized"))) h)
(garbage-collect)

will run the finalizer, even though it never becomes unreachable.

> So a finalizer can run for an object that actually survived.  Is that
> ever acceptable?  Can we prevent it?

If the current GC's behavior is acceptable, pretty much everything MPS
can do must be, too.

Pip





This bug report was last modified 25 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.