X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Flisp%2Fao_lisp_mem.c;h=0dfad1d7c87bcc6286b924698730a63a849c3dcb;hb=e600fc409c577eec02af612a36431c477a9c875e;hp=b681dbd547f1bd6d4e7f0b0fa873325d0ca075cc;hpb=daa06c8dedc6dc1cf21936ee2769d9d25f0567bd;p=fw%2Faltos diff --git a/src/lisp/ao_lisp_mem.c b/src/lisp/ao_lisp_mem.c index b681dbd5..0dfad1d7 100644 --- a/src/lisp/ao_lisp_mem.c +++ b/src/lisp/ao_lisp_mem.c @@ -144,6 +144,7 @@ struct ao_lisp_root { static struct ao_lisp_cons *save_cons[2]; static char *save_string[2]; +static struct ao_lisp_stack *save_stack[3]; static ao_poly save_poly[2]; static const struct ao_lisp_root ao_lisp_root[] = { @@ -155,6 +156,18 @@ static const struct ao_lisp_root ao_lisp_root[] = { .type = &ao_lisp_cons_type, .addr = (void **) &save_cons[1], }, + { + .type = &ao_lisp_stack_type, + .addr = (void **) &save_stack[0] + }, + { + .type = &ao_lisp_stack_type, + .addr = (void **) &save_stack[1] + }, + { + .type = &ao_lisp_stack_type, + .addr = (void **) &save_stack[2] + }, { .type = &ao_lisp_string_type, .addr = (void **) &save_string[0] @@ -252,23 +265,6 @@ static inline uint16_t pool_offset(void *addr) { return ((uint8_t *) addr) - ao_lisp_pool; } -/* - * Convert back and forth between 'poly's used - * as short addresses in the pool and addresses. - * These are used in the chunk code. - */ -static inline ao_poly pool_poly(void *addr) { -#if DBG_MEM - if (!AO_LISP_IS_POOL(addr)) - ao_lisp_abort(); -#endif - return ((uint8_t *) addr) - AO_LISP_POOL_BASE; -} - -static inline void *pool_ref(ao_poly p) { - return AO_LISP_POOL_BASE + p; -} - static inline void mark(uint8_t *tag, int offset) { int byte = offset >> 5; int bit = (offset >> 2) & 7; @@ -314,36 +310,55 @@ static int chunk_busy; static void note_chunk(uint16_t addr, uint16_t size) { - int i; + int l, r; - if (addr < chunk_low || chunk_high < addr) + if (addr < chunk_low || chunk_high <= addr) return; - 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) - ao_lisp_abort(); -#endif - 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], - (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++; + /* Binary search for the location */ + l = 0; + r = chunk_busy - 1; + while (l <= r) { + int m = (l + r) >> 1; + if (ao_lisp_chunk[m].old_addr < addr) + l = m + 1; else - chunk_high = ao_lisp_chunk[AO_LISP_NCHUNK-1].old_addr + - ao_lisp_chunk[AO_LISP_NCHUNK-1].size; + r = m - 1; } + /* + * The correct location is always in 'l', with r = l-1 being + * the entry before the right one + */ + +#if DBG_MEM + /* Off the right side */ + if (l >= AO_LISP_NCHUNK) + ao_lisp_abort(); + + /* Off the left side */ + if (l == 0 && chunk_busy && addr > ao_lisp_chunk[0].old_addr) + ao_lisp_abort(); +#endif + + /* Shuffle existing entries right */ + int end = min(AO_LISP_NCHUNK, chunk_busy + 1); + + memmove(&ao_lisp_chunk[l+1], + &ao_lisp_chunk[l], + (end - (l+1)) * sizeof (struct ao_lisp_chunk)); + + /* Add new entry */ + ao_lisp_chunk[l].old_addr = addr; + ao_lisp_chunk[l].size = size; + + /* Increment the number of elements up to the size of the array */ + if (chunk_busy < AO_LISP_NCHUNK) + chunk_busy++; + + /* Set the top address if the array is full */ + if (chunk_busy == AO_LISP_NCHUNK) + chunk_high = ao_lisp_chunk[AO_LISP_NCHUNK-1].old_addr + + ao_lisp_chunk[AO_LISP_NCHUNK-1].size; } static void @@ -432,6 +447,7 @@ static const struct ao_lisp_type const *ao_lisp_types[AO_LISP_NUM_TYPE] = { [AO_LISP_BUILTIN] = &ao_lisp_builtin_type, [AO_LISP_FRAME] = &ao_lisp_frame_type, [AO_LISP_LAMBDA] = &ao_lisp_lambda_type, + [AO_LISP_STACK] = &ao_lisp_stack_type, }; static int @@ -816,6 +832,20 @@ ao_lisp_cons_fetch(int id) return cons; } +void +ao_lisp_stack_stash(int id, struct ao_lisp_stack *stack) +{ + save_stack[id] = stack; +} + +struct ao_lisp_stack * +ao_lisp_stack_fetch(int id) +{ + struct ao_lisp_stack *stack = save_stack[id]; + save_stack[id] = NULL; + return stack; +} + void ao_lisp_string_stash(int id, char *string) {