Next: Garbage Collection - Step by Step, Previous: Garbage Collection, Up: Allocation of Objects in SXEmacs Lisp [Contents][Index]
GCPROingGCPROing 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()d or
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 staticpro() (in the 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.
Note that obarray is one of the staticpro()d things.
Therefore, all functions and variables get marked through this.
specpdl stack.
GCPRO.
Marking with 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.
UNGCPRO anything that’s GCPROed, and you
must not UNGCPRO if 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 gcpro local variables, with the
variable ‘gcprolist’ pointing to the head of the list and the nth
local gcpro variable pointing to the first gcpro variable
in the next enclosing stack frame. Each GCPROed thing is an
lvalue, and the struct gcpro local variable contains a pointer to
this lvalue. This is why things will mess up badly if you don’t pair up
the GCPROs and UNGCPROs—you will end up with
gcprolists containing pointers to struct gcpros or local
Lisp_Object variables in no-longer-active stack frames.
struct gcpro to
protect a contiguous array of any number of values, rather than
just a single lvalue. To effect this, call GCPROn as usual on
the first object in the array and then set gcpron.nvars.
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.
GCPRO’s, use NGCPROn
(along with 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 GCPRO any 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
protected.
So, if you create any Lisp objects (remember, this happens in all sorts
of circumstances, e.g. with Fcons(), etc.), you are responsible
for 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 GCPROing.
Feval, or
whenever a QUIT can occur where execution can continue past
this. (Remember, this is almost anywhere.)
GCPRO, you should GCPRO.
GCPROing something that is uninitialized. If you have
any shade of doubt about this, initialize all your variables to Qnil.
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. nconc2(), Fsignal()), break the “caller protects”
law and go ahead and GCPRO their 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-collect or 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 prog1
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.
Next: Garbage Collection - Step by Step, Previous: Garbage Collection, Up: Allocation of Objects in SXEmacs Lisp [Contents][Index]