Subject: Re: bug#75322: SAFE_ALLOCA assumed to root Lisp_Objects/SSDATA(string)

From: Pip Cet <[email-masked]>
Date: Sun, 05 Jan 2025 09:47:06 +0000

"Eli Zaretskii" <[email-masked]> writes:
>> >> >> > The below is indeed unsafe:
>> >> >> >
>> >> >> >   char *p = SDATA (unmarked);
>> >> >> >   ... trigger GC here ...
>> >> >> >   puts (p);
>> >> >>
>> >> >> Right now, that's safe for MPS, but not for the old GC, correct?
>> >> >
>> >> > If GC moves string data, then it is not safe, period.  Does MPS move
>> >> > string data?
>> >>
>> >> MPS does not move string data if there is a stack variable pointing to
>> >> it.  It does in other cases.  This is why it's safe for MPS.  The old
>> >> GC, IIUC, is less forgiving.
>> >
>> > The conclusion is that the above is NOT safe, because in some cases
>> > the data could move.  Which was what I said from the get-go.
>>
>> The conclusion is incorrect.  The code is safe if MPS is in use, and we
>> rely on that.
>
> No, we do NOT, and should NOT, rely on that!

We do, we should, and we will continue doing so.

> Because you yourself say above that MPS will move the string data in
> some cases.

Not in this case!

>> The idea behind MPS is that you write code as above, which is safe when
>> MPS is in use, rather than attempting to avoid GC, which is fragile at
>> best (see call_process) and impossible in multi-threaded systems.
>
> I don't suggest to avoid GC.  I suggest that where GC _can_ happen, we
> must reinitialize the pointer to string data after GC.

That suggestion is incorrect.  MPS GC can and does happen while we have
SDATA pointers on the stack, and we rely on it to keep those valid.  We
need not reinitialize anything after MPS GC, and we can't do so because
we don't know when and how we are interrupted for MPS GC.

IOW, MPS treats SDATA point the same way it treats Lisp_Objects. That
isn't the problem here.  The problem is that like Lisp_Objects, SDATA
pointers cannot be moved to xmalloc'd memory and retain their validity.

As long as you think MPS requires us to avoid GC in this case (this is
implied by "we must do this or that after GC"), your understanding of
how scratch/igc uses MPS is fundamentally incorrect.

Pip