mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-30 15:00:21 +02:00
* guardians.c (scm_guardian_zombify): Don't set marks manually ---
use the macros. (Thanks to Michael Livshin.)
This commit is contained in:
parent
6d8500ad76
commit
55b7e0bd82
1 changed files with 33 additions and 12 deletions
|
@ -176,12 +176,17 @@ void
|
||||||
scm_guardian_zombify ()
|
scm_guardian_zombify ()
|
||||||
{
|
{
|
||||||
guardian_t *g;
|
guardian_t *g;
|
||||||
|
|
||||||
|
/* Note that new guardians may be stuck on the end of the live
|
||||||
|
guardian list as we run this loop. As we move unmarked objects
|
||||||
|
to the zombie list and mark them, we may find some guarded
|
||||||
|
guardians. The guardian mark function will stick them on the end
|
||||||
|
of this list, so they'll be processed properly. */
|
||||||
for (g = first_live_guardian; g; g = g->next)
|
for (g = first_live_guardian; g; g = g->next)
|
||||||
{
|
{
|
||||||
/* Loop through the live list and
|
/* Loop through the live list and
|
||||||
1. move unmarked objects to the zombies tconc
|
1. move unmarked objects to the zombies tconc
|
||||||
2. mark the live tconc.
|
2. mark the live tconc. */
|
||||||
*/
|
|
||||||
SCM tconc_tail = g->live.tail;
|
SCM tconc_tail = g->live.tail;
|
||||||
SCM prev_pair = SCM_BOOL_F;
|
SCM prev_pair = SCM_BOOL_F;
|
||||||
SCM pair = g->live.head;
|
SCM pair = g->live.head;
|
||||||
|
@ -189,6 +194,21 @@ scm_guardian_zombify ()
|
||||||
{
|
{
|
||||||
SCM next_pair = SCM_CDR (pair);
|
SCM next_pair = SCM_CDR (pair);
|
||||||
|
|
||||||
|
/* Since next_pair is never assigned to, and since pair is
|
||||||
|
always set to next_pair at the end of the loop, we know
|
||||||
|
that this loop always reaches every pair in the tconc
|
||||||
|
once, except the tail.
|
||||||
|
|
||||||
|
At each iteration, we either throw the pair out of the
|
||||||
|
live list, or we mark it. And when we edit a pair's CDR,
|
||||||
|
we make sure to preserve its mark bit. So when this loop
|
||||||
|
terminates, all pairs left in the live tconc (except the
|
||||||
|
tail) have been marked.
|
||||||
|
|
||||||
|
Whenever we throw out a pair, we always relink the tconc,
|
||||||
|
so the tconc list structure is valid at the end of every
|
||||||
|
iteration. */
|
||||||
|
|
||||||
if (SCM_NMARKEDP (SCM_CAR (pair)))
|
if (SCM_NMARKEDP (SCM_CAR (pair)))
|
||||||
{
|
{
|
||||||
/* got you, zombie! */
|
/* got you, zombie! */
|
||||||
|
@ -197,28 +217,29 @@ scm_guardian_zombify ()
|
||||||
if (SCM_FALSEP (prev_pair))
|
if (SCM_FALSEP (prev_pair))
|
||||||
g->live.head = next_pair;
|
g->live.head = next_pair;
|
||||||
else
|
else
|
||||||
/* mark previous pair */
|
{
|
||||||
SCM_SETCDR (prev_pair, next_pair | 1);
|
SCM_SETCDR (prev_pair, next_pair);
|
||||||
|
/* Don't lose the mark bit! */
|
||||||
|
SCM_SETGCMARK (prev_pair);
|
||||||
|
}
|
||||||
|
|
||||||
/* to the zombie list! */
|
/* to the zombie list! */
|
||||||
TCONC_IN (g->zombies, SCM_CAR (pair), pair);
|
TCONC_IN (g->zombies, SCM_CAR (pair), pair);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (SCM_NFALSEP (prev_pair))
|
SCM_SETGCMARK (pair);
|
||||||
/* mark previous pair */
|
|
||||||
SCM_SETCDR (prev_pair, pair | 1);
|
|
||||||
prev_pair = pair;
|
prev_pair = pair;
|
||||||
}
|
}
|
||||||
|
|
||||||
pair = next_pair;
|
pair = next_pair;
|
||||||
}
|
}
|
||||||
if (SCM_NFALSEP (prev_pair))
|
|
||||||
/* mark previous pair */
|
|
||||||
SCM_SETCDR (prev_pair, pair | 1);
|
|
||||||
/* mark live list tail */
|
|
||||||
SCM_SETOR_CDR (tconc_tail, 1);
|
|
||||||
|
|
||||||
|
/* Mark the tconc's tail cell. All the other pairs in the tconc
|
||||||
|
are already marked. */
|
||||||
|
SCM_SETGCMARK (tconc_tail);
|
||||||
|
|
||||||
|
/* Bring the zombies back from the dead. */
|
||||||
scm_gc_mark (g->zombies.head);
|
scm_gc_mark (g->zombies.head);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue