[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Recent GCPRO removal and copying GC
Recent GCPRO removal and copying GC
Fri, 18 Sep 2015 19:31:22 +0000
Recently, the GCPRO machinery was removed from Emacs 25.
I am concerned this change might make it much harder to switch to a copying garbage collector in the future, or to integrate Emacs with an existing garbage collector of such design.
If I understand things correctly, such a garbage collector must know precisely which stack locations correspond to Lisp objects and which ones don't, while the current Emacs GC simply scans the entire stack for words that look like they might be Lisp objects, and doesn't bother about eliminating false positives.
I have experimented and it was reasonably straightforward to add (pointless) partial copying (of cons cells reachable only by "copyable" stack locations) to the current GC, when using the last revision of Emacs 25 that still had GCPRO. I think that would have been very hard without GCPRO, at least in C.
There is another way of keeping track of which Lisp objects on the stack are in scope, and if that other way can fully replace GCPRO, I consider my concerns moot: we could use C++ constructors/destructors to do the necessary book-keeping. I believe that would also require some somewhat difficile code to properly unregister stack locations when we call longjmp(), and I'm not completely sure it will be possible to perform all the required modifications automatically.
So that's going to be my next experiment.
Of course it is a potentially valid design choice to decide that Emacs will never use a copying garbage collector, but I would disagree with that decision.
I do understand that maintaining the previously existing GCPRO uses is a bit of a headache, since they were disabled by default; on the other hand, the information contained in the GCPRO structures is potentially useful for things other than copying garbage collectors: for example, we could implement Lisp watchpoints by making the corresponding Lisp_Objects point to invalid memory locations, then handling the resulting segfaults.
Strictly, speaking, of course, the information contained in the GCPRO structures is redundant:
1. This variable is on the stack (or in a register)
2. It's a Lisp_Object
3. It has been written to at least once (so doesn't contain an invalid pointer)
4. Its value is potentially used after this function call
(1) and (2) are straightforward to determine for anything that parses C; (3) can be ensured by initializing the variable if it isn't. (4) is hard (impossible, in general) to determine precisely, but GCC's optimization passes are good enough to detect most cases. I believe it should be possible to get GCC to produce the relevant lifetime analysis information, but I don't know precisely how; it might be in the RTL dumps, or it might require some work on GCC.
That means we can write a special preprocessor that turns C code without GCPRO invocations into C code that is guaranteed to perform all the necessary GCPROs, but might include some extra GCPROs and variable initializations that a human programmer could have avoided (on the other hand, it might do better than a human would).
My personal preference is to go back to GCPRO for a limited period until such a preprocessor exists and is expected to work (if we go this way, I'm volunteering to attempt to write it, but can't promise I'll succeed): it will be much easier to test the preprocessor if we still have the GCPRO data around for that.
Declaring it obsolete now and removing it later would also give people working on unusual ports some time to adjust to things. (I've used GCPRO-based GC when briefly attempting to get Emacs working on a weird virtual machine, but that was only because I was too lazy to figure out its stack growth direction; I don't think there's any reason stack-based GC wouldn't work on it.)
- Recent GCPRO removal and copying GC,
Pip Cet <=