Next: Garbage Collection - Step by Step, Previous: Garbage Collection, Up: Allocation of Objects in SXEmacs Lisp [Contents][Index]
GCPRO
ingGCPRO
ing 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 GCPRO
ed, and you
must not UNGCPRO
if you haven’t GCPRO
ed. Getting
either of these wrong will lead to crashes, often in completely random
places unrelated to where the problem lies.
GCPRO
s
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 GCPRO
ed 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 GCPRO
s and UNGCPRO
s—you will end up with
gcprolist
s containing pointers to struct gcpro
s 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.
GCPRO
s
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.
GCPRO
s.
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 GCPRO
ing 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 GCPRO
ing.
Feval
, or
whenever a QUIT can occur where execution can continue past
this. (Remember, this is almost anywhere.)
GCPRO
, you should GCPRO
.
GCPRO
ing 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
GCPRO
ing 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
GCPRO
ing 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 GCPRO
ing, 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]