+static int
+busy_object(uint8_t *tag, void *addr) {
+ int base;
+
+ if (!addr)
+ return 1;
+
+ if ((uint8_t *) addr < ao_lisp_pool || ao_lisp_pool + AO_LISP_POOL <= (uint8_t*) addr)
+ return 1;
+
+ base = (uint8_t *) addr - ao_lisp_pool;
+ base = limit(base);
+ if (busy(tag, base))
+ return 1;
+ return 0;
+}
+
+static void
+note_cons(void *addr)
+{
+ if (AO_LISP_IS_POOL(addr)) {
+ int offset = (uint8_t *) addr - ao_lisp_pool;
+ MDBG_MOVE("note cons %d\n", MDBG_OFFSET(addr));
+ ao_lisp_cons_noted = 1;
+ mark(ao_lisp_cons_note, offset);
+ }
+}
+
+/*
+ * Walk all referenced objects calling functions on each one
+ */
+
+static void
+walk(uint8_t *tag,
+ int (*visit_addr)(const struct ao_lisp_type *type, void **addr),
+ int (*visit_poly)(ao_poly *p, uint8_t do_note_cons))
+{
+ int i;
+
+ memset(tag, '\0', sizeof (ao_lisp_busy));
+ memset(ao_lisp_cons_note, '\0', sizeof (ao_lisp_cons_note));
+ ao_lisp_cons_noted = 0;
+ for (i = 0; i < AO_LISP_ROOT; i++) {
+ if (ao_lisp_root[i].type) {
+ void **a = ao_lisp_root[i].addr, *v;
+ if (a && (v = *a)) {
+ MDBG("root ptr %d\n", MDBG_OFFSET(v));
+ visit_addr(ao_lisp_root[i].type, a);
+ }
+ } else {
+ ao_poly *a = (ao_poly *) ao_lisp_root[i].addr, p;
+ if (a && (p = *a)) {
+ MDBG("root poly %d\n", MDBG_OFFSET(ao_lisp_ref(p)));
+ visit_poly(a, 0);
+ }
+ }
+ }
+ while (ao_lisp_cons_noted) {
+ memcpy(ao_lisp_cons_last, ao_lisp_cons_note, sizeof (ao_lisp_cons_note));
+ memset(ao_lisp_cons_note, '\0', sizeof (ao_lisp_cons_note));
+ ao_lisp_cons_noted = 0;
+ for (i = 0; i < AO_LISP_POOL; i += 4) {
+ if (busy(ao_lisp_cons_last, i)) {
+ void *v = ao_lisp_pool + i;
+ MDBG("root cons %d\n", MDBG_OFFSET(v));
+ visit_addr(&ao_lisp_cons_type, &v);
+ }
+ }
+ }
+}
+