From 66f6f65899f8d4be0071d9178e0f9f587520abdf Mon Sep 17 00:00:00 2001 From: gamemasterplc Date: Tue, 21 Nov 2023 22:15:51 -0600 Subject: [PATCH] Finish all but HuMemHeapDump HuMemHeapDump has some regallloc problems --- include/functions.h | 27 ++++--- src/game/malloc.c | 12 +-- src/game/memory.c | 179 ++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 192 insertions(+), 26 deletions(-) diff --git a/include/functions.h b/include/functions.h index 8de302eb..29afc607 100644 --- a/include/functions.h +++ b/include/functions.h @@ -23,25 +23,28 @@ void fn_1_26C(void); void HuMemInitAll(void); -void *HuMemInit(void *ptr, u32 size); +void *HuMemInit(void *ptr, s32 size); void HuMemDCFlushAll(); void HuMemDCFlush(int heap); -void *HuMemDirectMalloc(int heap, u32 size); -void *HuMemDirectMallocNum(int heap, u32 size, int num); +void *HuMemDirectMalloc(int heap, s32 size); +void *HuMemDirectMallocNum(int heap, s32 size, u32 num); void HuMemDirectFree(void *ptr); -void HuMemDirectFreeNum(int heap, int num); -u32 HuMemUsedMallocSizeGet(int heap); -u32 HuMemUsedMallocBlockGet(int heap); +void HuMemDirectFreeNum(int heap, u32 num); +s32 HuMemUsedMallocSizeGet(int heap); +s32 HuMemUsedMallocBlockGet(int heap); u32 HuMemHeapSizeGet(int heap); void *HuMemHeapPtrGet(int heap); -void *HuMemHeapInit(void *ptr, u32 size); -void *HuMemMemoryAlloc(void *heap_ptr, u32 size, u32 retaddr); -void *HuMemMemoryAllocNum(void *heap_ptr, u32 size, int num, u32 retaddr); +void *HuMemHeapInit(void *ptr, s32 size); +void *HuMemMemoryAlloc(void *heap_ptr, s32 size, u32 retaddr); +void *HuMemMemoryAllocNum(void *heap_ptr, s32 size, u32 num, u32 retaddr); void HuMemMemoryFree(void *ptr, u32 retaddr); -void HuMemMemoryFreeNum(void *heap_ptr, int num, u32 retaddr); -u32 HuMemUsedMemorySizeGet(void *heap_ptr); -u32 HuMemUsedMemoryBlockGet(void *heap_ptr); +void HuMemMemoryFreeNum(void *heap_ptr, u32 num, u32 retaddr); +s32 HuMemUsedMemorySizeGet(void *heap_ptr); +s32 HuMemUsedMemoryBlockGet(void *heap_ptr); +s32 HuMemMemoryAllocSizeGet(s32 size); +void HuMemHeapDump(void *heap_ptr, s16 status); + #endif \ No newline at end of file diff --git a/src/game/malloc.c b/src/game/malloc.c index 4c466b02..08910376 100644 --- a/src/game/malloc.c +++ b/src/game/malloc.c @@ -30,7 +30,7 @@ void HuMemInitAll(void) HeapSizeTbl[4] = free_size; } -void *HuMemInit(void *ptr, u32 size) +void *HuMemInit(void *ptr, s32 size) { return HuMemHeapInit(ptr, size); } @@ -46,7 +46,7 @@ void HuMemDCFlush(int heap) DCFlushRangeNoSync(HeapTbl[heap], HeapSizeTbl[heap]); } -void *HuMemDirectMalloc(int heap, u32 size) +void *HuMemDirectMalloc(int heap, s32 size) { register u32 retaddr; asm { @@ -56,7 +56,7 @@ void *HuMemDirectMalloc(int heap, u32 size) return HuMemMemoryAlloc(HeapTbl[heap], size, retaddr); } -void *HuMemDirectMallocNum(int heap, u32 size, int num) +void *HuMemDirectMallocNum(int heap, s32 size, u32 num) { register u32 retaddr; asm { @@ -75,7 +75,7 @@ void HuMemDirectFree(void *ptr) HuMemMemoryFree(ptr, retaddr); } -void HuMemDirectFreeNum(int heap, int num) +void HuMemDirectFreeNum(int heap, u32 num) { register u32 retaddr; asm { @@ -84,12 +84,12 @@ void HuMemDirectFreeNum(int heap, int num) HuMemMemoryFreeNum(HeapTbl[heap], num, retaddr); } -u32 HuMemUsedMallocSizeGet(int heap) +s32 HuMemUsedMallocSizeGet(int heap) { return HuMemUsedMemorySizeGet(HeapTbl[heap]); } -u32 HuMemUsedMallocBlockGet(int heap) +s32 HuMemUsedMallocBlockGet(int heap) { return HuMemUsedMemoryBlockGet(HeapTbl[heap]); } diff --git a/src/game/memory.c b/src/game/memory.c index 1b1576f3..15dfb908 100644 --- a/src/game/memory.c +++ b/src/game/memory.c @@ -1,18 +1,23 @@ #include "common.h" +#define DATA_GET_BLOCK(ptr) ((struct memory_block *)(((char *)(ptr))-32)) +#define BLOCK_GET_DATA(block) (((char *)(block))+32) + +#define MEM_ALLOC_SIZE(size) (((size)+63) & 0xFFFFFFE0) + struct memory_block { - u32 size; + s32 size; u8 magic; u8 flag; struct memory_block *prev; struct memory_block *next; - int num; + u32 num; u32 retaddr; }; -static void *HuMemMemoryAlloc2(void *heap_ptr, u32 size, int num, u32 retaddr); +static void *HuMemMemoryAlloc2(void *heap_ptr, s32 size, u32 num, u32 retaddr); -void *HuMemHeapInit(void *ptr, u32 size) +void *HuMemHeapInit(void *ptr, s32 size) { struct memory_block *block = ptr; block->size = size; @@ -25,17 +30,175 @@ void *HuMemHeapInit(void *ptr, u32 size) return block; } -void *HuMemMemoryAllocNum(void *heap_ptr, u32 size, int num, u32 retaddr) +void *HuMemMemoryAllocNum(void *heap_ptr, s32 size, u32 num, u32 retaddr) { return HuMemMemoryAlloc2(heap_ptr, size, num, retaddr); } -void *HuMemMemoryAlloc(void *heap_ptr, u32 size, u32 retaddr) +void *HuMemMemoryAlloc(void *heap_ptr, s32 size, u32 retaddr) { return HuMemMemoryAlloc2(heap_ptr, size, -256, retaddr); } -static void *HuMemMemoryAlloc2(void *heap_ptr, u32 size, int num, u32 retaddr) +static void *HuMemMemoryAlloc2(void *heap_ptr, s32 size, u32 num, u32 retaddr) { + s32 alloc_size = MEM_ALLOC_SIZE(size); + struct memory_block *block = heap_ptr; + do { + if(!block->flag && block->size >= alloc_size) { + if(block->size-alloc_size > 32u) { + struct memory_block *new_block = (struct memory_block *)(((u32)block)+alloc_size); + new_block->size = block->size-alloc_size; + new_block->magic = 205; + new_block->flag = 0; + new_block->retaddr = retaddr; + block->next->prev = new_block; + new_block->next = block->next; + block->next = new_block; + new_block->prev = block; + block->size = alloc_size; + } + block->flag = 1; + block->magic = 165; + block->num = num; + block->retaddr = retaddr; + return BLOCK_GET_DATA(block); + } + block = block->next; + } while(block != heap_ptr); + OSReport("HuMem>memory alloc error %08x(%08X): Call %08x\n", size, num, retaddr); + HuMemHeapDump(heap_ptr, -1); + return NULL; +} + +void HuMemMemoryFreeNum(void *heap_ptr, u32 num, u32 retaddr) +{ + struct memory_block *block = heap_ptr; + do { + struct memory_block *block_next = block->next; + if(block->flag && block->num == num) { + HuMemMemoryFree(BLOCK_GET_DATA(block), retaddr); + } + block = block_next; + } while(block != heap_ptr); -} \ No newline at end of file +} + +static void HuMemTailMemoryAlloc2() //Required for string literal +{ + OSReport("memory allocation(tail) error.\n"); +} + +void HuMemMemoryFree(void *ptr, u32 retaddr) +{ + struct memory_block *block; + if(!ptr) { + return; + } + block = DATA_GET_BLOCK(ptr); + if(block->magic != 165) { + OSReport("HuMem>memory free error. %08x( call %08x)\n", ptr, retaddr); + return; + } + if(block->prev < block && !block->prev->flag) { + block->flag = 0; + block->magic = 205; + block->next->prev = block->prev; + block->prev->next = block->next; + block->prev->size += block->size; + block = block->prev; + } + if(block->next > block && !block->next->flag) { + block->next->next->prev = block; + block->size += block->next->size; + block->next = block->next->next; + } + block->flag = 0; + block->magic = 205; + block->retaddr = retaddr; +} + +s32 HuMemUsedMemorySizeGet(void *heap_ptr) +{ + struct memory_block *block = heap_ptr; + s32 size = 0; + do { + if(block->flag == 1) { + size += block->size; + } + block = block->next; + } while(block != heap_ptr); + return size; +} + +s32 HuMemUsedMemoryBlockGet(void *heap_ptr) +{ + struct memory_block *block = heap_ptr; + s32 num_blocks = 0; + do { + if(block->flag == 1) { + num_blocks++; + } + block = block->next; + } while(block != heap_ptr); + return num_blocks; +} + +s32 HuMemMemoryAllocSizeGet(s32 size) +{ + return MEM_ALLOC_SIZE(size); +} + +void HuMemHeapDump(void *heap_ptr, s16 status) +{ + u8 dump_type; + s32 size, inactive_size; + s32 num_unused_blocks, num_blocks; + struct memory_block *block = heap_ptr; + size = 0; + inactive_size = 0; + num_blocks = 0; + num_unused_blocks = 0; + + if(status < 0) { + dump_type = 10; + } else if(status == 0) { + dump_type = 0; + } else { + dump_type = 1; + } + OSReport("======== HuMem heap dump %08x ========\n", heap_ptr); + OSReport("MCB-----+Size----+MG+FL+Prev----+Next----+UNum----+Body----+Call----\n"); + do { + if(dump_type == 10 || block->flag == dump_type) { + OSReport("%08x %08x %02x %02x %08x %08x %08x %08x %08x\n", block, block->size, block->magic, block->flag, + block->prev, block->next, block->num, BLOCK_GET_DATA(block), block->retaddr); + } + if(block->flag == 1) { + size += block->size; + num_blocks++; + } else { + inactive_size += block->size; + num_unused_blocks++; + } + + block = block->next; + } while(block != heap_ptr); + OSReport("MCB:%d(%d/%d) MEM:%08x(%08x/%08x)\n", num_blocks+num_unused_blocks, num_blocks, num_unused_blocks, + size+inactive_size, size, inactive_size); + OSReport("======== HuMem heap dump %08x end =====\n", heap_ptr); +} + +s32 HuMemMemorySizeGet(void *ptr) +{ + struct memory_block *block; + if(!ptr) { + return 0; + } + block = DATA_GET_BLOCK(ptr); + if(block->flag == 1 && block->magic == 165) { + return block->size-32; + } else { + return 0; + } +}