[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Conservative GC isn't safe
From: |
Ken Raeburn |
Subject: |
Re: Conservative GC isn't safe |
Date: |
Mon, 28 Nov 2016 04:36:56 -0500 |
On Nov 27, 2016, at 11:15, Paul Eggert <address@hidden> wrote:
>
> Ken Raeburn wrote:
>>> > Indeed. Hans Boehm's done a fair bit of research in this issue,
>>> > including discussing the underlying assumptions and arguing that
>>> > compilers should (and usually do) guarantee those assumptions.
>
>> I’d be surprised if that held reliably when the last use of a Lisp_Object in
>> some function extracts an object pointer and then never references the
>> Lisp_Object as such ever again.
>
> That's not a problem for Emacs, since the Emacs GC marks the object either
> way.
Ah, sorry, I misunderstood the case Daniel was describing. Yes, the case I was
thinking of is in fact handled; stack slots holding either Lisp_Object values
or pointers to the start of the Lisp data structures will be fine.
But we do use interior pointers sometimes; looking at Fsubstring’s handling of
a vector object:
else
res = Fvector (ito - ifrom, aref_addr (string, ifrom));
return res;
}
… here we pass Fvector a pointer to somewhere within the “contents” array of
the vector passed as argument “string”; it’s neither the Lisp_Object value, nor
the start of the allocated structure. Now, I don’t think this is a case that
can trigger GC at the critical time. But clearly we’ve got at least one case
where we keep an interior pointer and — locally, at least; the caller could be
another matter — don’t keep a live handle on the object itself.
And the compiler can do it too. For example, if we did something like this:
DEFUN (“frob-array-elts", Ffrob_array_elts, Sfrob_array_elts, 1, 1, 0,
doc: /* Blah */ )
(Lisp_Object obj)
{
int i;
for (i = 0; i < 30; i += 3)
{
frob (AREF (obj, i));
}
return Qnil;
}
I tried compiling this (“gcc version 4.9.2 (Debian 4.9.2-10)” on x86-64). The
generated code computes obj+3 (vector tag is 5, contents array starts at offset
8) and obj+0xf3 (end of the iteration), and overwrites the register containing
the original “obj” value with the argument to be passed to “frob”.
If, in this case, “frob” were something that could trigger GC, then stack
scanning would not see “obj”, at least not in this stack frame. And if the
caller is doing something like:
Ffrob_array_elts (get_vector_of_stuff ());
then the caller needn’t retain any other references to “obj” either.
Ken
- Re: Conservative GC isn't safe, (continued)
- Re: Conservative GC isn't safe, Ken Raeburn, 2016/11/27
- Re: Conservative GC isn't safe, Eli Zaretskii, 2016/11/27
- Re: Conservative GC isn't safe, Ken Raeburn, 2016/11/28
- Re: Conservative GC isn't safe, Eli Zaretskii, 2016/11/28
- Re: Conservative GC isn't safe, Paul Eggert, 2016/11/27
- Re: Conservative GC isn't safe,
Ken Raeburn <=
- Re: Conservative GC isn't safe, Eli Zaretskii, 2016/11/28
- Re: Conservative GC isn't safe, Björn Lindqvist, 2016/11/28
- Re: Conservative GC isn't safe, Stefan Monnier, 2016/11/28
- Re: Conservative GC isn't safe, Eli Zaretskii, 2016/11/28
- Re: Conservative GC isn't safe, Stefan Monnier, 2016/11/28
- Re: Conservative GC isn't safe, Eli Zaretskii, 2016/11/28
- Re: Conservative GC isn't safe, Stefan Monnier, 2016/11/28
- Re: Conservative GC isn't safe, Ken Raeburn, 2016/11/28
- Re: Conservative GC isn't safe, Eli Zaretskii, 2016/11/28
- Re: Conservative GC isn't safe, Ken Raeburn, 2016/11/29