mirror of
https://github.com/ashinn/chibi-scheme.git
synced 2025-05-21 22:59:16 +02:00
don't blow the stack during mark except in pathological cases
(should still implement D/S/W for those cases)
This commit is contained in:
parent
d2e520c1ec
commit
47a0656f5c
1 changed files with 11 additions and 6 deletions
17
gc.c
17
gc.c
|
@ -133,8 +133,8 @@ int sexp_valid_object_p (sexp ctx, sexp x) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void sexp_mark (sexp ctx, sexp x) {
|
void sexp_mark (sexp ctx, sexp x) {
|
||||||
sexp_sint_t i, len;
|
sexp_sint_t len;
|
||||||
sexp t, *p;
|
sexp t, *p, *q;
|
||||||
struct sexp_gc_var_t *saves;
|
struct sexp_gc_var_t *saves;
|
||||||
loop:
|
loop:
|
||||||
if (!x || !sexp_pointerp(x) || !sexp_valid_object_p(ctx, x) || sexp_markedp(x))
|
if (!x || !sexp_pointerp(x) || !sexp_valid_object_p(ctx, x) || sexp_markedp(x))
|
||||||
|
@ -144,12 +144,17 @@ void sexp_mark (sexp ctx, sexp x) {
|
||||||
for (saves=sexp_context_saves(x); saves; saves=saves->next)
|
for (saves=sexp_context_saves(x); saves; saves=saves->next)
|
||||||
if (saves->var) sexp_mark(ctx, *(saves->var));
|
if (saves->var) sexp_mark(ctx, *(saves->var));
|
||||||
t = sexp_object_type(ctx, x);
|
t = sexp_object_type(ctx, x);
|
||||||
p = (sexp*) (((char*)x) + sexp_type_field_base(t));
|
|
||||||
len = sexp_type_num_slots_of_object(t, x) - 1;
|
len = sexp_type_num_slots_of_object(t, x) - 1;
|
||||||
if (len >= 0) {
|
if (len >= 0) {
|
||||||
for (i=0; i<len; i++)
|
p = (sexp*) (((char*)x) + sexp_type_field_base(t));
|
||||||
sexp_mark(ctx, p[i]);
|
q = p + len;
|
||||||
x = p[len];
|
while (p < q && ! (*q && sexp_pointerp(*q)))
|
||||||
|
q--; /* skip trailing immediates */
|
||||||
|
while (p < q && *q == q[-1])
|
||||||
|
q--; /* skip trailing duplicates */
|
||||||
|
while (p < q)
|
||||||
|
sexp_mark(ctx, *p++);
|
||||||
|
x = *p;
|
||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue