X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fscheme%2Fao_scheme_mem.c;h=e7e89b89490ea902b81f23e92bebb987beefd305;hb=32f6877288ea6b7eb1cae9a42fbe8e2c5dbb2f08;hp=acc726c8a8fea8b0f834c48a63a084c0ff8b1576;hpb=195cbeec19a6a44f309a9040d727d37fe4e2ec97;p=fw%2Faltos diff --git a/src/scheme/ao_scheme_mem.c b/src/scheme/ao_scheme_mem.c index acc726c8..e7e89b89 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]; @@ -281,6 +311,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 +334,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 +366,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 +389,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 +488,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,10 +499,21 @@ 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, - [AO_SCHEME_BIGINT] = &ao_scheme_bigint_type, + [AO_SCHEME_STRING] = &ao_scheme_string_type, +#ifdef AO_SCHEME_FEATURE_FLOAT [AO_SCHEME_FLOAT] = &ao_scheme_float_type, +#endif +#ifdef AO_SCHEME_FEATURE_VECTOR + [AO_SCHEME_VECTOR] = &ao_scheme_vector_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) { @@ -482,16 +527,18 @@ ao_scheme_poly_mark_ref(ao_poly *p, uint8_t do_note_cons) } #if DBG_MEM_STATS -int ao_scheme_collects[2]; -int ao_scheme_freed[2]; -int ao_scheme_loops[2]; +uint64_t ao_scheme_collects[2]; +uint64_t ao_scheme_freed[2]; +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 @@ -504,10 +551,20 @@ ao_scheme_collect(uint8_t style) #endif MDBG_DO(ao_scheme_frame_write(ao_scheme_frame_poly(ao_scheme_frame_global))); + 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; @@ -621,6 +678,9 @@ 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 return AO_SCHEME_POOL - ao_scheme_top; } @@ -655,28 +715,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 @@ -703,7 +741,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; @@ -730,6 +768,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); @@ -744,16 +783,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; } } @@ -810,7 +859,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; @@ -828,16 +877,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); @@ -847,25 +892,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; @@ -938,16 +993,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; }