From c8d2b9acf4b118f36a114de2af4db42ae04426ed Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 11 Nov 2016 21:11:13 -0800 Subject: altos/lisp: Make sure memmove only happens once per object. Other GC fixes The memmove may be overlapping, so make sure it happens only once by just checking whether move_size has been set, rather than looking at ao_lisp_moving; that doesn't get set when moving a noted cons as that still needs to be walked at a later time. Fix up the various looping move functions to all use the same pattern. Atom was busted. Signed-off-by: Keith Packard --- src/lisp/ao_lisp_cons.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) (limited to 'src/lisp/ao_lisp_cons.c') diff --git a/src/lisp/ao_lisp_cons.c b/src/lisp/ao_lisp_cons.c index b75ffaa0..c7d8382f 100644 --- a/src/lisp/ao_lisp_cons.c +++ b/src/lisp/ao_lisp_cons.c @@ -49,6 +49,8 @@ static void cons_move(void *addr) (void) ao_lisp_poly_move(&cons->car, 1); cdr = ao_lisp_poly_cons(cons->cdr); + if (!cdr) + break; ret = ao_lisp_move_memory((void **) &cdr, sizeof (struct ao_lisp_cons)); if (cdr != ao_lisp_poly_cons(cons->cdr)) cons->cdr = ao_lisp_cons_poly(cdr); @@ -64,20 +66,29 @@ const struct ao_lisp_type ao_lisp_cons_type = { .move = cons_move, }; +static ao_poly cons_car; +static struct ao_lisp_cons *cons_cdr; +static int been_here; + struct ao_lisp_cons * ao_lisp_cons_cons(ao_poly car, struct ao_lisp_cons *cdr) { struct ao_lisp_cons *cons; - ao_lisp_root_add(&ao_lisp_cons_type, &cdr); - ao_lisp_root_poly_add(&car); + if (!been_here) { + ao_lisp_root_add(&ao_lisp_cons_type, &cons_cdr); + ao_lisp_root_poly_add(&cons_car); + been_here = 1; + } + cons_car = car; + cons_cdr = cdr; cons = ao_lisp_alloc(sizeof (struct ao_lisp_cons)); - ao_lisp_root_clear(&car); - ao_lisp_root_clear(&cdr); if (!cons) return NULL; - cons->car = car; - cons->cdr = ao_lisp_cons_poly(cdr); + cons->car = cons_car; + cons->cdr = ao_lisp_cons_poly(cons_cdr); + cons_car = AO_LISP_NIL; + cons_cdr = NULL; return cons; } -- cgit v1.2.3