diff options
Diffstat (limited to 'src/lib/memory.c')
| -rw-r--r-- | src/lib/memory.c | 50 |
1 files changed, 48 insertions, 2 deletions
diff --git a/src/lib/memory.c b/src/lib/memory.c index 03f2056..fb143ec 100644 --- a/src/lib/memory.c +++ b/src/lib/memory.c @@ -28,7 +28,9 @@ enum chunk_tag { CHUNK_TAG_STRING, CHUNK_TAG_TOKEN_LIST, CHUNK_TAG_APLWC_VALUE, - CHUNK_TAG_APLWC_MODULE + CHUNK_TAG_APLWC_MODULE, + CHUNK_TAG_MODULE_MEMBER, + CHUNK_TAG_SYMBOL }; struct chunk { @@ -39,6 +41,8 @@ struct chunk { unsigned int last:1; }; +static void debug_check_mem(struct aplwc *); + void memory_init(struct aplwc *aplwc) { @@ -69,14 +73,21 @@ data(struct chunk *c) struct chunk * next(struct chunk *c) { + static struct chunk *prev; uint8_t *p; if(c->last) return NULL; p = (uint8_t*)c; + assert((((uintptr_t)p) % ALIGNMENT) == 0); + p += c->size; + assert((((uintptr_t)p) % ALIGNMENT) == 0); + + prev = c; + UNUSED_PARAMETER(prev); - return (struct chunk *)(p + c->size); + return (struct chunk *)p; } #define VISIT_FIELD(X, tag, ptr) X(((struct tag *)data(c))->ptr) @@ -95,13 +106,25 @@ next(struct chunk *c) case CHUNK_TAG_APLWC_MODULE: \ VISIT_FIELD(X, aplwc_module, name); \ VISIT_FIELD(X, aplwc_module, tokens); \ + VISIT_FIELD(X, aplwc_module, imports); \ + VISIT_FIELD(X, aplwc_module, members); \ VISIT_FIELD(X, aplwc_module, link); \ break; \ + case CHUNK_TAG_MODULE_MEMBER: \ + VISIT_FIELD(X, module_member, module); \ + VISIT_FIELD(X, module_member, real_member); \ + VISIT_FIELD(X, module_member, link); \ + break; \ + case CHUNK_TAG_SYMBOL: \ + VISIT_FIELD(X, symbol, text); \ + VISIT_FIELD(X, symbol, link); \ + break; \ case CHUNK_TAG_FREE: \ break; \ } #define VISIT_ROOT_PTRS(X) do{ \ X(aplwc->modules); \ + X(aplwc->symtab); \ for(frame = aplwc->memptrs; frame; frame = frame->link) \ for(i = 0; i < frame->count; i++) \ if(frame->ptrs[i]) \ @@ -325,6 +348,7 @@ compact(struct aplwc *aplwc) if(c->tag == CHUNK_TAG_FREE){ prev->size += c->size; prev->last = c->last; + c = prev; }else{ /* swap prev and c */ oldptr = data(c); @@ -357,6 +381,8 @@ debug_check_mem(struct aplwc *aplwc) prev = NULL; for(c = (struct chunk *)aplwc->data; c; prev = c, c = next(c)){ assert(((uint8_t*)c) < (aplwc->data+aplwc->size)); + assert((c->size % ALIGNMENT) == 0); + assert(c->stack == NULL); size += c->size; assert((c->last == 0) != (size == aplwc->size)); if(c->tag == CHUNK_TAG_FREE) @@ -414,6 +440,8 @@ retry: if(new->last){ new->last = 0; free->last = 1; + }else{ + free->last = 0; } new->size = size+HEADER_SIZE; @@ -529,6 +557,24 @@ memory_alloc_aplwc_module(struct aplwc *aplwc) return p; } +struct module_member * +memory_alloc_module_member(struct aplwc *aplwc) +{ + struct module_member *p; + + p = alloc(aplwc, sizeof(struct module_member), CHUNK_TAG_MODULE_MEMBER); + return p; +} + +struct symbol * +memory_alloc_symbol(struct aplwc *aplwc) +{ + struct symbol *p; + + p = alloc(aplwc, sizeof(struct symbol), CHUNK_TAG_SYMBOL); + return p; +} + void clear_ref(struct aplwc_ref *ref) { |