GCPROing is one of the ugliest and trickiest parts of Emacs
internals. The basic idea is that whenever garbage collection
occurs, all in-use objects must be reachable somehow or
other from one of the roots of accessibility. The roots
of accessibility are:
staticpro_nodump()ed. This is used for any global C variables that hold Lisp objects. A call to
staticpro()happens implicitly as a result of any symbols declared with
defsymbol()and any variables declared with
DEFVAR_FOO(). You need to explicitly call
vars_of_foo()method of a module) for other global C variables holding Lisp objects. (This typically includes internal lists and such things.). Use
staticpro_nodump()only in the rare cases when you do not want the pointed variable to be saved at dump time but rather recompute it at startup.
obarray is one of the
Therefore, all functions and variables get marked through this.
GCPRO is necessary because some C functions (quite
a lot, in fact), allocate objects during their operation. Quite
frequently, there will be no other pointer to the object while the
function is running, and if a garbage collection occurs and the object
needs to be referenced again, bad things will happen. The solution is
to mark those objects with
GCPRO. Unfortunately this is easy to
forget, and there is basically no way around this problem. Here are
some rules, though:
GCPROn, there have to be declarations of
struct gcpro gcpro1, gcpro2, etc.
GCPROed, and you must not
UNGCPROif you haven’t
GCPROed. Getting either of these wrong will lead to crashes, often in completely random places unrelated to where the problem lies.
GCPROs are chained through the
struct gcprolocal variables, with the variable ‘gcprolist’ pointing to the head of the list and the nth local
gcprovariable pointing to the first
gcprovariable in the next enclosing stack frame. Each
GCPROed thing is an lvalue, and the
struct gcprolocal variable contains a pointer to this lvalue. This is why things will mess up badly if you don’t pair up the
UNGCPROs—you will end up with
gcprolists containing pointers to
struct gcpros or local
Lisp_Objectvariables in no-longer-active stack frames.
struct gcproto protect a contiguous array of any number of values, rather than just a single lvalue. To effect this, call
GCPROnas usual on the first object in the array and then set
XSTRING_DATA()is liable to change at any time, and you should never keep it around past any function call, or pass it as an argument to any function that might cause a garbage collection. This is why a number of functions accept either a “non-relocatable”
char *pointer or a relocatable Lisp string, and only access the Lisp string’s data at the very last minute. In some cases, you may end up having to
alloca()some space and copy the string’s data into it.
struct gcpro ngcpro1, ngcpro2, etc.),
NNGCPROn, etc. This avoids compiler warnings about shadowed locals.
GCPROs rather than too few. The extra cycles spent on this are almost never going to make a whit of difference in the speed of anything.
GCPROs. That is, you should not have to explicitly
GCPROany Lisp objects that are passed in as parameters.
One exception from this rule is if you ever plan to change the parameter
value, and store a new object in it. In that case, you must
GCPRO the parameter, because otherwise the new object will not be
So, if you create any Lisp objects (remember, this happens in all sorts
of circumstances, e.g. with
Fcons(), etc.), you are responsible
GCPROing them, unless you are absolutely sure that
there’s no possibility that a garbage-collection can occur while you
need to use the object. Even then, consider
Feval, or whenever a QUIT can occur where execution can continue past this. (Remember, this is almost anywhere.)
GCPRO, you should
GCPROing something that is uninitialized. If you have any shade of doubt about this, initialize all your variables to
Fcons()in the argument to another function. By the “caller protects” law, you should be
GCPROing the newly-created cons, but you aren’t. A certain number of functions that are commonly called on freshly created stuff (e.g.
Fsignal()), break the “caller protects” law and go ahead and
GCPROtheir arguments so as to simplify things, but make sure and check if it’s OK whenever doing something like this.
GCPRO! Bugs resulting from insufficient
GCPROing are intermittent and extremely difficult to track down, often showing up in crashes inside of
garbage-collector in weirdly corrupted objects or even in incorrect values in a totally different section of code.
If you don’t understand whether to
GCPRO in a particular
instance, ask on the mailing lists. A general hint is that
is the canonical example.
Given the extremely error-prone nature of the
GCPRO scheme, and
the difficulties in tracking down, it should be considered a deficiency
in the SXEmacs code. A solution to this problem would involve
implementing so-called conservative garbage collection for the C
stack. That involves looking through all of stack memory and treating
anything that looks like a reference to an object as a reference. This
will result in a few objects not getting collected when they should, but
it obviates the need for
GCPROing, and allows garbage collection
to happen at any point at all, such as during object allocation.