From 95ea4223d5c221916a39d6acb6bd3c8320111f3b Mon Sep 17 00:00:00 2001 From: Lightning Date: Sat, 6 Nov 2021 20:10:53 -0700 Subject: [PATCH] Match _heap_malloc and _heap_malloc_tail (#519) * Matched _heap_malloc and _heap_malloc_tail * Move heap_malloc away from using s32 returns * Remove unmatched files * Missed a line * Requested changes * Add more changes from hidden convos * Working through entries :) * Remove extra parens left over from match work * Removed macro per Ethan's request * Fix a space --- include/common_structs.h | 6 +- include/functions.h | 2 +- src/43F0.c | 139 +++++++++++++++++- ver/us/asm/nonmatchings/43F0/_heap_malloc.s | 73 --------- .../asm/nonmatchings/43F0/_heap_malloc_tail.s | 56 ------- ver/us/symbol_addrs.txt | 2 +- 6 files changed, 141 insertions(+), 137 deletions(-) delete mode 100644 ver/us/asm/nonmatchings/43F0/_heap_malloc.s delete mode 100644 ver/us/asm/nonmatchings/43F0/_heap_malloc_tail.s diff --git a/include/common_structs.h b/include/common_structs.h index 160c3b2756..47ba87bc9a 100644 --- a/include/common_structs.h +++ b/include/common_structs.h @@ -106,10 +106,10 @@ typedef struct PartnerData { typedef struct HeapNode { /* 0x00 */ struct HeapNode* next; - /* 0x04 */ s32 length; + /* 0x04 */ u32 length; /* 0x08 */ u16 allocated; - /* 0x0A */ s16 entryID; - /* 0x0C */ s32 capacity; + /* 0x0A */ u16 entryID; + /* 0x0C */ u32 capacity; } HeapNode; // size = 0x10 /// Ring buffer of an NPC's position over the past 20 frames. diff --git a/include/functions.h b/include/functions.h index f00bf19874..90f1526774 100644 --- a/include/functions.h +++ b/include/functions.h @@ -22,7 +22,7 @@ OSThread* osGetActiveQueue(void); f32 signF(f32 val); void* heap_malloc(s32 size); -s32* _heap_malloc(HeapNode* head, s32 size); +void* _heap_malloc(HeapNode* head, u32 size); HeapNode* _heap_create(s32* addr, u32 size); s32 dma_copy(Addr romStart, Addr romEnd, void* vramDest); void copy_matrix(Matrix4f src, Matrix4f dest); diff --git a/src/43F0.c b/src/43F0.c index 87f3ebc7c3..6c39dce252 100644 --- a/src/43F0.c +++ b/src/43F0.c @@ -1,7 +1,7 @@ #include "common.h" #include "nu/nusys.h" -s32 D_80074270 = 0; +u16 heap_nextMallocID = 0; f32 D_80074274[] = { 0.0f, 0.017452f, 0.034899f, 0.052336f, 0.069756f, 0.087156f, 0.104528f, 0.121869f, 0.139173f, @@ -74,9 +74,142 @@ HeapNode* _heap_create(s32* addr, u32 size) { } } -INCLUDE_ASM(s32, "43F0", _heap_malloc); +void* _heap_malloc(HeapNode* head, u32 size) { + HeapNode* nextHeapNode; + HeapNode* pPrevHeapNode = NULL; + u32 newBlockSize; + u32 curBlockLength; + HeapNode* curHeapNode; + u32 smallestBlockFound; + u16 HeapEntryID; + u16 HeapEntryID2; -INCLUDE_ASM(s32, "43F0", _heap_malloc_tail); + // must allocate 16 bytes or more at minimum or fail + size = ALIGN16(size); + if (!size) { + return NULL; + } + + smallestBlockFound = 0; + nextHeapNode = NULL; + + // find the smallest block we can fit into in the free list + for (curHeapNode = head; ; curHeapNode = curHeapNode->next) { + if (!curHeapNode->allocated) { + curBlockLength = curHeapNode->length; + if ((curBlockLength >= size) && (curBlockLength < smallestBlockFound || !smallestBlockFound)) { + pPrevHeapNode = curHeapNode; + smallestBlockFound = curBlockLength; + nextHeapNode = curHeapNode->next; + } + } + if (!curHeapNode->next) { + break; + } + } + + + // find out the required block size with header + newBlockSize = size + sizeof(HeapNode); + + // if we found a block see if we need to split it up + if (smallestBlockFound) { + if (smallestBlockFound >= newBlockSize) { + // update previous to the proper size for the block being returned + pPrevHeapNode->next = (HeapNode*)((u8*)pPrevHeapNode + newBlockSize); + pPrevHeapNode->length = size; + + // update the entry id on allocation + HeapEntryID = heap_nextMallocID; + pPrevHeapNode->allocated = TRUE; + heap_nextMallocID = HeapEntryID + 1; + pPrevHeapNode->entryID = HeapEntryID; + + // setup the new heap block entry + curHeapNode = pPrevHeapNode->next; + curHeapNode->next = nextHeapNode; + curHeapNode->length = smallestBlockFound - newBlockSize; + curHeapNode->allocated = FALSE; + } else { + // take this entry out of the free linked list and mark as allocated + pPrevHeapNode->next = nextHeapNode; + pPrevHeapNode->length = smallestBlockFound; + + // update the entry id on allocation + // note, usage of a single ID from above will result in wrong code + HeapEntryID2 = heap_nextMallocID; + pPrevHeapNode->allocated = TRUE; + heap_nextMallocID = HeapEntryID2 + 1; + pPrevHeapNode->entryID = HeapEntryID2; + } + return (u8*)pPrevHeapNode + sizeof(HeapNode); + } + return NULL; +} + +void* _heap_malloc_tail(HeapNode* head, u32 size) { + HeapNode* curNode; + u32 newNodeSize; + u32 foundNodeLength; + HeapNode* foundNode; + HeapNode* nextNode; + + size = ALIGN16(size); + foundNode = NULL; + + // make sure we have a size to allocate + if (!size) { + return NULL; + } + + foundNodeLength = 0; + nextNode = NULL; + + // find the smallest block we can fit into + for (curNode = head; ; curNode = curNode->next) { + if (!curNode->allocated) { + if (curNode->length >= size) { + foundNode = curNode; + foundNodeLength = curNode->length; + nextNode = curNode->next; + } + } + + if (!curNode->next) { + break; + } + } + + newNodeSize = size + sizeof(HeapNode); + if (foundNodeLength != 0) { + curNode = foundNode; + + // we found a block to use, see if we can split it and return a portion + // or if we just need to return the whole block + if (foundNodeLength >= newNodeSize) { + // room to split and add another free block after this one, do so + curNode->next = (HeapNode*)((u8*)curNode + foundNodeLength - size); + curNode->length = foundNodeLength - newNodeSize; + curNode->allocated = FALSE; + + curNode = curNode->next; + curNode->next = nextNode; + curNode->length = size; + curNode->allocated = TRUE; + + } else { + // just return this actual block + curNode->next = nextNode; + curNode->length = foundNodeLength; + curNode->allocated = TRUE; + } + + return (u8*)curNode + sizeof(HeapNode); + } + + // did not find a block + return NULL; +} INCLUDE_ASM(s32, "43F0", _heap_free); diff --git a/ver/us/asm/nonmatchings/43F0/_heap_malloc.s b/ver/us/asm/nonmatchings/43F0/_heap_malloc.s deleted file mode 100644 index 19e8ebafbe..0000000000 --- a/ver/us/asm/nonmatchings/43F0/_heap_malloc.s +++ /dev/null @@ -1,73 +0,0 @@ -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches - -glabel _heap_malloc -/* 446C 8002906C 24A5000F */ addiu $a1, $a1, 0xf -/* 4470 80029070 2402FFF0 */ addiu $v0, $zero, -0x10 -/* 4474 80029074 00A22824 */ and $a1, $a1, $v0 -/* 4478 80029078 14A00003 */ bnez $a1, .L80029088 -/* 447C 8002907C 0000382D */ daddu $a3, $zero, $zero -/* 4480 80029080 03E00008 */ jr $ra -/* 4484 80029084 00E0102D */ daddu $v0, $a3, $zero -.L80029088: -/* 4488 80029088 0000402D */ daddu $t0, $zero, $zero -/* 448C 8002908C 0100502D */ daddu $t2, $t0, $zero -/* 4490 80029090 0080302D */ daddu $a2, $a0, $zero -.L80029094: -/* 4494 80029094 94C20008 */ lhu $v0, 8($a2) -/* 4498 80029098 1440000C */ bnez $v0, .L800290CC -/* 449C 8002909C 00000000 */ nop -/* 44A0 800290A0 8CC30004 */ lw $v1, 4($a2) -/* 44A4 800290A4 0065102B */ sltu $v0, $v1, $a1 -/* 44A8 800290A8 14400008 */ bnez $v0, .L800290CC -/* 44AC 800290AC 0068102B */ sltu $v0, $v1, $t0 -/* 44B0 800290B0 54400004 */ bnel $v0, $zero, .L800290C4 -/* 44B4 800290B4 00C0382D */ daddu $a3, $a2, $zero -/* 44B8 800290B8 15000004 */ bnez $t0, .L800290CC -/* 44BC 800290BC 00000000 */ nop -/* 44C0 800290C0 00C0382D */ daddu $a3, $a2, $zero -.L800290C4: -/* 44C4 800290C4 0060402D */ daddu $t0, $v1, $zero -/* 44C8 800290C8 8CEA0000 */ lw $t2, ($a3) -.L800290CC: -/* 44CC 800290CC 8CC40000 */ lw $a0, ($a2) -/* 44D0 800290D0 5480FFF0 */ bnel $a0, $zero, .L80029094 -/* 44D4 800290D4 0080302D */ daddu $a2, $a0, $zero -/* 44D8 800290D8 11000020 */ beqz $t0, .L8002915C -/* 44DC 800290DC 24A90010 */ addiu $t1, $a1, 0x10 -/* 44E0 800290E0 0109102B */ sltu $v0, $t0, $t1 -/* 44E4 800290E4 54400012 */ bnel $v0, $zero, .L80029130 -/* 44E8 800290E8 ACEA0000 */ sw $t2, ($a3) -/* 44EC 800290EC 00E91021 */ addu $v0, $a3, $t1 -/* 44F0 800290F0 ACE20000 */ sw $v0, ($a3) -/* 44F4 800290F4 0040302D */ daddu $a2, $v0, $zero -/* 44F8 800290F8 3C038007 */ lui $v1, %hi(D_80074270) -/* 44FC 800290FC 24634270 */ addiu $v1, $v1, %lo(D_80074270) -/* 4500 80029100 ACE50004 */ sw $a1, 4($a3) -/* 4504 80029104 94640000 */ lhu $a0, ($v1) -/* 4508 80029108 24020001 */ addiu $v0, $zero, 1 -/* 450C 8002910C A4E20008 */ sh $v0, 8($a3) -/* 4510 80029110 24820001 */ addiu $v0, $a0, 1 -/* 4514 80029114 A4620000 */ sh $v0, ($v1) -/* 4518 80029118 01091023 */ subu $v0, $t0, $t1 -/* 451C 8002911C A4E4000A */ sh $a0, 0xa($a3) -/* 4520 80029120 ACCA0000 */ sw $t2, ($a2) -/* 4524 80029124 ACC20004 */ sw $v0, 4($a2) -/* 4528 80029128 0800A455 */ j .L80029154 -/* 452C 8002912C A4C00008 */ sh $zero, 8($a2) -.L80029130: -/* 4530 80029130 3C038007 */ lui $v1, %hi(D_80074270) -/* 4534 80029134 24634270 */ addiu $v1, $v1, %lo(D_80074270) -/* 4538 80029138 ACE80004 */ sw $t0, 4($a3) -/* 453C 8002913C 94640000 */ lhu $a0, ($v1) -/* 4540 80029140 24020001 */ addiu $v0, $zero, 1 -/* 4544 80029144 A4E20008 */ sh $v0, 8($a3) -/* 4548 80029148 24820001 */ addiu $v0, $a0, 1 -/* 454C 8002914C A4620000 */ sh $v0, ($v1) -/* 4550 80029150 A4E4000A */ sh $a0, 0xa($a3) -.L80029154: -/* 4554 80029154 03E00008 */ jr $ra -/* 4558 80029158 24E20010 */ addiu $v0, $a3, 0x10 -.L8002915C: -/* 455C 8002915C 03E00008 */ jr $ra -/* 4560 80029160 0000102D */ daddu $v0, $zero, $zero diff --git a/ver/us/asm/nonmatchings/43F0/_heap_malloc_tail.s b/ver/us/asm/nonmatchings/43F0/_heap_malloc_tail.s deleted file mode 100644 index 72ab3382de..0000000000 --- a/ver/us/asm/nonmatchings/43F0/_heap_malloc_tail.s +++ /dev/null @@ -1,56 +0,0 @@ -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches - -glabel _heap_malloc_tail -/* 4564 80029164 24A5000F */ addiu $a1, $a1, 0xf -/* 4568 80029168 2402FFF0 */ addiu $v0, $zero, -0x10 -/* 456C 8002916C 00A22824 */ and $a1, $a1, $v0 -/* 4570 80029170 14A00003 */ bnez $a1, .L80029180 -/* 4574 80029174 0000402D */ daddu $t0, $zero, $zero -/* 4578 80029178 03E00008 */ jr $ra -/* 457C 8002917C 0100102D */ daddu $v0, $t0, $zero -.L80029180: -/* 4580 80029180 0000302D */ daddu $a2, $zero, $zero -/* 4584 80029184 00C0382D */ daddu $a3, $a2, $zero -.L80029188: -/* 4588 80029188 94820008 */ lhu $v0, 8($a0) -/* 458C 8002918C 14400008 */ bnez $v0, .L800291B0 -/* 4590 80029190 00000000 */ nop -/* 4594 80029194 8C830004 */ lw $v1, 4($a0) -/* 4598 80029198 0065102B */ sltu $v0, $v1, $a1 -/* 459C 8002919C 14400004 */ bnez $v0, .L800291B0 -/* 45A0 800291A0 00000000 */ nop -/* 45A4 800291A4 0080402D */ daddu $t0, $a0, $zero -/* 45A8 800291A8 0060302D */ daddu $a2, $v1, $zero -/* 45AC 800291AC 8C870000 */ lw $a3, ($a0) -.L800291B0: -/* 45B0 800291B0 8C840000 */ lw $a0, ($a0) -/* 45B4 800291B4 1480FFF4 */ bnez $a0, .L80029188 -/* 45B8 800291B8 00000000 */ nop -/* 45BC 800291BC 10C00015 */ beqz $a2, .L80029214 -/* 45C0 800291C0 24A30010 */ addiu $v1, $a1, 0x10 -/* 45C4 800291C4 00C3102B */ sltu $v0, $a2, $v1 -/* 45C8 800291C8 1440000C */ bnez $v0, .L800291FC -/* 45CC 800291CC 0100202D */ daddu $a0, $t0, $zero -/* 45D0 800291D0 00861021 */ addu $v0, $a0, $a2 -/* 45D4 800291D4 00451023 */ subu $v0, $v0, $a1 -/* 45D8 800291D8 AC820000 */ sw $v0, ($a0) -/* 45DC 800291DC 00C31023 */ subu $v0, $a2, $v1 -/* 45E0 800291E0 AC820004 */ sw $v0, 4($a0) -/* 45E4 800291E4 A4800008 */ sh $zero, 8($a0) -/* 45E8 800291E8 8C840000 */ lw $a0, ($a0) -/* 45EC 800291EC 24020001 */ addiu $v0, $zero, 1 -/* 45F0 800291F0 AC870000 */ sw $a3, ($a0) -/* 45F4 800291F4 0800A482 */ j .L80029208 -/* 45F8 800291F8 AC850004 */ sw $a1, 4($a0) -.L800291FC: -/* 45FC 800291FC 24020001 */ addiu $v0, $zero, 1 -/* 4600 80029200 AC870000 */ sw $a3, ($a0) -/* 4604 80029204 AC860004 */ sw $a2, 4($a0) -.L80029208: -/* 4608 80029208 A4820008 */ sh $v0, 8($a0) -/* 460C 8002920C 03E00008 */ jr $ra -/* 4610 80029210 24820010 */ addiu $v0, $a0, 0x10 -.L80029214: -/* 4614 80029214 03E00008 */ jr $ra -/* 4618 80029218 0000102D */ daddu $v0, $zero, $zero diff --git a/ver/us/symbol_addrs.txt b/ver/us/symbol_addrs.txt index 95f7341d74..c9c7fd8e5f 100644 --- a/ver/us/symbol_addrs.txt +++ b/ver/us/symbol_addrs.txt @@ -1304,7 +1304,7 @@ D_80074230 = 0x80074230; // type:data rom:0x4F630 D_80074260 = 0x80074260; // type:data rom:0x4F660 D_80074264 = 0x80074264; // type:data rom:0x4F664 D_80074268 = 0x80074268; // type:data rom:0x4F668 -D_80074270 = 0x80074270; // type:data rom:0x4F670 +heap_nextMallocID = 0x80074270; // type:data rom:0x4F670 D_80074274 = 0x80074274; // type:data rom:0x4F674 D_800743E0 = 0x800743E0; // type:data rom:0x4F7E0 gRandSeed = 0x80074410; // rom:0x4F810