diff options
author | WormHeamer | 2025-03-04 08:54:44 -0500 |
---|---|---|
committer | WormHeamer | 2025-03-04 08:54:44 -0500 |
commit | c1d26bdba9c0d62c3e34c8ca374f45d4795e1305 (patch) | |
tree | c914978b44f23bef3f0059a2a9baa3c25a21da79 | |
parent | 20cbe7ee472c416b243541e661e7eb11621a881f (diff) |
store pointers in zone frame, finer-grained alignment, zn_new, etc
-rw-r--r-- | zone.h | 154 |
1 files changed, 90 insertions, 64 deletions
diff --git a/zone.h b/zone.h index 936f757..b5aeee5 100644 --- a/zone.h +++ b/zone.h @@ -2,6 +2,7 @@ #define ZONE_H #include <stdint.h> +#include <stddef.h> #ifndef ZONE_MIN_CAPACITY #define ZONE_MIN_CAPACITY 1024 @@ -13,17 +14,17 @@ typedef struct ZoneFrame ZoneFrame; struct ZoneFrame { ZoneFrame *prev, *next; - size_t length, capacity; - uintptr_t data[]; + uint8_t *beg, *end; + uint8_t data[]; }; typedef struct { - ZoneFrame *tail, *here; + ZoneFrame *cur, *tail; } Zone; typedef struct { ZoneFrame *zf; - size_t length; + uint8_t *beg; } ZoneState; void zn_free(Zone *z); @@ -31,10 +32,15 @@ void zn_reset(Zone *z); void zn_save(Zone *z, ZoneState *m); void zn_load(Zone *z, ZoneState *m); -void *zn_alloc(Zone *z, size_t n); -void *zn_zf_alloc(Zone *z, ZoneFrame **zf, size_t n); -void *zn_zf_realloc(Zone *z, ZoneFrame **zf, void *ptr, size_t oldsz, size_t newsz); +void *zn_alloc(Zone *z, ptrdiff_t n); +void *zn_alloc_align(Zone *z, ptrdiff_t n, size_t align); +void *zn_realloc(Zone *z, void *ptr, ptrdiff_t oldsz, ptrdiff_t newsz); +void *zn_realloc_align(Zone *z, void *ptr, ptrdiff_t oldsz, ptrdiff_t newsz, size_t align); + char *zn_strdup(Zone *z, const char *s); +void *zn_zeroed(void *, size_t); + +#define zn_new(z, t) (t*)zn_zeroed(zn_alloc_align(z, sizeof(t), alignof(t)), sizeof(t)) #ifdef ZONE_IMPL @@ -66,7 +72,7 @@ char *zn_strdup(Zone *z, const char *s); return zf; } static void zn_zf_free(ZoneFrame *zf) { - munmap(zf, sizeof *zf + zf->capacity * sizeof(uintptr_t)); + munmap(zf, (uintptr_t)zf->end - (uintptr_t)zf); } static size_t zn_zf_capacity(size_t cap) { if (cap < ZONE_MIN_CAPACITY) cap = ZONE_MIN_CAPACITY; @@ -100,99 +106,119 @@ char *zn_strdup(Zone *z, const char *s); #endif static ZoneFrame *zn_zf_new(size_t capacity) { + capacity = zn_zf_capacity(capacity); ZoneFrame *zf = zn_zf_allocate(capacity); zf->prev = NULL; zf->next = NULL; - zf->length = 0; - zf->capacity = capacity; + zf->beg = zf->data; + zf->end = (uint8_t*)zf + capacity; return zf; } -void *zn_alloc(Zone *z, size_t n) { - return zn_zf_alloc(z, NULL, n); -} +#define PTR_ALIGN(ptr, align) (typeof(ptr))((uint8_t*)ptr + ((-(uintptr_t)ptr) & ((align)-1))) -void *zn_zf_alloc(Zone *z, ZoneFrame **zfo, size_t n) { - ZoneFrame *zf = NULL; - size_t wordsz = (n + sizeof(uintptr_t) - 1) / sizeof(uintptr_t); - for (ZoneFrame *f = z->here; f; f = f->next) { - if (f->capacity - f->length >= wordsz) { - zf = f; - break; - } +void *zn_alloc_align(Zone *z, ptrdiff_t n, size_t align) { + ZoneFrame *zf = z->cur; + while (zf && PTR_ALIGN(zf->beg, align) + n >= zf->end) { + zf = zf->next; } if (!zf) { - zf = zn_zf_new(zn_zf_capacity(wordsz)); + zf = zn_zf_new(n + align - 1); zf->prev = z->tail; if (z->tail) z->tail->next = zf; z->tail = zf; + z->cur = zf; } - void *ptr = &zf->data[zf->length]; - zf->length += wordsz; - z->here = zf; - if (zfo) *zfo = zf; - return ptr; + zf->beg = PTR_ALIGN(zf->beg, align); + void *p = zf->beg; + zf->beg += n; + return p; } -void *zn_zf_realloc(Zone *z, ZoneFrame **zfo, void *old, size_t oldsz, size_t newsz) { - ZoneFrame *zf = *zfo; - size_t old_wordsz = (oldsz + sizeof(uintptr_t) - 1) / sizeof(uintptr_t); - size_t new_wordsz = (newsz + sizeof(uintptr_t) - 1) / sizeof(uintptr_t); - if (&zf->data[zf->length - old_wordsz] == old && zf->length + new_wordsz - old_wordsz <= zf->capacity) { - zf->length = zf->length + new_wordsz - old_wordsz; - return old; +void *zn_realloc_align(Zone *z, void *ptr, ptrdiff_t oldsz, ptrdiff_t newsz, size_t align) { + goto justalloc; + if (!ptr || !oldsz) return zn_alloc_align(z, newsz, align); + if (z->cur && ptr == z->cur->beg - oldsz && z->cur->beg - oldsz + newsz < z->cur->end) { + z->cur->beg -= oldsz; + z->cur->beg += newsz; + return ptr; } else { - void *new = zn_zf_alloc(z, zfo, newsz); - zf->length -= old_wordsz; - memcpy(new, old, oldsz); - return new; +justalloc: + void *p = zn_alloc_align(z, newsz, align); + memcpy(p, ptr, oldsz); + return p; } } +static inline size_t zn_align_for(size_t n) { + size_t a = 1; + while (n > a) a <<= 1; + return a; +} + +void *zn_alloc(Zone *z, ptrdiff_t n) { + return zn_alloc_align(z, n, zn_align_for(n)); +} + +void *zn_realloc(Zone *z, void *ptr, ptrdiff_t oldsz, ptrdiff_t newsz) { + return zn_realloc_align(z, ptr, oldsz, newsz, zn_align_for(newsz)); +} + +void *zn_calloc(Zone *z, size_t n, size_t size) { + void *p = zn_alloc_align(z, n * size, zn_align_for(size)); + memset(p, 0, n * size); + return p; +} + void zn_free(Zone *z) { - ZoneFrame *p, *t; - t = z->tail; - while (t) { - p = t->prev; - zn_zf_free(t); - t = p; + ZoneFrame *a = z->tail, *b; + while (a) { + b = a->prev; + zn_zf_free(a); + a = b; } } void zn_reset(Zone *z) { - ZoneFrame *zf = z->here; - if (!zf) return; - for (;;) { - zf->length = 0; - if (zf->prev) zf = zf->prev; - else break; + ZoneFrame *zf = z->tail; + while (zf) { + zf->beg = zf->data; + if (!zf->prev) break; + zf = zf->prev; } - z->tail = zf; -} - -char *zn_strdup(Zone *z, const char *s) { - size_t n = strlen(s) + 1; - char *d = zn_alloc(z, n); - memcpy(d, s, n); - return d; + if (zf) z->cur = zf; } void zn_save(Zone *z, ZoneState *m) { - m->zf = z->here; - m->length = z->here ? z->tail->length : 0; + m->zf = z->cur; + m->beg = z->cur ? z->cur->beg : 0; } void zn_load(Zone *z, ZoneState *m) { if (m->zf) { - while (z->here != m->zf) { - z->here->length = 0; - z->here = z->here->prev; + while (z->cur != m->zf) { + z->cur->beg = z->cur->data; + z->cur = z->cur->prev; } - m->zf->length = m->length; + m->zf->beg = m->beg; } else { zn_reset(z); } } +/* utils */ + +char *zn_strdup(Zone *z, const char *s) { + size_t n = strlen(s) + 1; + char *d = zn_alloc_align(z, n, 1); + memcpy(d, s, n); + return d; +} + +void *zn_zeroed(void *ptr, size_t n) { + memset(ptr, 0, n); + return ptr; +} + #endif #endif |