Subject: bug#37006: 27.0.50; garbage collection not happening after 26de2d42

From: Eli Zaretskii <[email-masked]>
Date: Wed, 14 Aug 2019 19:06:49 +0300

> Cc: [email-masked], [email-masked], [email-masked]
> From: Paul Eggert <[email-masked]>
> Date: Tue, 13 Aug 2019 12:32:24 -0700
> 
> > OBJECT_CT_MAX should have the value EMACS_INT_MAX.
> 
> Not if EMACS_INT_MAX < INTPTR_MAX, since object counts might overflow in that 
> case. However, I take your point that consing_until_gc can easily be made to 
> hold any fixnum value, so I installed the first attached patch. This is to some 
> extent overkill, since these variables should not be assumed to have this sort 
> of fine-grained control, but the change is tiny so should be fine.

Thanks.

However, I'd rather we don't invent new data types unless really
necessary.  I think we should simply use EMACS_INT (see below), but
even if we end up using intptr_max, let's just use that directly, not
introduce yet another type which we will have to look up every time we
read this code.  And likewise with the corresponding _MAX value.
Using a non-standard data type makes the code harder to read.

> Come to think of it, the limit should be INTMAX_MAX not EMACS_INT_MAX since 
> gc-cons-threshold could exceed EMACS_INT_MAX.

Sorry, I don't think I follow.  gc-cons-threshold is a Lisp integer, a
fixnum, so it cannot exceed EMACS_INT_MAX, I think.

> The idea would be to have a type that is like struct Lisp_Objfwd but with an 
> extra member, a function to be called whenever the variable is accessed. (Or 
> perhaps two extra members, a getter and a setter.) This could be useful for 
> other builtin vars, I suspect.

Ah, okay.  Can we use for this purpose the existing trapped_write
field of Lisp_Symbol that is the base for implementing Lisp watcher
functions?

> > How else would you succeed in reacting to the change "soon enough"?
> 
> There are other possibilities. We could have a timer, for example.

I don't think timers are reliable enough, as they can be deferred for
arbitrarily long time interval by some Lisp that takes a long time to
finish.

> >>> We must also notice the memory-full condition there.
> >>
> >> memory_full already does that, no? It sets consing_until_gc.
> > 
> > It sets it to a positive value, so no immediate GC will follow.  The
> > original code was setting the threshold to a very small value, so GC
> > would happen immediately.
> 
> Are you talking about the change in commit 
> 2019-07-20T02:40:[email-masked] 
> (26de2d42d0460c5b193456950a568cb04a29dc00)? If so, I'm not quite following, as 
> the old code did not GC until consing_since_gc > memory_full_cons_threshold. I 
> expect that the idea was to not thrash doing GCs when memory is full.

With the old code, whenever memory-full was non-nil, and
consing_since_gc was more than the size of cons_block (about 1KB on my
system), the very next maybe_gc call would actually trigger GC.  With
the new code, no matter how much consing happened before memory-full
became non-nil, we still need to cons 1KB worth of objects before GC
happens.  This 1KB might be critical when we are out of memory.

> Immediate-GC might cause GC thrashing, no?

Not sure how, can you elaborate?