diff options
Diffstat (limited to 'src/mem.hff')
| -rw-r--r-- | src/mem.hff | 42 |
1 files changed, 28 insertions, 14 deletions
diff --git a/src/mem.hff b/src/mem.hff index 84064f3..a86bee3 100644 --- a/src/mem.hff +++ b/src/mem.hff @@ -9,30 +9,44 @@ extern fn xrealloc(p *void, n usize) *void; struct ArenaRegion { prev *ArenaRegion, - idx int, - mem [ARENA_SIZE]u8, + idx usize, + siz usize, + mem [0]u8, } struct Arena { r *ArenaRegion, + fn addregion(a *Arena, siz usize) void { + let r *ArenaRegion = xcalloc(sizeof ArenaRegion + siz, 1); + r.siz = siz; + r.prev = a.r; + a.r = r; + } + fn allocf(a *void, n usize) *void { let a *Arena = a; n = ALIGNUP(n, 16); - if ARENA_SIZE < n { - return xmalloc(n); + if n > ARENA_SIZE { + a->addregion(n); + return a.r.mem; } else if a.r == #null { - a.r = xcalloc(1, sizeof ArenaRegion); - return allocf(a, n); - } else if ARENA_SIZE - a.r.idx >= n { - let ptr = &a.r.mem[a.r.idx]; - a.r.idx += n; - return ptr; + a->addregion(ARENA_SIZE); + return allocf(a, n); + } else if n > a.r.siz - a.r.idx { + a->addregion(ARENA_SIZE); + return allocf(a, n); } else { - let rp *ArenaRegion = xmalloc(sizeof ArenaRegion); - *rp = *a.r; - let r = ArenaRegion { .prev: rp }; - return allocf(a, n); + let p = &a.r.mem[a.r.idx]; + a.r.idx += n; + return p; + } + } + + fn destroy(a *Arena) void { + for let r = a.r, next *ArenaRegion = #null; r; r = next { + next = r.prev; + free(r); } } } |