diff options
| author | peter <peter@pmikkelsen.com> | 2026-09-01 21:14:43 +0000 |
|---|---|---|
| committer | peter <peter@pmikkelsen.com> | 2026-09-01 21:14:43 +0000 |
| commit | 047b642464442b290ea04f5d07bb3ce57a59fdb8 (patch) | |
| tree | 378521ffc2d19fa18ed66c46128d2b0628001c78 | |
| parent | 26c3da82eb6f33cce64d218e97e2d44324fb9721 (diff) | |
Put all the code which visits pointers in memory.c behind a macro, so it can easily be reused.memory-manager
FossilOrigin-Name: 1e911fa0ea41797f445fff6f25df36b6c0f07063b5c6e9936cb243294a2d8a0c
| -rw-r--r-- | src/lib/memory.c | 177 |
1 files changed, 56 insertions, 121 deletions
diff --git a/src/lib/memory.c b/src/lib/memory.c index e95afc5..a53a37e 100644 --- a/src/lib/memory.c +++ b/src/lib/memory.c @@ -47,17 +47,49 @@ data(struct chunk *c) return p + HEADER_SIZE; } -static void -fixrefs(struct aplwc *aplwc, uint8_t *new, uint8_t *old) -{ -#define FIX(ptr) do{ \ - if(ptr){ \ - (ptr) = (void*)(((uint8_t*)(ptr))+add); \ - (ptr) = (void*)(((uint8_t*)(ptr))-sub); \ +#define VISIT_FIELD(X, tag, ptr) X(((struct tag *)data(c))->ptr) +#define VISIT_CHUNK_PTRS(X, c) switch(c->tag){ \ + case CHUNK_TAG_APLWC_LINE: \ + VISIT_FIELD(X, aplwc_line, text); \ + VISIT_FIELD(X, aplwc_line, tokens); \ + break; \ + case CHUNK_TAG_STRING: \ + break; \ + case CHUNK_TAG_TOKEN_LIST: \ + VISIT_FIELD(X, token_list, text); \ + break; \ + case CHUNK_TAG_APLWC_VALUE: \ + break; \ + case CHUNK_TAG_APLWC_MODULE: \ + VISIT_FIELD(X, aplwc_module, name); \ + VISIT_FIELD(X, aplwc_module, tokens); \ + VISIT_FIELD(X, aplwc_module, link); \ + break; \ + case CHUNK_TAG_FREE: \ + break; \ + } +#define VISIT_ROOT_PTRS(X) do{ \ + X(aplwc->modules); \ + for(frame = aplwc->memptrs; frame; frame = frame->link) \ + for(i = 0; i < frame->count; i++) \ + if(frame->ptrs[i]) \ + X(*frame->ptrs[i]); \ + for(root = aplwc->rootptrs; root; root = root->link) \ + if(root->ptr) \ + X(root->ptr); \ +}while(0) + +#define VISIT_ALL_PTRS(X, data) do{ \ + VISIT_ROOT_PTRS(X); \ + for(c = (struct chunk *)(data); c; c = c->next){ \ + X(c->next); \ + VISIT_CHUNK_PTRS(X, c); \ } \ }while(0) -#define FIX_DATA(type, ptr) FIX(((type *)data(c))->ptr) +static void +fixrefs(struct aplwc *aplwc, uint8_t *new, uint8_t *old) +{ struct chunk *c; struct memory_ptr_frame *frame; @@ -72,44 +104,14 @@ fixrefs(struct aplwc *aplwc, uint8_t *new, uint8_t *old) sub = old-new; } - FIX(aplwc->modules); - - for(c = (struct chunk *)new; c; c = c->next){ - FIX(c->next); - - switch(c->tag){ - case CHUNK_TAG_APLWC_LINE: - FIX_DATA(struct aplwc_line, text); - FIX_DATA(struct aplwc_line, tokens); - break; - case CHUNK_TAG_STRING: - break; - case CHUNK_TAG_TOKEN_LIST: - FIX_DATA(struct token_list, text); - break; - case CHUNK_TAG_APLWC_VALUE: - break; - case CHUNK_TAG_APLWC_MODULE: - FIX_DATA(struct aplwc_module, name); - FIX_DATA(struct aplwc_module, tokens); - FIX_DATA(struct aplwc_module, link); - break; - case CHUNK_TAG_FREE: - break; - } - } - - for(frame = aplwc->memptrs; frame; frame = frame->link) - for(i = 0; i < frame->count; i++) - if(frame->ptrs[i]) - FIX(*frame->ptrs[i]); - - for(root = aplwc->rootptrs; root; root = root->link) - if(root->ptr) - FIX(root->ptr); - +#define FIX(ptr) do{ \ + if(ptr){ \ + (ptr) = (void*)(((uint8_t*)(ptr))+add); \ + (ptr) = (void*)(((uint8_t*)(ptr))-sub); \ + } \ +}while(0) + VISIT_ALL_PTRS(FIX, new); #undef FIX -#undef FIX_DATA } static enum aplwc_rc @@ -239,40 +241,12 @@ collect(struct aplwc *aplwc) /* Mark reachable chunks */ stack = NULL; - push(aplwc, &stack, aplwc->modules); - - for(frame = aplwc->memptrs; frame; frame = frame->link) - for(i = 0; i < frame->count; i++) - if(frame->ptrs[i]) - push(aplwc, &stack, *frame->ptrs[i]); - - for(root = aplwc->rootptrs; root; root = root->link) - if(root->ptr) - push(aplwc, &stack, root->ptr); +#define PUSH(ptr) push(aplwc, &stack, ptr) + VISIT_ROOT_PTRS(PUSH); while(stack){ c = pop(&stack); -#define PUSH(type, ptr) push(aplwc, &stack, ((type *)data(c))->ptr) - switch(c->tag){ - case CHUNK_TAG_APLWC_LINE: - PUSH(struct aplwc_line, text); - PUSH(struct aplwc_line, tokens); - break; - case CHUNK_TAG_STRING: - break; - case CHUNK_TAG_TOKEN_LIST: - PUSH(struct token_list, text); - break; - case CHUNK_TAG_APLWC_VALUE: - break; - case CHUNK_TAG_APLWC_MODULE: - PUSH(struct aplwc_module, name); - PUSH(struct aplwc_module, tokens); - PUSH(struct aplwc_module, link); - break; - case CHUNK_TAG_FREE: - break; - } + VISIT_CHUNK_PTRS(PUSH, c); #undef PUSH } @@ -286,56 +260,17 @@ collect(struct aplwc *aplwc) static void swapptr(struct aplwc *aplwc, void *old, void *new) { -#define SWAP(ptr) do{ \ - if((ptr) == old) \ - (ptr) = new; \ -}while(0) - -#define SWAP_DATA(type, ptr) SWAP(((type *)data(c))->ptr) - struct chunk *c; struct memory_ptr_frame *frame; struct root_ptr *root; size_t i; - SWAP(aplwc->modules); - - for(c = (struct chunk *)new; c; c = c->next){ - SWAP(c->next); - - switch(c->tag){ - case CHUNK_TAG_APLWC_LINE: - SWAP_DATA(struct aplwc_line, text); - SWAP_DATA(struct aplwc_line, tokens); - break; - case CHUNK_TAG_STRING: - break; - case CHUNK_TAG_TOKEN_LIST: - SWAP_DATA(struct token_list, text); - break; - case CHUNK_TAG_APLWC_VALUE: - break; - case CHUNK_TAG_APLWC_MODULE: - SWAP_DATA(struct aplwc_module, name); - SWAP_DATA(struct aplwc_module, tokens); - SWAP_DATA(struct aplwc_module, link); - break; - case CHUNK_TAG_FREE: - break; - } - } - - for(frame = aplwc->memptrs; frame; frame = frame->link) - for(i = 0; i < frame->count; i++) - if(frame->ptrs[i]) - SWAP(*frame->ptrs[i]); - - for(root = aplwc->rootptrs; root; root = root->link) - if(root->ptr) - SWAP(root->ptr); - -#undef SWAP -#undef SWAP_DATA +#define SWAP(ptr) do{ \ + if((ptr) == old) \ + (ptr) = new; \ +}while(0) + VISIT_ALL_PTRS(SWAP, new); +#undef SWAP } static void |