X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=blobdiff_plain;f=src%2Flisp%2Fao_lisp_mem.c;h=b681dbd547f1bd6d4e7f0b0fa873325d0ca075cc;hp=e7ece96036ae1d31ce17f5d1a4a463385d3453f3;hb=daa06c8dedc6dc1cf21936ee2769d9d25f0567bd;hpb=5557f6b87a9b8bc9716de8191f2062a772a6ae6c diff --git a/src/lisp/ao_lisp_mem.c b/src/lisp/ao_lisp_mem.c index e7ece960..b681dbd5 100644 --- a/src/lisp/ao_lisp_mem.c +++ b/src/lisp/ao_lisp_mem.c @@ -36,10 +36,6 @@ uint8_t ao_lisp_pool[AO_LISP_POOL + AO_LISP_POOL_EXTRA] __attribute__((aligned(4 #endif -#if 0 -#define MDBG_POOL -#endif - #if DBG_MEM int dbg_move_depth; int dbg_mem = DBG_MEM_START; @@ -214,8 +210,16 @@ static const struct ao_lisp_root ao_lisp_root[] = { static const void ** const ao_lisp_cache[] = { (const void **) &ao_lisp_cons_free_list, (const void **) &ao_lisp_stack_free_list, + (const void **) &ao_lisp_frame_free_list[0], + (const void **) &ao_lisp_frame_free_list[1], + (const void **) &ao_lisp_frame_free_list[2], + (const void **) &ao_lisp_frame_free_list[3], }; +#if AO_LISP_FRAME_FREE != 4 +#error Unexpected AO_LISP_FRAME_FREE value +#endif + #define AO_LISP_CACHE (sizeof (ao_lisp_cache) / sizeof (ao_lisp_cache[0])) #define AO_LISP_BUSY_SIZE ((AO_LISP_POOL + 31) / 32) @@ -303,18 +307,19 @@ note_cons(void *addr) } } -static uint16_t chunk_low; +static uint16_t chunk_low, chunk_high; static uint16_t chunk_first, chunk_last; +static int chunk_busy; static void note_chunk(uint16_t addr, uint16_t size) { int i; - if (addr < chunk_low) + if (addr < chunk_low || chunk_high < addr) return; - for (i = 0; i < AO_LISP_NCHUNK; i++) { + for (i = 0; i < chunk_busy; i++) { if (ao_lisp_chunk[i].size && ao_lisp_chunk[i].old_addr == addr) { #if DBG_MEM if (ao_lisp_chunk[i].size != size) @@ -323,17 +328,30 @@ note_chunk(uint16_t addr, uint16_t size) return; } if (ao_lisp_chunk[i].old_addr > addr) { + int end = min(AO_LISP_NCHUNK, chunk_busy + 1); memmove(&ao_lisp_chunk[i+1], &ao_lisp_chunk[i], - (AO_LISP_NCHUNK - (i+1)) * sizeof (struct ao_lisp_chunk)); - ao_lisp_chunk[i].size = 0; - } - if (ao_lisp_chunk[i].size == 0) { - ao_lisp_chunk[i].old_addr = addr; - ao_lisp_chunk[i].size = size; - return; + (end - (i+1)) * sizeof (struct ao_lisp_chunk)); + break; } } + if (i < AO_LISP_NCHUNK) { + ao_lisp_chunk[i].old_addr = addr; + ao_lisp_chunk[i].size = size; + if (chunk_busy < AO_LISP_NCHUNK) + chunk_busy++; + else + chunk_high = ao_lisp_chunk[AO_LISP_NCHUNK-1].old_addr + + ao_lisp_chunk[AO_LISP_NCHUNK-1].size; + } +} + +static void +reset_chunks(void) +{ + memset(ao_lisp_chunk, '\0', sizeof (ao_lisp_chunk)); + chunk_high = ao_lisp_top; + chunk_busy = 0; } /* @@ -428,15 +446,20 @@ ao_lisp_poly_mark_ref(ao_poly *p, uint8_t do_note_cons) return ao_lisp_poly_mark(*p, do_note_cons); } -int ao_lisp_collects; +int ao_lisp_collects[2]; +int ao_lisp_freed[2]; +int ao_lisp_loops[2]; -void -ao_lisp_collect(void) +int ao_lisp_last_top; + +int +ao_lisp_collect(uint8_t style) { + int ret; int i; int top; -#if DBG_MEM int loops = 0; +#if DBG_MEM int marked; int moved; struct ao_lisp_record *mark_record = NULL, *move_record = NULL; @@ -445,18 +468,23 @@ ao_lisp_collect(void) marked = moved = 0; #endif - ++ao_lisp_collects; + /* The first time through, we're doing a full collect */ + if (ao_lisp_last_top == 0) + style = AO_LISP_COLLECT_FULL; /* Clear references to all caches */ for (i = 0; i < (int) AO_LISP_CACHE; i++) *ao_lisp_cache[i] = NULL; - chunk_low = 0; - top = 0; + if (style == AO_LISP_COLLECT_FULL) { + chunk_low = top = 0; + } else { + chunk_low = top = ao_lisp_last_top; + } for (;;) { - MDBG_DO(loops++); + loops++; MDBG_MOVE("move chunks from %d to %d\n", chunk_low, top); /* Find the sizes of the first chunk of objects to move */ - memset(ao_lisp_chunk, '\0', sizeof (ao_lisp_chunk)); + reset_chunks(); walk(ao_lisp_mark_ref, ao_lisp_poly_mark_ref); #if DBG_MEM marked = total_marked; @@ -490,7 +518,6 @@ ao_lisp_collect(void) MDBG_MOVE("chunk %d %d not moving\n", ao_lisp_chunk[i].old_addr, ao_lisp_chunk[i].size); - chunk_low = ao_lisp_chunk[i].old_addr + size; } chunk_first = i; @@ -510,7 +537,6 @@ ao_lisp_collect(void) &ao_lisp_pool[ao_lisp_chunk[i].old_addr], size); top += size; - chunk_low = ao_lisp_chunk[i].old_addr + size; } chunk_last = i; @@ -533,13 +559,26 @@ ao_lisp_collect(void) if (chunk_last != AO_LISP_NCHUNK) break; + + chunk_low = chunk_high; } + + /* Compute amount of memory freed */ + ret = ao_lisp_top - top; + + /* Collect stats */ + ++ao_lisp_collects[style]; + ao_lisp_freed[style] += ret; + ao_lisp_loops[style] += loops; + ao_lisp_top = top; + if (style == AO_LISP_COLLECT_FULL) + ao_lisp_last_top = top; MDBG_DO(memset(ao_lisp_chunk, '\0', sizeof (ao_lisp_chunk)); walk(ao_lisp_mark_ref, ao_lisp_poly_mark_ref)); -// printf ("collect. top %d loops %d\n", top, loops); + return ret; } /* @@ -729,45 +768,6 @@ ao_lisp_poly_move(ao_poly *ref, uint8_t do_note_cons) return ret; } -#ifdef MDBG_POOL -static int AO_LISP_POOL_CUR = AO_LISP_POOL / 8; - -static void -ao_lisp_poison(void) -{ - int i; - - printf("poison\n"); - ao_lisp_mark_busy(); - for (i = 0; i < AO_LISP_POOL_CUR; i += 4) { - uint32_t *a = (uint32_t *) &ao_lisp_pool[i]; - if (!busy_object(ao_lisp_busy, a)) - *a = 0xBEEFBEEF; - } - for (i = 0; i < AO_LISP_POOL_CUR; i += 2) { - ao_poly *a = (uint16_t *) &ao_lisp_pool[i]; - ao_poly p = *a; - - if (!ao_lisp_is_const(p)) { - void *r = ao_lisp_ref(p); - - if (ao_lisp_pool <= (uint8_t *) r && - (uint8_t *) r <= ao_lisp_pool + AO_LISP_POOL_CUR) - { - if (!busy_object(ao_lisp_busy, r)) { - printf("missing reference from %d to %d\n", - (int) ((uint8_t *) a - ao_lisp_pool), - (int) ((uint8_t *) r - ao_lisp_pool)); - } - } - } - } -} - -#else -#define AO_LISP_POOL_CUR AO_LISP_POOL -#endif - #if DBG_MEM void ao_lisp_validate(void) @@ -781,7 +781,6 @@ int dbg_allocs; #endif - void * ao_lisp_alloc(int size) { @@ -790,26 +789,10 @@ ao_lisp_alloc(int size) MDBG_DO(++dbg_allocs); MDBG_DO(if (dbg_validate) ao_lisp_validate()); size = ao_lisp_size_round(size); - if (ao_lisp_top + size > AO_LISP_POOL_CUR) { -#ifdef MDBG_POOL - if (AO_LISP_POOL_CUR < AO_LISP_POOL) { - AO_LISP_POOL_CUR += AO_LISP_POOL / 8; - ao_lisp_poison(); - } else -#endif - ao_lisp_collect(); -#ifdef MDBG_POOL + if (ao_lisp_top + size > AO_LISP_POOL) { + if (!ao_lisp_collect(AO_LISP_COLLECT_INCREMENTAL) && + !ao_lisp_collect(AO_LISP_COLLECT_FULL)) { - int i; - - for (i = ao_lisp_top; i < AO_LISP_POOL; i += 4) { - uint32_t *p = (uint32_t *) &ao_lisp_pool[i]; - *p = 0xbeefbeef; - } - } -#endif - - if (ao_lisp_top + size > AO_LISP_POOL) { ao_lisp_error(AO_LISP_OOM, "out of memory"); return NULL; }