diff --git a/src/system_allocator.c b/src/system_allocator.c index f9dd291aebb4aec066e3ed02fd249f60c2f73be7..b47bf06a575cc08b63219814f91caefd96cc6bfb 100644 --- a/src/system_allocator.c +++ b/src/system_allocator.c @@ -2,41 +2,77 @@ #include <stdlib.h> #include "internal.h" -//#define DEBUG__MEMFILL 0xFF +// NOTE(uucidl): undefine to automatically fill up newly allocated block +// with this byte: +// #define DEBUG__MEMFILL 0xFF + +/** + * Blocks allocated by the system_allocator start with this header. + * I.e. the user part of the allocation directly follows. + */ +typedef struct HDebugBlockHeader_ +{ + size_t size; /** size of the user allocation */ +} HDebugBlockHeader; + +#define BLOCK_HEADER_SIZE (sizeof(HDebugBlockHeader)) + +/** + * Compute the total size needed for a given allocation size. + */ +static inline size_t block_size(size_t alloc_size) { + return BLOCK_HEADER_SIZE + alloc_size; +} + +/** + * Obtain the block containing the user pointer `uptr` + */ +static inline void* block_for_user_ptr(void *uptr) { + return ((char*)uptr) - BLOCK_HEADER_SIZE; +} + +/** + * Obtain the user area of the allocation from a given block + */ +static inline void* user_ptr(void *block) { + return ((char*)block) + BLOCK_HEADER_SIZE; +} static void* system_alloc(HAllocator *allocator, size_t size) { - - void* ptr = malloc(size + sizeof(size_t)); - if (!ptr) { + void *block = malloc(block_size(size)); + if (!block) { return NULL; } + void *uptr = user_ptr(block); #ifdef DEBUG__MEMFILL - memset(ptr, DEBUG__MEMFILL, size + sizeof(size_t)); + memset(uptr, DEBUG__MEMFILL, size); #endif - *(size_t*)ptr = size; - return ptr + sizeof(size_t); + ((HDebugBlockHeader*)block)->size = size; + return uptr; } -static void* system_realloc(HAllocator *allocator, void* ptr, size_t size) { - if (!ptr) { +static void* system_realloc(HAllocator *allocator, void* uptr, size_t size) { + if (!uptr) { return system_alloc(allocator, size); } - ptr = realloc(ptr - sizeof(size_t), size + sizeof(size_t)); - if (!ptr) { + void* block = realloc(block_for_user_ptr(uptr), block_size(size)); + if (!block) { return NULL; } - *(size_t*)ptr = size; + uptr = user_ptr(block); + #ifdef DEBUG__MEMFILL - size_t old_size = *(size_t*)ptr; + size_t old_size = ((HDebugBlockHeader*)block)->size; if (size > old_size) - memset(ptr+sizeof(size_t)+old_size, DEBUG__MEMFILL, size - old_size); + memset((char*)uptr+old_size, DEBUG__MEMFILL, size - old_size); #endif - return ptr + sizeof(size_t); + ((HDebugBlockHeader*)block)->size = size; + return uptr; } -static void system_free(HAllocator *allocator, void* ptr) { - if (ptr) { - free(ptr - sizeof(size_t)); +static void system_free(HAllocator *allocator, void* uptr) { + if (uptr) { + free(block_for_user_ptr(uptr)); } } diff --git a/tools/windows/hammer_lib_src_list b/tools/windows/hammer_lib_src_list index 87b3b280b48e3a720b3256da32e84c3c26544674..c332d2c2362e7a2760ca3c139a3f6a0bc7ab96ba 100644 --- a/tools/windows/hammer_lib_src_list +++ b/tools/windows/hammer_lib_src_list @@ -7,6 +7,7 @@ cfgrammar.c desugar.c glue.c hammer.c +system_allocator.c parsers/action.c parsers/and.c parsers/attr_bool.c