From 2d75df22efe25d4e50a6f1cc117f3258829316db Mon Sep 17 00:00:00 2001 From: "Sven M. Hallberg" <pesco@khjk.org> Date: Sun, 9 Feb 2020 18:06:28 +0100 Subject: [PATCH] add a dumb but working implementation of h_arena_realloc() --- src/allocator.c | 29 +++++++++++++++++++++++++++++ src/allocator.h | 1 + src/parsers/bind.c | 3 +-- 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/allocator.c b/src/allocator.c index 2ff5caca..93c94e1d 100644 --- a/src/allocator.c +++ b/src/allocator.c @@ -267,3 +267,32 @@ void h_allocator_stats(HArena *arena, HArenaStats *stats) { stats->arena_li_malloc_bytes = arena->arena_li_malloc_bytes; #endif } + +void* h_arena_realloc(HArena *arena, void* ptr, size_t n) { + struct arena_link *link; + void* ret; + size_t ncopy; + + // XXX this is really wasteful, but maybe better than nothing? + // + // first, we walk the blocks to find our ptr. since we don't know how large + // the original allocation was, we must always make a new one and copy as + // much data from the old block as there could have been. + + for (link = arena->head; link; link = link->next) { + if (ptr >= (void *)link->rest && ptr <= (void *)link->rest + link->used) + break; /* found it */ + } + assert(link != NULL); + + ncopy = (void *)link->rest + link->used - ptr; + if (n < ncopy) + ncopy = n; + + ret = h_arena_malloc_noinit(arena, n); + assert(ret != NULL); + memcpy(ret, ptr, ncopy); + h_arena_free(arena, ptr); + + return ret; +} diff --git a/src/allocator.h b/src/allocator.h index 06d1e6f5..8ebde723 100644 --- a/src/allocator.h +++ b/src/allocator.h @@ -55,6 +55,7 @@ HArena *h_new_arena(HAllocator* allocator, size_t block_size); // pass 0 for def void* h_arena_malloc_noinit(HArena *arena, size_t count) ATTR_MALLOC(2); void* h_arena_malloc(HArena *arena, size_t count) ATTR_MALLOC(2); +void* h_arena_realloc(HArena *arena, void* ptr, size_t count); void h_arena_free(HArena *arena, void* ptr); // For future expansion, with alternate memory managers. void h_delete_arena(HArena *arena); void h_arena_set_except(HArena *arena, jmp_buf *except); diff --git a/src/parsers/bind.c b/src/parsers/bind.c index 87f42330..eac49744 100644 --- a/src/parsers/bind.c +++ b/src/parsers/bind.c @@ -21,8 +21,7 @@ static void *aa_alloc(HAllocator *allocator, size_t size) static void *aa_realloc(HAllocator *allocator, void *ptr, size_t size) { HArena *arena = ((ArenaAllocator *)allocator)->arena; - assert(((void)"XXX need realloc for arena allocator", 0)); - return NULL; + return h_arena_realloc(arena, ptr, size); } static void aa_free(HAllocator *allocator, void *ptr) -- GitLab