summaryrefslogtreecommitdiff
path: root/src/lib/memory.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/memory.c')
-rw-r--r--src/lib/memory.c50
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)
{