diff --git a/src/game/memory.c b/src/game/memory.c index ee123c0ff..22a8908b7 100644 --- a/src/game/memory.c +++ b/src/game/memory.c @@ -5,7 +5,8 @@ #include "print.h" #include "pc/debuglog.h" -#define ALIGN16(val) (((val) + 0xF) & ~0xF) +// Alignment to a data size +#define ALIGN_UP(val, align) (((val) + ((align) - 1)) & ~((align) - 1)) ////////////////// // dynamic pool // @@ -14,7 +15,8 @@ struct DynamicPool *gLevelPool = NULL; struct DynamicPool* dynamic_pool_init(void) { - struct DynamicPool* pool = calloc(1, sizeof(struct DynamicPool)); + struct DynamicPool* pool = malloc(sizeof(struct DynamicPool)); + if (!pool) { return NULL; } pool->usedSpace = 0; pool->tail = NULL; pool->nextFree = NULL; @@ -24,14 +26,17 @@ struct DynamicPool* dynamic_pool_init(void) { void* dynamic_pool_alloc(struct DynamicPool *pool, u32 size) { if (!pool) { return NULL; } - struct DynamicPoolNode* node = calloc(1, sizeof(struct DynamicPoolNode)); - node->ptr = calloc(1, size); + size_t header = ALIGN_UP(sizeof(struct DynamicPoolNode), sizeof(void*)); + struct DynamicPoolNode* node = malloc(header + size); + if (!node) { return NULL; } + node->ptr = (u8*)node + header; node->prev = pool->tail; node->size = size; pool->tail = node; pool->usedSpace += size; + memset(node->ptr, 0, size); return node->ptr; } @@ -50,8 +55,7 @@ void dynamic_pool_free(struct DynamicPool *pool, void* ptr) { next->prev = prev; } pool->usedSpace -= node->size; - free(node->ptr); - free(node); + free(node); // node->ptr is freed here too; it's part of the same allocation return; } next = node; @@ -81,8 +85,7 @@ void dynamic_pool_free_pool(struct DynamicPool *pool) { struct DynamicPoolNode* node = pool->nextFree; while (node) { struct DynamicPoolNode* prev = node->prev; - free(node->ptr); - free(node); + free(node); // node->ptr is freed here too; it's part of the same allocation node = prev; } @@ -107,7 +110,8 @@ struct GrowingPool* growing_pool_init(struct GrowingPool* pool, u32 nodeSize) { pool->usedSpace = 0; } else { // allocate a new pool - pool = calloc(1, sizeof(struct GrowingPool)); + pool = malloc(sizeof(struct GrowingPool)); + if (!pool) { return NULL; } pool->usedSpace = 0; pool->nodeSize = nodeSize; pool->tail = NULL; @@ -119,19 +123,22 @@ void* growing_pool_alloc(struct GrowingPool *pool, u32 size) { if (!pool) { return NULL; } // maintain alignment - size = ALIGN16(size); + size = ALIGN_UP(size, sizeof(void*)); // check if it's too big for a node if (size >= pool->nodeSize) { // create a node just for this - struct GrowingPoolNode* node = calloc(1, sizeof(struct GrowingPoolNode)); - node->ptr = calloc(1, size); + size_t header = ALIGN_UP(sizeof(struct GrowingPoolNode), sizeof(void*)); + struct GrowingPoolNode* node = malloc(header + size); + if (!node) { return NULL; } + node->ptr = (u8*) node + header; node->prev = pool->tail; node->usedSpace = size; pool->tail = node; pool->usedSpace += size; + memset(node->ptr, 0, size); return node->ptr; } @@ -143,7 +150,7 @@ void* growing_pool_alloc(struct GrowingPool *pool, u32 size) { while (node && depth < 128) { depth++; s64 freeSpace = (s64)pool->nodeSize - (s64)node->usedSpace; - if (freeSpace > size) { break; } + if (freeSpace >= (s64) size) { break; } node = node->prev; } if (depth >= 128) { @@ -153,9 +160,11 @@ void* growing_pool_alloc(struct GrowingPool *pool, u32 size) { // allocate new node if (!node) { - node = calloc(1, sizeof(struct GrowingPoolNode)); + size_t header = ALIGN_UP(sizeof(struct GrowingPoolNode), sizeof(void*)); + node = malloc(header + pool->nodeSize); + if (!node) { return NULL; } node->usedSpace = 0; - node->ptr = calloc(1, pool->nodeSize); + node->ptr = (u8*) node + header; node->prev = pool->tail; pool->tail = node; } @@ -174,8 +183,7 @@ void growing_pool_free_pool(struct GrowingPool *pool) { struct GrowingPoolNode* node = pool->tail; while (node) { struct GrowingPoolNode* prev = node->prev; - free(node->ptr); - free(node); + free(node); // node->ptr is freed here too; it's part of the same allocation node = prev; } free(pool); @@ -218,7 +226,12 @@ struct GrowingArray *growing_array_init(struct GrowingArray *array, u32 capacity } } else { array = malloc(sizeof(struct GrowingArray)); + if (!array) { return NULL; } array->buffer = calloc(capacity, sizeof(void *)); + if (!array->buffer) { + free(array); + return NULL; + } } array->capacity = capacity; @@ -234,9 +247,9 @@ void *growing_array_alloc(struct GrowingArray *array, u32 size) { // Increase capacity if needed while (array->count >= array->capacity) { u32 newCapacity = array->capacity * 2; - void **newBuffer = calloc(newCapacity, sizeof(void *)); - memcpy(newBuffer, array->buffer, array->capacity * sizeof(void *)); - free(array->buffer); + void **newBuffer = realloc(array->buffer, newCapacity * sizeof(void *)); + if (!newBuffer) { return NULL; } + memset(newBuffer + array->capacity, 0, (newCapacity - array->capacity) * sizeof(void *)); array->buffer = newBuffer; array->capacity = newCapacity; }