summaryrefslogtreecommitdiff
path: root/src/scheme/ao_scheme_mem.c
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2017-12-17 22:22:50 -0800
committerKeith Packard <keithp@keithp.com>2017-12-17 22:22:50 -0800
commite1a6b3bf458f311d832aea7eec34935d42f8efed (patch)
tree7141f7e4ae75f23969722f75517f4c39cb623263 /src/scheme/ao_scheme_mem.c
parent9d1131da911f7220ac8b6cb7ba5a0afd3deef657 (diff)
altos/scheme: Use memory manager mark code to note recursive print
This flags any object being printed and checks before recursing to avoid infinite loops. Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'src/scheme/ao_scheme_mem.c')
-rw-r--r--src/scheme/ao_scheme_mem.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/src/scheme/ao_scheme_mem.c b/src/scheme/ao_scheme_mem.c
index e7e89b89..c7d6b1f8 100644
--- a/src/scheme/ao_scheme_mem.c
+++ b/src/scheme/ao_scheme_mem.c
@@ -280,6 +280,10 @@ static const void ** const ao_scheme_cache[] = {
#define AO_SCHEME_BUSY_SIZE ((AO_SCHEME_POOL + 31) / 32)
+static int ao_scheme_printing, ao_scheme_print_cleared;
+#if DBG_MEM
+static int ao_scheme_collecting;
+#endif
static uint8_t ao_scheme_busy[AO_SCHEME_BUSY_SIZE];
static uint8_t ao_scheme_cons_note[AO_SCHEME_BUSY_SIZE];
static uint8_t ao_scheme_cons_last[AO_SCHEME_BUSY_SIZE];
@@ -550,6 +554,7 @@ ao_scheme_collect(uint8_t style)
MDBG_MOVE("collect %d\n", ao_scheme_collects[style]);
#endif
MDBG_DO(ao_scheme_frame_write(ao_scheme_frame_poly(ao_scheme_frame_global)));
+ MDBG_DO(++ao_scheme_collecting);
ao_scheme_reset_stack();
@@ -681,6 +686,7 @@ ao_scheme_collect(uint8_t style)
#if DBG_MEM_STACK
fprintf(stderr, "max collect stack depth %lu\n", mem_collect_max_depth);
#endif
+ MDBG_DO(--ao_scheme_collecting);
return AO_SCHEME_POOL - ao_scheme_top;
}
@@ -1021,3 +1027,53 @@ ao_scheme_frame_fetch(int id)
save_frame[id] = NULL;
return frame;
}
+
+int
+ao_scheme_print_mark_addr(void *addr)
+{
+ int offset;
+
+#if DBG_MEM
+ if (ao_scheme_collecting)
+ ao_scheme_abort();
+#endif
+
+ if (!AO_SCHEME_IS_POOL(addr))
+ return 1;
+
+ if (!ao_scheme_print_cleared) {
+ ao_scheme_print_cleared = 1;
+ memset(ao_scheme_busy, '\0', sizeof (ao_scheme_busy));
+ }
+ offset = pool_offset(addr);
+ if (busy(ao_scheme_busy, offset))
+ return 1;
+ mark(ao_scheme_busy, offset);
+ return 0;
+}
+
+int
+ao_scheme_print_mark_poly(ao_poly p)
+{
+ uint8_t type = ao_scheme_poly_base_type(p);
+
+ if (type == AO_SCHEME_INT)
+ return 1;
+ return ao_scheme_print_mark_addr(ao_scheme_ref(p));
+}
+
+/* Notes that printing has started */
+void
+ao_scheme_print_start(void)
+{
+ ao_scheme_printing++;
+}
+
+/* Notes that printing has ended */
+void
+ao_scheme_print_stop(void)
+{
+ ao_scheme_printing--;
+ if (ao_scheme_printing == 0)
+ ao_scheme_print_cleared = 0;
+}