1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
|
[ This is -*-C-*- ]
This is some other code for marking cons cells, it comes from after the
`case V_Cons' switch in markvalue(). Currently the first case is that
which is actually used.
Note that these can't be plugged straight in anymore, the modifications
to the Lisp data management have seen to that...
-----
/* Attempts to walk though whole lists at a time (since Lisp
lists mainly link from the cdr). */
do {
GC_SET(val);
MARKVAL(VCAR(val));
val = VCDR(val);
} while(val && CONSP(val));
/* Since most lists end in nil, check for this. */
if(val && !NILP(val))
MARKVAL(val);
break;
-----
{
/* Non-recursive marking of chains of cons cells. I ripped this
out of a book and translated it from lisp to C.
Uses less stack than either of the other two algorithms but
doesn't beat the above one by that much. I guess it depends on
how many cons cells have lists hung from their car. */
register VALUE q, n = sym_nil;
loopcar:
q = VCAR(val);
if(q && !GC_MARKEDP(q)) /* track down car */
{
if(!CONSP(q))
MARKVAL(q);
else
{
VCAR(val) = n; /* reverse pointer */
n = val; val = q;
goto loopcar; /* continue down car */
}
}
loopcdr:
GC_SET(val); /* indicate car is done */
q = VCDR(val); /* track down cdr */
if(q && !GC_MARKEDP(q))
{
if(!CONSP(q))
MARKVAL(q);
else
{
VCDR(val) = n; /* reverse pointer */
n = val; val = q;
goto loopcar; /* go down car first */
}
}
loopcons:
if(!n || NILP(n))
break; /* finished marking? */
q = n;
if(GC_MARKEDP(q)) /* was car of this done? */
{
n = VCDR(q);
VCDR(q) = val; /* undo pointer reversal */
val = q;
goto loopcons; /* continue upwards */
}
else
{
GC_SET(q);
n = VCAR(q);
VCAR(q) = val; /* undo pointer reversal */
val = q;
goto loopcdr; /* still have to do cdr */
}
}
/* NOT REACHED */
-----
/* This is the worst method, recursion city! */
GC_SET(val);
MARKVAL(VCAR(val));
MARKVAL(VCDR(val));
break;
|