X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fscheme%2Fao_scheme_mem.c;h=c7d6b1f8c2f3c345e5d2305373c182d4f2794e5a;hb=e1a6b3bf458f311d832aea7eec34935d42f8efed;hp=292d0f9d6835db38756e9ec055b1117389caf586;hpb=d8c9024f3829dc3f241b16869f165f3ee01764f3;p=fw%2Faltos diff --git a/src/scheme/ao_scheme_mem.c b/src/scheme/ao_scheme_mem.c index 292d0f9d..c7d6b1f8 100644 --- a/src/scheme/ao_scheme_mem.c +++ b/src/scheme/ao_scheme_mem.c @@ -41,6 +41,36 @@ uint8_t ao_scheme_pool[AO_SCHEME_POOL + AO_SCHEME_POOL_EXTRA] __attribute__((ali #define DBG_MEM_STATS DBG_MEM #endif +#define DBG_MEM_STACK 0 +#if DBG_MEM_STACK +char *mem_collect_stack; +int64_t mem_collect_max_depth; + +static void +ao_scheme_check_stack(void) +{ + char x; + int64_t depth; + + depth = mem_collect_stack - &x; + if (depth > mem_collect_max_depth) + mem_collect_max_depth = depth; +} + +static void +_ao_scheme_reset_stack(char *x) +{ + mem_collect_stack = x; +// mem_collect_max_depth = 0; +} +#define ao_scheme_declare_stack char x; +#define ao_scheme_reset_stack() _ao_scheme_reset_stack(&x) +#else +#define ao_scheme_check_stack() +#define ao_scheme_declare_stack +#define ao_scheme_reset_stack() +#endif + #if DBG_MEM int dbg_move_depth; int dbg_mem = DBG_MEM_START; @@ -148,7 +178,7 @@ struct ao_scheme_root { }; static struct ao_scheme_cons *save_cons[2]; -static char *save_string[2]; +static struct ao_scheme_string *save_string[2]; static struct ao_scheme_frame *save_frame[1]; static ao_poly save_poly[3]; @@ -250,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]; @@ -281,6 +315,7 @@ static inline uint16_t pool_offset(void *addr) { static inline void mark(uint8_t *tag, int offset) { int byte = offset >> 5; int bit = (offset >> 2) & 7; + ao_scheme_check_stack(); tag[byte] |= (1 << bit); } @@ -303,7 +338,7 @@ static inline int limit(int offset) { return min(AO_SCHEME_POOL, max(offset, 0)); } -static void +static inline void note_cons(uint16_t offset) { MDBG_MOVE("note cons %d\n", offset); @@ -335,6 +370,7 @@ static void note_chunk(uint16_t offset, uint16_t size) { int l; + int end; if (offset < chunk_low || chunk_high <= offset) return; @@ -357,7 +393,7 @@ note_chunk(uint16_t offset, uint16_t size) #endif /* Shuffle existing entries right */ - int end = min(AO_SCHEME_NCHUNK, chunk_last + 1); + end = min(AO_SCHEME_NCHUNK, chunk_last + 1); memmove(&ao_scheme_chunk[l+1], &ao_scheme_chunk[l], @@ -456,7 +492,9 @@ dump_busy(void) static const struct ao_scheme_type * const ao_scheme_types[AO_SCHEME_NUM_TYPE] = { [AO_SCHEME_CONS] = &ao_scheme_cons_type, [AO_SCHEME_INT] = NULL, - [AO_SCHEME_STRING] = &ao_scheme_string_type, +#ifdef AO_SCHEME_FEATURE_BIGINT + [AO_SCHEME_BIGINT] = &ao_scheme_bigint_type, +#endif [AO_SCHEME_OTHER] = (void *) 0x1, [AO_SCHEME_ATOM] = &ao_scheme_atom_type, [AO_SCHEME_BUILTIN] = &ao_scheme_builtin_type, @@ -465,9 +503,7 @@ static const struct ao_scheme_type * const ao_scheme_types[AO_SCHEME_NUM_TYPE] = [AO_SCHEME_LAMBDA] = &ao_scheme_lambda_type, [AO_SCHEME_STACK] = &ao_scheme_stack_type, [AO_SCHEME_BOOL] = &ao_scheme_bool_type, -#ifdef AO_SCHEME_FEATURE_BIGINT - [AO_SCHEME_BIGINT] = &ao_scheme_bigint_type, -#endif + [AO_SCHEME_STRING] = &ao_scheme_string_type, #ifdef AO_SCHEME_FEATURE_FLOAT [AO_SCHEME_FLOAT] = &ao_scheme_float_type, #endif @@ -476,6 +512,12 @@ static const struct ao_scheme_type * const ao_scheme_types[AO_SCHEME_NUM_TYPE] = #endif }; +static int +ao_scheme_mark(const struct ao_scheme_type *type, void *addr); + +static int +ao_scheme_move(const struct ao_scheme_type *type, void **ref); + static int ao_scheme_mark_ref(const struct ao_scheme_type *type, void **ref) { @@ -495,10 +537,12 @@ uint64_t ao_scheme_loops[2]; #endif int ao_scheme_last_top; +int ao_scheme_collect_counts; int ao_scheme_collect(uint8_t style) { + ao_scheme_declare_stack int i; int top; #if DBG_MEM_STATS @@ -510,11 +554,22 @@ 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(); /* The first time through, we're doing a full collect */ if (ao_scheme_last_top == 0) style = AO_SCHEME_COLLECT_FULL; + /* One in a while, just do a full collect */ + + if (ao_scheme_collect_counts >= 128) + style = AO_SCHEME_COLLECT_FULL; + + if (style == AO_SCHEME_COLLECT_FULL) + ao_scheme_collect_counts = 0; + /* Clear references to all caches */ for (i = 0; i < (int) AO_SCHEME_CACHE; i++) *ao_scheme_cache[i] = NULL; @@ -628,6 +683,10 @@ ao_scheme_collect(uint8_t style) MDBG_DO(memset(ao_scheme_chunk, '\0', sizeof (ao_scheme_chunk)); walk(ao_scheme_mark_ref, ao_scheme_poly_mark_ref)); +#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; } @@ -662,28 +721,6 @@ ao_scheme_cons_check(struct ao_scheme_cons *cons) */ -/* - * Mark a block of memory with an explicit size - */ - -int -ao_scheme_mark_block(void *addr, int size) -{ - int offset; - if (!AO_SCHEME_IS_POOL(addr)) - return 1; - - offset = pool_offset(addr); - MDBG_MOVE("mark memory %d\n", MDBG_OFFSET(addr)); - if (busy(ao_scheme_busy, offset)) { - MDBG_MOVE("already marked\n"); - return 1; - } - mark(ao_scheme_busy, offset); - note_chunk(offset, size); - return 0; -} - /* * Note a reference to memory and collect information about a few * object sizes at a time @@ -710,7 +747,7 @@ ao_scheme_mark_memory(const struct ao_scheme_type *type, void *addr) /* * Mark an object and all that it refereces */ -int +static int ao_scheme_mark(const struct ao_scheme_type *type, void *addr) { int ret; @@ -737,6 +774,7 @@ ao_scheme_poly_mark(ao_poly p, uint8_t do_note_cons) { uint8_t type; void *addr; + int ret; type = ao_scheme_poly_base_type(p); @@ -751,16 +789,26 @@ ao_scheme_poly_mark(ao_poly p, uint8_t do_note_cons) note_cons(pool_offset(addr)); return 1; } else { + const struct ao_scheme_type *lisp_type; + if (type == AO_SCHEME_OTHER) type = ao_scheme_other_type(addr); - const struct ao_scheme_type *lisp_type = ao_scheme_types[type]; + lisp_type = ao_scheme_types[type]; #if DBG_MEM if (!lisp_type) ao_scheme_abort(); #endif - return ao_scheme_mark(lisp_type, addr); + MDBG_MOVE("mark %d\n", MDBG_OFFSET(addr)); + MDBG_MOVE_IN(); + ret = ao_scheme_mark_memory(lisp_type, addr); + if (!ret) { + MDBG_MOVE("mark recurse\n"); + lisp_type->mark(addr); + } + MDBG_MOVE_OUT(); + return ret; } } @@ -817,7 +865,7 @@ ao_scheme_move_memory(const struct ao_scheme_type *type, void **ref) return 0; } -int +static int ao_scheme_move(const struct ao_scheme_type *type, void **ref) { int ret; @@ -835,16 +883,12 @@ ao_scheme_move(const struct ao_scheme_type *type, void **ref) int ao_scheme_poly_move(ao_poly *ref, uint8_t do_note_cons) { - uint8_t type; ao_poly p = *ref; int ret; void *addr; uint16_t offset, orig_offset; - uint8_t base_type; - - base_type = type = ao_scheme_poly_base_type(p); - if (type == AO_SCHEME_INT) + if (ao_scheme_poly_base_type(p) == AO_SCHEME_INT) return 1; addr = ao_scheme_ref(p); @@ -854,25 +898,35 @@ ao_scheme_poly_move(ao_poly *ref, uint8_t do_note_cons) orig_offset = pool_offset(addr); offset = move_map(orig_offset); - if (type == AO_SCHEME_CONS && do_note_cons) { + if (ao_scheme_poly_base_type(p) == AO_SCHEME_CONS && do_note_cons) { note_cons(orig_offset); ret = 1; } else { + uint8_t type = ao_scheme_poly_base_type(p); + const struct ao_scheme_type *lisp_type; + if (type == AO_SCHEME_OTHER) type = ao_scheme_other_type(ao_scheme_pool + offset); - const struct ao_scheme_type *lisp_type = ao_scheme_types[type]; + lisp_type = ao_scheme_types[type]; #if DBG_MEM if (!lisp_type) ao_scheme_abort(); #endif - - ret = ao_scheme_move(lisp_type, &addr); + /* inline ao_scheme_move to save stack space */ + MDBG_MOVE("move object %d\n", MDBG_OFFSET(addr)); + MDBG_MOVE_IN(); + ret = ao_scheme_move_memory(lisp_type, &addr); + if (!ret) { + MDBG_MOVE("move recurse\n"); + lisp_type->move(addr); + } + MDBG_MOVE_OUT(); } /* Re-write the poly value */ if (offset != orig_offset) { - ao_poly np = ao_scheme_poly(ao_scheme_pool + offset, base_type); + ao_poly np = ao_scheme_poly(ao_scheme_pool + offset, ao_scheme_poly_base_type(p)); MDBG_MOVE("poly %d moved %d -> %d\n", type, orig_offset, offset); *ref = np; @@ -945,16 +999,16 @@ ao_scheme_poly_fetch(int id) } void -ao_scheme_string_stash(int id, char *string) +ao_scheme_string_stash(int id, struct ao_scheme_string *string) { assert(save_string[id] == NULL); save_string[id] = string; } -char * +struct ao_scheme_string * ao_scheme_string_fetch(int id) { - char *string = save_string[id]; + struct ao_scheme_string *string = save_string[id]; save_string[id] = NULL; return string; } @@ -973,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; +}