From 8f57c0761eaf1f10493fd52118d309eb69491464 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 5 Nov 2016 14:51:58 -0700 Subject: altos/lisp: Change GC move API Pass reference to move API so it can change the values in-place, then let it return '1' when the underlying object has already been moved to shorten GC times. Signed-off-by: Keith Packard --- src/lisp/ao_lisp_prim.c | 44 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 8 deletions(-) (limited to 'src/lisp/ao_lisp_prim.c') diff --git a/src/lisp/ao_lisp_prim.c b/src/lisp/ao_lisp_prim.c index e9367553..7f02505d 100644 --- a/src/lisp/ao_lisp_prim.c +++ b/src/lisp/ao_lisp_prim.c @@ -14,6 +14,12 @@ #include "ao_lisp.h" +#if 0 +#define DBG(...) printf (__VA_ARGS__) +#else +#define DBG(...) +#endif + static void (*const ao_lisp_print_funcs[AO_LISP_NUM_TYPE])(ao_poly) = { [AO_LISP_CONS] = ao_lisp_cons_print, [AO_LISP_STRING] = ao_lisp_string_print, @@ -33,30 +39,52 @@ ao_lisp_poly_print(ao_poly p) static const struct ao_lisp_type const *ao_lisp_types[AO_LISP_NUM_TYPE] = { [AO_LISP_CONS] = &ao_lisp_cons_type, + [AO_LISP_INT] = NULL, [AO_LISP_STRING] = &ao_lisp_string_type, + [AO_LISP_OTHER] = (void *) 0x1, [AO_LISP_ATOM] = &ao_lisp_atom_type, [AO_LISP_BUILTIN] = &ao_lisp_builtin_type, + [AO_LISP_FRAME] = &ao_lisp_frame_type, }; -void +int ao_lisp_poly_mark(ao_poly p) { const struct ao_lisp_type *lisp_type = ao_lisp_types[ao_lisp_poly_type(p)]; if (lisp_type) - ao_lisp_mark(lisp_type, ao_lisp_ref(p)); + return ao_lisp_mark(lisp_type, ao_lisp_ref(p)); + return 1; } -ao_poly -ao_lisp_poly_move(ao_poly p) +int +ao_lisp_poly_move(ao_poly *ref) { - uint8_t type = p & AO_LISP_TYPE_MASK; + uint8_t type; + ao_poly p = *ref; const struct ao_lisp_type *lisp_type; + int ret; + void *addr; + + if (!p) + return 1; + type = p & AO_LISP_TYPE_MASK; if (type == AO_LISP_OTHER) type = ao_lisp_other_type(ao_lisp_move_map(ao_lisp_poly_other(p))); + if (type >= AO_LISP_NUM_TYPE) + abort(); + lisp_type = ao_lisp_types[type]; - if (lisp_type) - p = ao_lisp_poly(ao_lisp_move(lisp_type, ao_lisp_ref(p)), p & AO_LISP_TYPE_MASK); - return p; + if (!lisp_type) + return 1; + addr = ao_lisp_ref(p); + ret = ao_lisp_move(lisp_type, &addr); + if (addr != ao_lisp_ref(p)) { + ao_poly np = ao_lisp_poly(addr, p & AO_LISP_TYPE_MASK); + DBG("poly %d moved %04x -> %04x\n", + type, p, np); + *ref = np; + } + return ret; } -- cgit v1.2.3