diff options
| author | Keith Packard <keithp@keithp.com> | 2016-11-11 21:11:13 -0800 | 
|---|---|---|
| committer | Keith Packard <keithp@keithp.com> | 2017-02-20 11:16:50 -0800 | 
| commit | 29c890b4599b3bbdbd09a5915ea68a63f4e0a9ac (patch) | |
| tree | 791966151a186d37ba143d7a56f0f3640add54bd /src/lisp/ao_lisp_cons.c | |
| parent | d46ca67f93e9ecbc4d8c051c3fbdead85490b690 (diff) | |
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 <keithp@keithp.com>
Diffstat (limited to 'src/lisp/ao_lisp_cons.c')
| -rw-r--r-- | src/lisp/ao_lisp_cons.c | 23 | 
1 files changed, 17 insertions, 6 deletions
| 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;  } | 
