We can now describe exactly what happens after the invocation takes place.
gc_in_progress), when the garbage collection is somehow forbidden (
gc_currently_forbidden), when we are currently displaying something (
in_display) or when we are preparing for the armageddon of the whole system (
cursor_changedtake care of that.
gc_currently_forbiddenmust be restored after the garbage collection, no matter what happens during the process. We accomplish this by
record_unwind_protecting the suitable function
restore_gc_inhibittogether with the current value of
clear_event_resource) and for specifiers (
mark_objectis called for each root individually to go out from there to mark all reachable objects. All roots that are traversed are shown in their processed order:
staticproin the dynarr
staticpros. See Adding Global Lisp Variables.
gcprolist. See GCPROing.
symboland old values
old_values) that are bound during the evaluation by the Lisp engine. They are stored in
specbindingstructs pushed on a stack called
specpdl. See Dynamic Binding; The specbinding Stack; Unwind-Protects.
catchtaginserted in the list
catchlist. Their tag (
tag) and value (
valfields are freshly created objects and therefore have to be marked. See Catch and Throw.
backtraceon the call stack of the Lisp engine (
backtrace_list). The unique parts that have to be marked are the fields for each function (
function) and all their arguments (
args). See Evaluation.
Because there are complicated dependency rules about when and what to
mark while processing weak hash tables, the standard
method is only active if it is marking non-weak hash tables. As soon as
a weak component is in the table, the hash table entries are ignored
while marking. Instead their marking is done each separately by the
finish_marking_weak_hash_tables. This function iterates
over each hash table entry
hentries for each weak hash table in
Vall_weak_hash_tables. Depending on the type of a table, the
appropriate action is performed.
If a table is acting as
HASH_TABLE_KEY_WEAK, and a key already marked,
everything reachable from the
value component is marked. If it is
acting as a
HASH_TABLE_VALUE_WEAK and the value component is
already marked, the marking starts beginning only from the
If it is a
HASH_TABLE_KEY_CAR_WEAK and the car
of the key entry is already marked, we mark both the
Finally, if the table is of the type
and the car of the value components is already marked, again both the
key and the
value components get marked.
Again, there are lists with comparable properties called weak
lists. There exist different peculiarities of their types called
value-assoc. You can find further details about them in the
description to the function
make-weak-list. The scheme of their
marking is similar: all weak lists are listed in
therefore we iterate over them. The marking is advanced until we hit an
already marked pair. Then we know that during a former run all
the rest has been marked completely. Again, depending on the special
type of the weak list, our jobs differ. If it is a
and the elem is marked, we mark the
cons part. If it is a
WEAK_LIST_ASSOC and not a pair or a pair with both marked car and
cdr, we mark the
cons and the
elem. If it is a
WEAK_LIST_KEY_ASSOC and not a pair or a pair with a marked car of
the elem, we mark the
cons and the
elem. Finally, if it is
WEAK_LIST_VALUE_ASSOC and not a pair or a pair with a marked
cdr of the elem, we mark both the
cons and the
Since, by marking objects in reach from weak hash tables and weak lists, other objects could get marked, this perhaps implies further marking of other weak objects, both finishing functions are redone as long as yet unmarked objects get freshly marked.
prune_weak_hash_tables does the job for weak hash
tables. Totally unmarked hash tables are removed from the list
Vall_weak_hash_tables. The other ones are treated more carefully
by scanning over all entries and removing one as soon as one of
value is unmarked.
The same idea applies to the weak lists. It is accomplished by
prune_weak_lists: An unmarked list is pruned from
Vall_weak_lists immediately. A marked list is treated more
carefully by going over it and removing just the unmarked pairs.
prune_specifierschecks all listed specifiers held in
Vall_specifiersand removes the ones from the lists that are unmarked.
Vall_syntax_tables. The function
prune_syntax_tableswalks through it and unlinks the tables that are unmarked.
gc_sweepwhich holds the predominance.
consing_since_gc- the counter of the created cells since the last garbage collection - is set back to 0, and
gc_inhibitis restored to the former value by unwinding the stack.
breathing_space. If nothing more is left, we create a new reserve and exit.