From 57bb02906eeeee0e88b6b3d8e5645c1542a5badf Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Mon, 19 Sep 2022 21:35:24 -0700 Subject: [PATCH] More allocator work Former-commit-id: 57ce723ec2d787b29c5ba3b4924842db591b4bfe --- asm/Kyoto/Alloc/CGameAllocator.s | 61 ++-- asm/Kyoto/Alloc/CMediumAllocPool.s | 61 ++-- include/Kyoto/Alloc/AllocatorCommon.hpp | 8 + include/Kyoto/Alloc/CCallStack.hpp | 15 + include/Kyoto/Alloc/CGameAllocator.hpp | 128 ++++++++ include/Kyoto/Alloc/CMediumAllocPool.hpp | 34 +++ include/Kyoto/Alloc/CSmallAllocPool.hpp | 21 +- include/Kyoto/Alloc/IAllocator.hpp | 19 +- include/Kyoto/Basics/COsContext.hpp | 8 + include/Kyoto/Basics/CStopwatch.hpp | 1 + include/MetroidPrime/CMemoryDrawEnum.hpp | 4 + include/dolphin/os.h | 9 + include/dolphin/os/OSArena.h | 1 + obj_files.mk | 2 +- src/Kyoto/Alloc/CGameAllocator.cpp | 374 +++++++++++++++++++++++ src/MetroidPrime/CMemoryDrawEnum.cpp | 28 ++ 16 files changed, 700 insertions(+), 74 deletions(-) create mode 100644 include/Kyoto/Alloc/AllocatorCommon.hpp create mode 100644 include/Kyoto/Alloc/CCallStack.hpp create mode 100644 include/Kyoto/Alloc/CGameAllocator.hpp create mode 100644 include/Kyoto/Alloc/CMediumAllocPool.hpp create mode 100644 include/MetroidPrime/CMemoryDrawEnum.hpp create mode 100644 include/dolphin/os/OSArena.h create mode 100644 src/Kyoto/Alloc/CGameAllocator.cpp create mode 100644 src/MetroidPrime/CMemoryDrawEnum.cpp diff --git a/asm/Kyoto/Alloc/CGameAllocator.s b/asm/Kyoto/Alloc/CGameAllocator.s index 45288222..97b3d376 100644 --- a/asm/Kyoto/Alloc/CGameAllocator.s +++ b/asm/Kyoto/Alloc/CGameAllocator.s @@ -3,8 +3,8 @@ .section .data .balign 8 -.global lbl_803EF6D8 -lbl_803EF6D8: +.global __vt__14CGameAllocator +__vt__14CGameAllocator: # ROM: 0x3EC6D8 .4byte 0 .4byte 0 @@ -26,11 +26,8 @@ lbl_803EF6D8: .section .sbss, "wa" .balign 8 -.global lbl_805A95D8 -lbl_805A95D8: - .skip 0x8 -.global lbl_805A95E0 -lbl_805A95E0: +.global gAllocatorTime +gAllocatorTime: .skip 0x4 .global lbl_805A95E4 lbl_805A95E4: @@ -1054,11 +1051,11 @@ lbl_80351EC0: /* 80351EC0 0034EE20 28 18 00 00 */ cmplwi r24, 0 /* 80351EC4 0034EE24 41 82 00 20 */ beq lbl_80351EE4 /* 80351EC8 0034EE28 48 03 34 F9 */ bl OSGetTick -/* 80351ECC 0034EE2C 80 0D AA 20 */ lwz r0, lbl_805A95E0@sda21(r13) +/* 80351ECC 0034EE2C 80 0D AA 20 */ lwz r0, gAllocatorTime@sda21(r13) /* 80351ED0 0034EE30 7C 99 18 50 */ subf r4, r25, r3 /* 80351ED4 0034EE34 7F 03 C3 78 */ mr r3, r24 /* 80351ED8 0034EE38 7C 00 22 14 */ add r0, r0, r4 -/* 80351EDC 0034EE3C 90 0D AA 20 */ stw r0, lbl_805A95E0@sda21(r13) +/* 80351EDC 0034EE3C 90 0D AA 20 */ stw r0, gAllocatorTime@sda21(r13) /* 80351EE0 0034EE40 48 00 02 84 */ b lbl_80352164 lbl_80351EE4: /* 80351EE4 0034EE44 38 60 00 19 */ li r3, 0x19 @@ -1073,7 +1070,7 @@ lbl_80351EF4: /* 80351F04 0034EE64 41 81 01 08 */ bgt lbl_8035200C /* 80351F08 0034EE68 57 60 07 FF */ clrlwi. r0, r27, 0x1f /* 80351F0C 0034EE6C 40 82 01 00 */ bne lbl_8035200C -/* 80351F10 0034EE70 4B FF ED CD */ bl sub_80350cdc +/* 80351F10 0034EE70 4B FF ED CD */ bl HasPuddles__16CMediumAllocPoolCFv /* 80351F14 0034EE74 54 60 06 3F */ clrlwi. r0, r3, 0x18 /* 80351F18 0034EE78 40 82 00 20 */ bne lbl_80351F38 /* 80351F1C 0034EE7C 80 7F 00 74 */ lwz r3, 0x74(r31) @@ -1081,7 +1078,7 @@ lbl_80351EF4: /* 80351F24 0034EE84 80 BF 00 78 */ lwz r5, 0x78(r31) /* 80351F28 0034EE88 38 80 10 00 */ li r4, 0x1000 /* 80351F2C 0034EE8C 38 C0 00 00 */ li r6, 0 -/* 80351F30 0034EE90 4B FF EA 61 */ bl AddPuddle__16CMediumAllocPoolFUiPvPvi +/* 80351F30 0034EE90 4B FF EA 61 */ bl AddPuddle__16CMediumAllocPoolFUiPvi /* 80351F34 0034EE94 92 FF 00 78 */ stw r23, 0x78(r31) lbl_80351F38: /* 80351F38 0034EE98 80 7F 00 74 */ lwz r3, 0x74(r31) @@ -1112,7 +1109,7 @@ lbl_80351F38: /* 80351F9C 0034EEFC 7C 05 03 78 */ mr r5, r0 /* 80351FA0 0034EF00 38 80 10 00 */ li r4, 0x1000 /* 80351FA4 0034EF04 38 C0 00 01 */ li r6, 1 -/* 80351FA8 0034EF08 4B FF E9 E9 */ bl AddPuddle__16CMediumAllocPoolFUiPvPvi +/* 80351FA8 0034EF08 4B FF E9 E9 */ bl AddPuddle__16CMediumAllocPoolFUiPvi /* 80351FAC 0034EF0C 80 7F 00 74 */ lwz r3, 0x74(r31) /* 80351FB0 0034EF10 7F 44 D3 78 */ mr r4, r26 /* 80351FB4 0034EF14 4B FF EC 85 */ bl Alloc__16CMediumAllocPoolFUi @@ -1121,11 +1118,11 @@ lbl_80351FBC: /* 80351FBC 0034EF1C 28 17 00 00 */ cmplwi r23, 0 /* 80351FC0 0034EF20 41 82 00 20 */ beq lbl_80351FE0 /* 80351FC4 0034EF24 48 03 33 FD */ bl OSGetTick -/* 80351FC8 0034EF28 80 0D AA 20 */ lwz r0, lbl_805A95E0@sda21(r13) +/* 80351FC8 0034EF28 80 0D AA 20 */ lwz r0, gAllocatorTime@sda21(r13) /* 80351FCC 0034EF2C 7C 99 18 50 */ subf r4, r25, r3 /* 80351FD0 0034EF30 7E E3 BB 78 */ mr r3, r23 /* 80351FD4 0034EF34 7C 00 22 14 */ add r0, r0, r4 -/* 80351FD8 0034EF38 90 0D AA 20 */ stw r0, lbl_805A95E0@sda21(r13) +/* 80351FD8 0034EF38 90 0D AA 20 */ stw r0, gAllocatorTime@sda21(r13) /* 80351FDC 0034EF3C 48 00 01 88 */ b lbl_80352164 lbl_80351FE0: /* 80351FE0 0034EF40 88 1F 00 7C */ lbz r0, 0x7c(r31) @@ -1229,11 +1226,11 @@ lbl_8035213C: /* 80352144 0034F0A4 7E C5 B3 78 */ mr r5, r22 /* 80352148 0034F0A8 4B FF F8 21 */ bl UpdateAllocDebugStats__14CGameAllocatorFUiUiUi /* 8035214C 0034F0AC 48 03 32 75 */ bl OSGetTick -/* 80352150 0034F0B0 80 0D AA 20 */ lwz r0, lbl_805A95E0@sda21(r13) +/* 80352150 0034F0B0 80 0D AA 20 */ lwz r0, gAllocatorTime@sda21(r13) /* 80352154 0034F0B4 7C 99 18 50 */ subf r4, r25, r3 /* 80352158 0034F0B8 38 78 00 20 */ addi r3, r24, 0x20 /* 8035215C 0034F0BC 7C 00 22 14 */ add r0, r0, r4 -/* 80352160 0034F0C0 90 0D AA 20 */ stw r0, lbl_805A95E0@sda21(r13) +/* 80352160 0034F0C0 90 0D AA 20 */ stw r0, gAllocatorTime@sda21(r13) lbl_80352164: /* 80352164 0034F0C4 BA C1 00 18 */ lmw r22, 0x18(r1) /* 80352168 0034F0C8 80 01 00 44 */ lwz r0, 0x44(r1) @@ -1502,8 +1499,8 @@ __dt__14CGameAllocatorFv: /* 80352558 0034F4B8 93 C1 00 08 */ stw r30, 8(r1) /* 8035255C 0034F4BC 7C 7E 1B 79 */ or. r30, r3, r3 /* 80352560 0034F4C0 41 82 00 50 */ beq lbl_803525B0 -/* 80352564 0034F4C4 3C 60 80 3F */ lis r3, lbl_803EF6D8@ha -/* 80352568 0034F4C8 38 03 F6 D8 */ addi r0, r3, lbl_803EF6D8@l +/* 80352564 0034F4C4 3C 60 80 3F */ lis r3, __vt__14CGameAllocator@ha +/* 80352568 0034F4C8 38 03 F6 D8 */ addi r0, r3, __vt__14CGameAllocator@l /* 8035256C 0034F4CC 90 1E 00 00 */ stw r0, 0(r30) /* 80352570 0034F4D0 80 7E 00 74 */ lwz r3, 0x74(r30) /* 80352574 0034F4D4 28 03 00 00 */ cmplwi r3, 0 @@ -1534,11 +1531,11 @@ lbl_803525B0: .global __ct__14CGameAllocatorFv __ct__14CGameAllocatorFv: /* 803525CC 0034F52C 3C A0 80 3F */ lis r5, __vt__10IAllocator@ha -/* 803525D0 0034F530 3C 80 80 3F */ lis r4, lbl_803EF6D8@ha +/* 803525D0 0034F530 3C 80 80 3F */ lis r4, __vt__14CGameAllocator@ha /* 803525D4 0034F534 38 A5 D9 C0 */ addi r5, r5, __vt__10IAllocator@l /* 803525D8 0034F538 38 00 00 00 */ li r0, 0 /* 803525DC 0034F53C 90 A3 00 00 */ stw r5, 0(r3) -/* 803525E0 0034F540 38 84 F6 D8 */ addi r4, r4, lbl_803EF6D8@l +/* 803525E0 0034F540 38 84 F6 D8 */ addi r4, r4, __vt__14CGameAllocator@l /* 803525E4 0034F544 90 83 00 00 */ stw r4, 0(r3) /* 803525E8 0034F548 98 03 00 04 */ stb r0, 4(r3) /* 803525EC 0034F54C 90 03 00 08 */ stw r0, 8(r3) @@ -1581,7 +1578,7 @@ GetMemInfoFromBlockPtr__14CGameAllocatorCFPCv: .global lbl_805AE9B8 lbl_805AE9B8: # ROM: 0x3FB258 - .4byte 0x3BA3D70A + .float 0.005 .4byte 0 @@ -1591,21 +1588,15 @@ lbl_805AE9B8: lbl_803D8248: # ROM: 0x3D5248 .asciz "" - .byte 0x3C - .asciz "SOURCE MODULE UNLOADED>" - .4byte 0x004D6564 - .asciz "iumAllocMainData " + .asciz "" + .asciz "" + .asciz "MediumAllocMainData " .asciz " - Ignore" - .byte 0x4D, 0x65 - .asciz "mHead" - .byte 0x4D, 0x65 - .asciz "mTail" - .byte 0x53, 0x6D - .asciz "allAllocMainData " + .asciz "MemHead" + .asciz "MemTail" + .asciz "SmallAllocMainData " .asciz "SmallAllocBookKeeping" - .byte 0x53, 0x6D - .asciz "allAllocClass " + .asciz "SmallAllocClass " .asciz "MediumAllocClass " - .balign 4 - .4byte 0 + .balign 8 diff --git a/asm/Kyoto/Alloc/CMediumAllocPool.s b/asm/Kyoto/Alloc/CMediumAllocPool.s index a0f08356..3fd00253 100644 --- a/asm/Kyoto/Alloc/CMediumAllocPool.s +++ b/asm/Kyoto/Alloc/CMediumAllocPool.s @@ -1,9 +1,16 @@ .include "macros.inc" +.section .sbss, "ax" +.balign 8 + +.global gMediumAllocPtr__16CMediumAllocPool +gMediumAllocPtr__16CMediumAllocPool: + .skip 0x4 + .section .text, "ax" -.global sub_80350540 -sub_80350540: +.global InitBookKeeping__18SMediumAllocPuddleFPvUi +InitBookKeeping__18SMediumAllocPuddleFPvUi: /* 80350540 0034D4A0 54 85 04 3E */ clrlwi r5, r4, 0x10 /* 80350544 0034D4A4 28 05 00 04 */ cmplwi r5, 4 /* 80350548 0034D4A8 40 80 00 48 */ bge lbl_80350590 @@ -36,8 +43,8 @@ lbl_80350590: /* 803505A8 0034D508 98 05 FF FF */ stb r0, -1(r5) /* 803505AC 0034D50C 4E 80 00 20 */ blr -.global sub_803505b0 -sub_803505b0: +.global GetBlockOffset_18SMediumAllocPuddleFCPvCPv +GetBlockOffset_18SMediumAllocPuddleFCPvCPv: /* 803505B0 0034D510 7C 03 20 50 */ subf r0, r3, r4 /* 803505B4 0034D514 2C 00 00 01 */ cmpwi r0, 1 /* 803505B8 0034D518 40 81 00 0C */ ble lbl_803505C4 @@ -66,8 +73,8 @@ lbl_80350604: /* 80350604 0034D564 54 03 04 3E */ clrlwi r3, r0, 0x10 /* 80350608 0034D568 4E 80 00 20 */ blr -.global sub_8035060c -sub_8035060c: +.global Free_18SMediumAllocPuddleFCPv +Free_18SMediumAllocPuddleFCPv: /* 8035060C 0034D56C 94 21 FF E0 */ stwu r1, -0x20(r1) /* 80350610 0034D570 7C 08 02 A6 */ mflr r0 /* 80350614 0034D574 90 01 00 24 */ stw r0, 0x24(r1) @@ -132,13 +139,13 @@ lbl_803506DC: /* 803506E8 0034D648 88 03 00 00 */ lbz r0, 0(r3) /* 803506EC 0034D64C 54 00 06 31 */ rlwinm. r0, r0, 0, 0x18, 0x18 /* 803506F0 0034D650 40 81 00 10 */ ble lbl_80350700 -/* 803506F4 0034D654 4B FF FE BD */ bl sub_803505b0 +/* 803506F4 0034D654 4B FF FE BD */ bl GetBlockOffset_18SMediumAllocPuddleFCPvCPv /* 803506F8 0034D658 7C 1D 1A 14 */ add r0, r29, r3 /* 803506FC 0034D65C 54 1D 04 3E */ clrlwi r29, r0, 0x10 lbl_80350700: /* 80350700 0034D660 7F C3 F3 78 */ mr r3, r30 /* 80350704 0034D664 57 A4 04 3E */ clrlwi r4, r29, 0x10 -/* 80350708 0034D668 4B FF FE 39 */ bl sub_80350540 +/* 80350708 0034D668 4B FF FE 39 */ bl InitBookKeeping__18SMediumAllocPuddleFPvUi /* 8035070C 0034D66C 57 80 06 3F */ clrlwi. r0, r28, 0x18 /* 80350710 0034D670 41 82 00 24 */ beq lbl_80350734 /* 80350714 0034D674 7C 1E F8 40 */ cmplw r30, r31 @@ -157,8 +164,8 @@ lbl_80350734: /* 80350740 0034D6A0 38 21 00 20 */ addi r1, r1, 0x20 /* 80350744 0034D6A4 4E 80 00 20 */ blr -.global sub_80350748 -sub_80350748: +.global FindFreeEntry__18SMediumAllocPuddleFUi +FindFreeEntry__18SMediumAllocPuddleFUi: /* 80350748 0034D6A8 94 21 FF E0 */ stwu r1, -0x20(r1) /* 8035074C 0034D6AC 7C 08 02 A6 */ mflr r0 /* 80350750 0034D6B0 90 01 00 24 */ stw r0, 0x24(r1) @@ -194,7 +201,7 @@ lbl_803507B0: lbl_803507B8: /* 803507B8 0034D718 7F 83 E3 78 */ mr r3, r28 /* 803507BC 0034D71C 7F A4 EB 78 */ mr r4, r29 -/* 803507C0 0034D720 4B FF FD F1 */ bl sub_803505b0 +/* 803507C0 0034D720 4B FF FD F1 */ bl GetBlockOffset_18SMediumAllocPuddleFCPvCPv /* 803507C4 0034D724 54 60 04 3E */ clrlwi r0, r3, 0x10 /* 803507C8 0034D728 7C 00 D8 40 */ cmplw r0, r27 /* 803507CC 0034D72C 41 80 00 24 */ blt lbl_803507F0 @@ -202,7 +209,7 @@ lbl_803507B8: /* 803507D4 0034D734 54 04 04 3F */ clrlwi. r4, r0, 0x10 /* 803507D8 0034D738 41 82 00 0C */ beq lbl_803507E4 /* 803507DC 0034D73C 7C 7C DA 14 */ add r3, r28, r27 -/* 803507E0 0034D740 4B FF FD 61 */ bl sub_80350540 +/* 803507E0 0034D740 4B FF FD 61 */ bl InitBookKeeping__18SMediumAllocPuddleFPvUi lbl_803507E4: /* 803507E4 0034D744 93 9A 00 0C */ stw r28, 0xc(r26) /* 803507E8 0034D748 7F 83 E3 78 */ mr r3, r28 @@ -235,7 +242,7 @@ FindFree__16CMediumAllocPoolFi: /* 80350838 0034D798 7C 9F 23 78 */ mr r31, r4 /* 8035083C 0034D79C 93 C1 00 08 */ stw r30, 8(r1) /* 80350840 0034D7A0 7C 7E 1B 78 */ mr r30, r3 -/* 80350844 0034D7A4 4B FF FF 05 */ bl sub_80350748 +/* 80350844 0034D7A4 4B FF FF 05 */ bl FindFreeEntry__18SMediumAllocPuddleFUi /* 80350848 0034D7A8 28 03 00 00 */ cmplwi r3, 0 /* 8035084C 0034D7AC 40 82 00 0C */ bne lbl_80350858 /* 80350850 0034D7B0 38 60 00 00 */ li r3, 0 @@ -293,8 +300,8 @@ lbl_803508F0: /* 80350904 0034D864 38 21 00 10 */ addi r1, r1, 0x10 /* 80350908 0034D868 4E 80 00 20 */ blr -.global __ct__18SMediumAllocPuddleFUiPvPv -__ct__18SMediumAllocPuddleFUiPvPv: +.global __ct__18SMediumAllocPuddleFUiPv +__ct__18SMediumAllocPuddleFUiPv: /* 8035090C 0034D86C 94 21 FF F0 */ stwu r1, -0x10(r1) /* 80350910 0034D870 7C 08 02 A6 */ mflr r0 /* 80350914 0034D874 38 E0 00 00 */ li r7, 0 @@ -321,7 +328,7 @@ __ct__18SMediumAllocPuddleFUiPvPv: /* 80350968 0034D8C8 50 C0 3E 30 */ rlwimi r0, r6, 7, 0x18, 0x18 /* 8035096C 0034D8CC 98 1F 00 20 */ stb r0, 0x20(r31) /* 80350970 0034D8D0 80 7F 00 08 */ lwz r3, 8(r31) -/* 80350974 0034D8D4 4B FF FB CD */ bl sub_80350540 +/* 80350974 0034D8D4 4B FF FB CD */ bl InitBookKeeping__18SMediumAllocPuddleFPvUi /* 80350978 0034D8D8 80 01 00 14 */ lwz r0, 0x14(r1) /* 8035097C 0034D8DC 7F E3 FB 78 */ mr r3, r31 /* 80350980 0034D8E0 83 E1 00 0C */ lwz r31, 0xc(r1) @@ -329,18 +336,18 @@ __ct__18SMediumAllocPuddleFUiPvPv: /* 80350988 0034D8E8 38 21 00 10 */ addi r1, r1, 0x10 /* 8035098C 0034D8EC 4E 80 00 20 */ blr -.global AddPuddle__16CMediumAllocPoolFUiPvPvi -AddPuddle__16CMediumAllocPoolFUiPvPvi: +.global AddPuddle__16CMediumAllocPoolFUiPvi +AddPuddle__16CMediumAllocPoolFUiPvi: /* 80350990 0034D8F0 94 21 FF C0 */ stwu r1, -0x40(r1) /* 80350994 0034D8F4 7C 08 02 A6 */ mflr r0 /* 80350998 0034D8F8 90 01 00 44 */ stw r0, 0x44(r1) /* 8035099C 0034D8FC 93 E1 00 3C */ stw r31, 0x3c(r1) /* 803509A0 0034D900 7C 7F 1B 78 */ mr r31, r3 /* 803509A4 0034D904 38 61 00 08 */ addi r3, r1, 8 -/* 803509A8 0034D908 4B FF FF 65 */ bl __ct__18SMediumAllocPuddleFUiPvPv +/* 803509A8 0034D908 4B FF FF 65 */ bl __ct__18SMediumAllocPuddleFUiPv /* 803509AC 0034D90C 7F E3 FB 78 */ mr r3, r31 /* 803509B0 0034D910 38 81 00 08 */ addi r4, r1, 8 -/* 803509B4 0034D914 48 00 00 39 */ bl sub_803509ec +/* 803509B4 0034D914 48 00 00 39 */ bl "push_back__Q24rstl53list<18SMediumAllocPuddle,Q24rstl17rmemory_allocator>FRC18SMediumAllocPuddle" /* 803509B8 0034D918 38 61 00 08 */ addi r3, r1, 8 /* 803509BC 0034D91C 38 80 FF FF */ li r4, -1 /* 803509C0 0034D920 4B FF FE E9 */ bl __dt__18SMediumAllocPuddleFv @@ -355,8 +362,8 @@ AddPuddle__16CMediumAllocPoolFUiPvPvi: /* 803509E4 0034D944 38 21 00 40 */ addi r1, r1, 0x40 /* 803509E8 0034D948 4E 80 00 20 */ blr -.global sub_803509ec -sub_803509ec: +.global "push_back__Q24rstl53list<18SMediumAllocPuddle,Q24rstl17rmemory_allocator>FRC18SMediumAllocPuddle" +"push_back__Q24rstl53list<18SMediumAllocPuddle,Q24rstl17rmemory_allocator>FRC18SMediumAllocPuddle": /* 803509EC 0034D94C 94 21 FF F0 */ stwu r1, -0x10(r1) /* 803509F0 0034D950 7C 08 02 A6 */ mflr r0 /* 803509F4 0034D954 7C 85 23 78 */ mr r5, r4 @@ -502,7 +509,7 @@ lbl_80350BB0: /* 80350BC0 0034DB20 54 00 28 34 */ slwi r0, r0, 5 /* 80350BC4 0034DB24 7C 05 00 40 */ cmplw r5, r0 /* 80350BC8 0034DB28 40 80 00 48 */ bge lbl_80350C10 -/* 80350BCC 0034DB2C 4B FF FA 41 */ bl sub_8035060c +/* 80350BCC 0034DB2C 4B FF FA 41 */ bl Free_18SMediumAllocPuddleFCPv /* 80350BD0 0034DB30 80 1F 00 20 */ lwz r0, 0x20(r31) /* 80350BD4 0034DB34 28 00 00 00 */ cmplwi r0, 0 /* 80350BD8 0034DB38 40 82 00 30 */ bne lbl_80350C08 @@ -584,8 +591,8 @@ lbl_80350CC0: /* 80350CD4 0034DC34 38 21 00 20 */ addi r1, r1, 0x20 /* 80350CD8 0034DC38 4E 80 00 20 */ blr -.global sub_80350cdc -sub_80350cdc: +.global HasPuddles__16CMediumAllocPoolCFv +HasPuddles__16CMediumAllocPoolCFv: /* 80350CDC 0034DC3C 80 63 00 14 */ lwz r3, 0x14(r3) /* 80350CE0 0034DC40 7C 03 00 D0 */ neg r0, r3 /* 80350CE4 0034DC44 7C 00 1B 78 */ or r0, r0, r3 @@ -620,7 +627,7 @@ lbl_80350D3C: /* 80350D3C 0034DC9C 7C 04 F8 40 */ cmplw r4, r31 /* 80350D40 0034DCA0 40 82 FF F0 */ bne lbl_80350D30 /* 80350D44 0034DCA4 38 00 00 00 */ li r0, 0 -/* 80350D48 0034DCA8 90 0D AA 18 */ stw r0, lbl_805A95D8@sda21(r13) +/* 80350D48 0034DCA8 90 0D AA 18 */ stw r0, gMediumAllocPtr__16CMediumAllocPool@sda21(r13) /* 80350D4C 0034DCAC 80 01 00 14 */ lwz r0, 0x14(r1) /* 80350D50 0034DCB0 83 E1 00 0C */ lwz r31, 0xc(r1) /* 80350D54 0034DCB4 83 C1 00 08 */ lwz r30, 8(r1) @@ -639,7 +646,7 @@ __ct__16CMediumAllocPoolFv: /* 80350D7C 0034DCDC 90 03 00 14 */ stw r0, 0x14(r3) /* 80350D80 0034DCE0 80 03 00 04 */ lwz r0, 4(r3) /* 80350D84 0034DCE4 90 03 00 18 */ stw r0, 0x18(r3) -/* 80350D88 0034DCE8 90 6D AA 18 */ stw r3, lbl_805A95D8@sda21(r13) +/* 80350D88 0034DCE8 90 6D AA 18 */ stw r3, gMediumAllocPtr__16CMediumAllocPool@sda21(r13) /* 80350D8C 0034DCEC 4E 80 00 20 */ blr .global "erase__Q24rstl53list<18SMediumAllocPuddle,Q24rstl17rmemory_allocator>FRCQ34rstl53list<18SMediumAllocPuddle,Q24rstl17rmemory_allocator>8iteratorRCQ34rstl53list<18SMediumAllocPuddle,Q24rstl17rmemory_allocator>8iterator" diff --git a/include/Kyoto/Alloc/AllocatorCommon.hpp b/include/Kyoto/Alloc/AllocatorCommon.hpp new file mode 100644 index 00000000..abc095dd --- /dev/null +++ b/include/Kyoto/Alloc/AllocatorCommon.hpp @@ -0,0 +1,8 @@ +#ifndef __ALLOCATORCOMMON_HPP__ +#define __ALLOCATORCOMMON_HPP__ + + +static const int kPointerSize = sizeof(void*); +static const int kPointerBits = kPointerSize * 8; + +#endif // __ALLOCATORCOMMON_HPP__ diff --git a/include/Kyoto/Alloc/CCallStack.hpp b/include/Kyoto/Alloc/CCallStack.hpp new file mode 100644 index 00000000..ed7aa49e --- /dev/null +++ b/include/Kyoto/Alloc/CCallStack.hpp @@ -0,0 +1,15 @@ +#ifndef __CCALLSTACK_HPP__ +#define __CCALLSTACK_HPP__ + +class CCallStack { +public: + CCallStack(uint lineNum, const char* lineStr, const char* type); + + const char* GetFileAndLineText() const; + const char* GetTypeText() const; +private: + const char* x0_line; + const char* x4_type; +}; + +#endif // __CCALLSTACK_HPP__ diff --git a/include/Kyoto/Alloc/CGameAllocator.hpp b/include/Kyoto/Alloc/CGameAllocator.hpp new file mode 100644 index 00000000..d65e892c --- /dev/null +++ b/include/Kyoto/Alloc/CGameAllocator.hpp @@ -0,0 +1,128 @@ +#ifndef __CGAMEALLOCATOR_HPP__ +#define __CGAMEALLOCATOR_HPP__ + +#include +#include +#include + +class CSmallAllocPool; +class CMediumAllocPool; +class COsContext; +class CGameAllocator : public IAllocator { +public: + class SGameMemInfo { + public: + SGameMemInfo(SGameMemInfo* prev, SGameMemInfo* next, SGameMemInfo* nextFree, uint len, const char* fileAndLine, const char* type) + : x0_priorGuard(0xefefefef) + , x4_len(len) + , x8_fileAndLine(fileAndLine) + , xc_type(type) + , x10_prev(prev) + , x14_next(next) + , x18_nextFree(nextFree) + , x1c_postGuard(0xeaeaeaea) {} + + SGameMemInfo* GetPrev() { return (SGameMemInfo*)((size_t)x10_prev & ~31); } + void SetPrev(SGameMemInfo* prev) { + void* ptr = x10_prev; + x10_prev = prev; + x10_prev = (SGameMemInfo*)(((size_t)ptr & 31) | ((size_t)x10_prev & ~31)); + } + SGameMemInfo* GetNext() const { return (SGameMemInfo*)((size_t)x14_next & ~31); } + void SetNext(SGameMemInfo* next) { + void* ptr = x14_next; + x14_next = next; + x14_next = (SGameMemInfo*)(((size_t)ptr & 31) | ((size_t)x14_next & ~31)); + } + u32 GetPrevMaskedFlags(); + u32 GetNextMaskedFlags(); + void SetTopOfHeapAllocated(bool topOfHeap); + size_t GetLength() const { return x4_len; } + SGameMemInfo* GetNextFree() const { return (SGameMemInfo*)((size_t)x18_nextFree & ~31); } + void SetNextFree(SGameMemInfo* info) { + void* ptr = x18_nextFree; + x18_nextFree = info; + x18_nextFree = (SGameMemInfo*)(((size_t)ptr & 31) | ((size_t)x18_nextFree & ~31)); + } + + bool IsAllocated() const { return ((size_t)x10_prev) & 1; } + private: + int x0_priorGuard; + size_t x4_len; + const char* x8_fileAndLine; + const char* xc_type; + SGameMemInfo* x10_prev; + SGameMemInfo* x14_next; + SGameMemInfo* x18_nextFree; + int x1c_postGuard; + }; + + SGameMemInfo* GetMemInfoFromBlockPtr(const void* ptr) const; + CGameAllocator(); + ~CGameAllocator(); + + bool Initialize(COsContext& ctx); + void Shutdown(); + void* Alloc(size_t, EHint, EScope, EType, const CCallStack&) override; + SGameMemInfo* FindFreeBlock(uint); + SGameMemInfo* FindFreeBlockFromTopOfHeap(uint); + uint FixupAllocPtrs(SGameMemInfo*, uint, uint, EHint, const CCallStack&); + void UpdateAllocDebugStats(unsigned int, unsigned int, unsigned int); + bool Free(const void* ptr) override; + bool FreeNormalAllocation(const void* ptr); + void ReleaseAll() override; + void* AllocSecondary(size_t, IAllocator::EHint, IAllocator::EScope, IAllocator::EType, const CCallStack&) override; + bool FreeSecondary(const void* ptr) override; + void ReleaseAllSecondary() override; + void SetOutOfMemoryCallback(FOutOfMemoryCb cb, const void* target) override; + void EnumAllocations(FEnumAllocationsCb func, const void* ptr, bool b) const override; + SAllocInfo GetAllocInfo(const void* ptr) const override; + SMetrics GetMetrics() const override; + void OffsetFakeStatics(int offset) override; + + static uint GetFreeBinEntryForSize(uint); + void AddFreeEntryToFreeList(SGameMemInfo*); + void RemoveFreeEntryFromFreeList(SGameMemInfo*); + void DumpAllocations() const; + size_t GetLargestFreeChunk() const; + +private: + SGameMemInfo** GetBinPtr(u32 bin) { return &x14_bins[bin]; } + u8 x4_; + u8 x5_; + u8 x6_; + u8 x7_; + u32 x8_heapSize; + SGameMemInfo* xc_first; + SGameMemInfo* x10_last; + SGameMemInfo* x14_bins[16]; + u32 x54_; + FOutOfMemoryCb x58_oomCallback; + const void* x5c_oomTarget; + CSmallAllocPool* x60_smallAllocPool; + void* x64_smallAllocMainData; + void* x68_smallAllocBookKeeping; + bool x6c_; + int x70_; + CMediumAllocPool* x74_mediumPool; + void* x78_; + bool x7c_; + uint x80_; + uint x84_; + uint x88_; + uint x8c_; + uint x90_heapSize2; + uint x94_; + uint x98_; + uint x9c_; + uint xa0_; + uint xa4_; + uint xa8_; + uint xac_; + mutable uint xb0_; + void* xb4_physicalAddr; + uint xb8_fakeStatics; + uint xbc_; +}; + +#endif // __CGAMEALLOCATOR_HPP__ diff --git a/include/Kyoto/Alloc/CMediumAllocPool.hpp b/include/Kyoto/Alloc/CMediumAllocPool.hpp new file mode 100644 index 00000000..bf0b7223 --- /dev/null +++ b/include/Kyoto/Alloc/CMediumAllocPool.hpp @@ -0,0 +1,34 @@ +#ifndef __CMEDIUMALLOCPOOL_HPP__ +#define __CMEDIUMALLOCPOOL_HPP__ + +#include + +class CMediumAllocPool { +public: + struct SMediumAllocPuddle { + u8 unk; + void* x4_mainData; + void* x8_bookKeeping; + void* xc_cachedBookKeepingOffset; + int x10_; + int x14_numBlocks; + int x18_numAllocs; + int x1c_numEntries; + }; + + rstl::list x0_list; + /*rstl::list_node* x18_lastNodePrev; */ + void* x18_lastNodePrev; + void* Alloc(uint size); + bool HasPuddles() const; + void AddPuddle(uint, void*, int); + void ClearPuddles(); + + s32 Free(const void* ptr); + + uint GetTotalEntries(); + uint GetNumBlocksAvailable(); + uint GetNumAllocs(); +}; + +#endif // __CMEDIUMALLOCPOOL_HPP__ diff --git a/include/Kyoto/Alloc/CSmallAllocPool.hpp b/include/Kyoto/Alloc/CSmallAllocPool.hpp index bee6d04d..8ea46da4 100644 --- a/include/Kyoto/Alloc/CSmallAllocPool.hpp +++ b/include/Kyoto/Alloc/CSmallAllocPool.hpp @@ -3,7 +3,8 @@ #include -static const int kPointerSize = sizeof(void*); +#include + class CSmallAllocPool { public: CSmallAllocPool(uint len, void* mainData, void* bookKeeping); @@ -12,13 +13,21 @@ public: bool Free(const void* ptr); private: - uint GetIndexFromPtr(const void* ptr) const { - return ((const u8*)ptr - x0_mainData) / kPointerSize; + bool PtrWithinPool(const void* ptr) const { + return u32((reinterpret_cast< const u8* >(ptr) - reinterpret_cast< u8* >(x0_mainData)) / 4) < x8_numBlocks; } + + uint GetIndexFromPtr(const void* ptr) const { return ((const u8*)ptr - x0_mainData) / kPointerSize; } long GetEntryValue(uint idx) const { return (long)*((u8*)x4_bookKeeping + idx); } - u8* GetPtrFromIndex(unsigned int idx) const { - return static_cast< u8* >(x0_mainData) + (idx << 3); - } + u8* GetPtrFromIndex(unsigned int idx) const { return static_cast< u8* >(x0_mainData) + (idx << 3); } + + uint GetNumBlocksAvailable() const { return x18_numBlocksAvailable; } + uint GetTotalEntries() const { return x8_numBlocks; } + uint GetAllocatedSize() const { return x8_numBlocks - x18_numBlocksAvailable; } + uint GetNumAllocs() const { return x1c_numAllocs; } + +private: + void* x0_mainData; void* x4_bookKeeping; int x8_numBlocks; diff --git a/include/Kyoto/Alloc/IAllocator.hpp b/include/Kyoto/Alloc/IAllocator.hpp index c8ecedfa..38d3063b 100644 --- a/include/Kyoto/Alloc/IAllocator.hpp +++ b/include/Kyoto/Alloc/IAllocator.hpp @@ -3,6 +3,7 @@ #include "Kyoto/Alloc/CMemory.hpp" #include "types.h" +#include class COsContext; class CCallStack; @@ -10,13 +11,20 @@ class CCallStack; class IAllocator { public: enum EHint { - kHI_Unk = (1 << 0), + kHI_None = 0, + kHI_TopOfHeap = (1 << 0), kHI_RoundUpLen = (1 << 1), }; + enum EScope { kSC_Unk0, + kSC_Unk1, + }; + + enum EType { + kTP_Unk0, + kTP_Unk1, }; - enum EType { kTP_Unk0 }; struct SMetrics { uint x0_heapSize; @@ -46,6 +54,7 @@ public: uint smallAllocAllocatedSize, uint smallAllocRemainingSize, uint mediumAllocNumAllocs, uint mediumAllocAllocatedSize, uint mediumAllocBlocksAvailable, uint unk10, uint unk11, uint unk12, uint mediumAllocTotalAllocated, uint fakeStatics); + SMetrics(const SMetrics& other); }; struct SAllocInfo { @@ -57,7 +66,7 @@ public: const char* x10_type; }; - typedef const bool (*FOutOfMemoryCb)(void*, uint); + typedef const bool (*FOutOfMemoryCb)(const void*, uint); typedef const bool (*FEnumAllocationsCb)(const SAllocInfo& info, const void* ptr); virtual ~IAllocator(); @@ -65,11 +74,11 @@ public: virtual void Shutdown() = 0; virtual void* Alloc(unsigned long size, EHint hint, EScope scope, EType type, const CCallStack& cs) = 0; - virtual void Free(const void* ptr) = 0; + virtual bool Free(const void* ptr) = 0; virtual void ReleaseAll() = 0; virtual void* AllocSecondary(unsigned long size, EHint hint, EScope scope, EType type, const CCallStack& cs) = 0; - virtual void FreeSecondary(const void* ptr) = 0; + virtual bool FreeSecondary(const void* ptr) = 0; virtual void ReleaseAllSecondary() = 0; virtual void SetOutOfMemoryCallback(FOutOfMemoryCb cb, const void* data) = 0; virtual void EnumAllocations(FEnumAllocationsCb func, const void* ptr, bool b) const = 0; diff --git a/include/Kyoto/Basics/COsContext.hpp b/include/Kyoto/Basics/COsContext.hpp index b821e482..21132b32 100644 --- a/include/Kyoto/Basics/COsContext.hpp +++ b/include/Kyoto/Basics/COsContext.hpp @@ -1,6 +1,8 @@ #ifndef _COSCONTEXT_HPP #define _COSCONTEXT_HPP +#include + #include "types.h" #include @@ -10,6 +12,12 @@ public: COsContext(bool, bool); ~COsContext(); + uint GetBaseFreeRam() const { + size_t hiAddr = reinterpret_cast< size_t >(x1c_arenaHi); + size_t loAddr = reinterpret_cast< size_t >(x20_arenaLo2); + return ((hiAddr & ~31) - ((loAddr + 31) & ~31)); + } + private: int x0_right; int x4_bottom; diff --git a/include/Kyoto/Basics/CStopwatch.hpp b/include/Kyoto/Basics/CStopwatch.hpp index a9a9d502..1d1d280d 100644 --- a/include/Kyoto/Basics/CStopwatch.hpp +++ b/include/Kyoto/Basics/CStopwatch.hpp @@ -39,6 +39,7 @@ public: return (mData.GetCPUCycles() - x0_startTime) / mData.GetTimerFreqO1M(); } + static void Wait(f32); private: static CSWData mData; static CStopwatch mGlobalTimer; diff --git a/include/MetroidPrime/CMemoryDrawEnum.hpp b/include/MetroidPrime/CMemoryDrawEnum.hpp new file mode 100644 index 00000000..429439c6 --- /dev/null +++ b/include/MetroidPrime/CMemoryDrawEnum.hpp @@ -0,0 +1,4 @@ +#ifndef __CMEMORYDRAWENUM_HPP__ +#define __CMEMORYDRAWENUM_HPP__ + +#endif // __CMEMORYDRAWENUM_HPP__ diff --git a/include/dolphin/os.h b/include/dolphin/os.h index 1633a3c6..738b8199 100644 --- a/include/dolphin/os.h +++ b/include/dolphin/os.h @@ -52,7 +52,16 @@ u32 __OSCoreClock AT_ADDRESS(OS_BASE_CACHED | 0x00FC); // sync with OSLoMem.h #define OSRoundUp32B(v) (((u32)(v + 31) & ~31)) +void* OSGetArenaHi(void); +void* OSGetArenaLo(void); +void OSSetArenaHi(void* newHi); +void OSSetArenaLo(void* newLo); + +void* OSAllocFromArenaLo(u32 size, u32 align); +void* OSAllocFromArenaHi(u32 size, u32 align); + OSTime OSGetTime(); +OSTick OSGetTick(); void OSReport(const char* msg, ...); void OSPanic(const char* file, int line, const char* msg, ...); diff --git a/include/dolphin/os/OSArena.h b/include/dolphin/os/OSArena.h new file mode 100644 index 00000000..8d1c8b69 --- /dev/null +++ b/include/dolphin/os/OSArena.h @@ -0,0 +1 @@ + diff --git a/obj_files.mk b/obj_files.mk index 4fcd42ce..b3e08440 100644 --- a/obj_files.mk +++ b/obj_files.mk @@ -87,7 +87,7 @@ METROIDPRIME :=\ $(BUILD_DIR)/asm/MetroidPrime/CWeaponMgr.o\ $(BUILD_DIR)/asm/MetroidPrime/ScriptObjects/CScriptPickup.o\ $(BUILD_DIR)/asm/MetroidPrime/CDamageInfo.o\ - $(BUILD_DIR)/asm/MetroidPrime/CMemoryDrawEnum.o\ + $(BUILD_DIR)/src/MetroidPrime/CMemoryDrawEnum.o\ $(BUILD_DIR)/asm/MetroidPrime/ScriptObjects/CScriptDock.o\ $(BUILD_DIR)/asm/MetroidPrime/ScriptObjects/CScriptCameraHint.o\ $(BUILD_DIR)/asm/MetroidPrime/ScriptLoader.o\ diff --git a/src/Kyoto/Alloc/CGameAllocator.cpp b/src/Kyoto/Alloc/CGameAllocator.cpp new file mode 100644 index 00000000..09b1e5d9 --- /dev/null +++ b/src/Kyoto/Alloc/CGameAllocator.cpp @@ -0,0 +1,374 @@ +#include + +#include +#include +#include +#include +#include + +/* Here just to make sure the data section matches */ +static const char* string_NULL = ""; +static const char* string_SOURCE_MODULE_UNLOADED = ""; +static const char* string_ = ""; +static int gAllocatorTime = 0; + +template < typename U1, typename U2 > +static inline U1 T_round_up(U2 val, int align) { + return (val + (align - 1)) & ~(align - 1); +} + +CGameAllocator::SGameMemInfo* CGameAllocator::GetMemInfoFromBlockPtr(const void* ptr) const { + return (SGameMemInfo*)(const_cast< u8* >(ptr) - sizeof(SGameMemInfo)); +} + +CGameAllocator::CGameAllocator() +: x4_(0) +, x8_heapSize(0) +, xc_first(nullptr) +, x10_last(nullptr) +, x54_(0) +, x58_oomCallback(nullptr) +, x5c_oomTarget(nullptr) +, x60_smallAllocPool(nullptr) +, x64_smallAllocMainData(nullptr) +, x68_smallAllocBookKeeping(nullptr) +, x6c_(false) +, x70_(0) +, x74_mediumPool(nullptr) +, x80_(0) +, x84_(0) +, x88_(0) +, x8c_(0) +, x90_heapSize2(0) +, x94_(0) +, x98_(0) +, x9c_(0) +, xa0_(0) +, xa4_(0) +, xa8_(0) +, xac_(0) +, xb0_(0) +, xb4_physicalAddr(nullptr) +, xb8_fakeStatics(0) +, xbc_(0) {} + +CGameAllocator::~CGameAllocator() { + if (x74_mediumPool) { + x74_mediumPool->ClearPuddles(); + FreeNormalAllocation(x74_mediumPool); + x74_mediumPool = nullptr; + } +} + +bool CGameAllocator::Initialize(COsContext& ctx) {} + +void CGameAllocator::Shutdown() { + ReleaseAll(); + x4_ = 0; + x54_ = 0; +} + +void* CGameAllocator::Alloc(size_t size, EHint hint, EScope scope, EType type, const CCallStack& callstack) { + OSTick startTick = OSGetTick(); + + if (hint & kHI_RoundUpLen) { + size = T_round_up< size_t, size_t >(size, 32); + } + + bool bVar1 = size <= 56 && !(hint & (kHI_RoundUpLen | kHI_TopOfHeap)) && x60_smallAllocPool; + + if (bVar1 && x70_ > 0) { + bVar1 = false; + --x70_; + } + + if (bVar1) { + void* buf = x60_smallAllocPool->Alloc(size); + u32 tmp = x60_smallAllocPool->GetAllocatedSize(); + if (xac_ < tmp) { + xac_ = tmp; + static int sLastSmallAllocSize = 0; + if (sLastSmallAllocSize + 128 < tmp) { + sLastSmallAllocSize = tmp; + } + } + + if (buf != nullptr) { + gAllocatorTime += (OSGetTick() - startTick); + return buf; + } + x70_ = 25; + x6c_ = true; + } + + if (x74_mediumPool && size <= 0x400 && !(hint & kHI_TopOfHeap)) { + void* buf = nullptr; + if (!x74_mediumPool->HasPuddles()) { + void* ptr = x78_; + uint puddleSize = 0x1000; + x74_mediumPool->AddPuddle(puddleSize, ptr, 0); + x78_ = nullptr; + } + + buf = x74_mediumPool->Alloc(size); + + if (buf == nullptr) { + buf = Alloc(0x21000, kHI_None, kSC_Unk1, kTP_Unk0, CCallStack(-1, "MediumAllocMainData ", " - Ignore")); + x74_mediumPool->AddPuddle(0x1000, buf, 1); + buf = x74_mediumPool->Alloc(size); + } + + if (buf != nullptr) { + gAllocatorTime += OSGetTick() - startTick; + return buf; + } + + if (!x7c_) { + x74_mediumPool->GetTotalEntries(); + x74_mediumPool->GetNumAllocs(); + x74_mediumPool->GetNumBlocksAvailable(); + } + x7c_ = true; + } + + size_t roundedSize = T_round_up< size_t, size_t >(size, 32); + SGameMemInfo* info = nullptr; + + if (hint & kHI_TopOfHeap) { + info = FindFreeBlockFromTopOfHeap(roundedSize); + } else { + info = FindFreeBlock(roundedSize); + } + + if (info == nullptr) { + void* mediumBuf = nullptr; + if (x58_oomCallback) { + x58_oomCallback(x5c_oomTarget, size); + } + + static bool bTriedCallback = false; + + if (!bTriedCallback) { + bTriedCallback = true; + mediumBuf = (SGameMemInfo*)Alloc(size, hint, scope, type, callstack); + bTriedCallback = false; + } else { + return nullptr; + } + + if (mediumBuf == nullptr) { + callstack.GetFileAndLineText(); + callstack.GetTypeText(); + DumpAllocations(); + mediumBuf = nullptr; + return nullptr; + } + return mediumBuf; + } + + uint tmp = FixupAllocPtrs(info, size, roundedSize, hint, callstack); + if ((hint & kHI_TopOfHeap) != 0u && !info->IsAllocated()) { + info = info->GetNext(); + } + + UpdateAllocDebugStats(size, roundedSize, tmp); + gAllocatorTime += OSGetTick() - startTick; + ((u8*)info) += sizeof(SGameMemInfo); + return info; +} + +CGameAllocator::SGameMemInfo* CGameAllocator::FindFreeBlock(uint) {} + +CGameAllocator::SGameMemInfo* CGameAllocator::FindFreeBlockFromTopOfHeap(uint size) { + SGameMemInfo* iter = x10_last; + SGameMemInfo* ret = nullptr; + + while (iter != nullptr) { + if (!iter->IsAllocated() && iter->GetLength() >= size) { + ret = iter; + break; + } + iter = iter->GetPrev(); + } + + RemoveFreeEntryFromFreeList(ret); + return ret; +} + +uint CGameAllocator::FixupAllocPtrs(SGameMemInfo*, uint, uint, EHint, const CCallStack&) {} + +void CGameAllocator::UpdateAllocDebugStats(uint len, uint roundedLen, uint offset) { + ++x84_; + ++x80_; + x88_ += len; + x8c_ += roundedLen + offset; + x90_heapSize2 -= roundedLen + offset; + + if (x84_ > x94_) { + x94_ = x84_; + } + + if (x8c_ > x98_) { + x98_ = x8c_; + } + + if (len < x9c_) { + x9c_ = len; + } + + if (len > xa0_) { + xa0_ = len; + } + xa4_ = (len + xa4_ * (x80_ - 1)) / x80_; + if (len > 56) { + return; + } + + ++xa8_; +} + +bool CGameAllocator::Free(const void* ptr) { + if (ptr == nullptr) { + return true; + } + + if (x60_smallAllocPool && x60_smallAllocPool->PtrWithinPool(ptr)) { + return x60_smallAllocPool->Free(ptr); + } + + if (x74_mediumPool) { + int tmp = x74_mediumPool->Free(ptr); + if (tmp != 1) { + return tmp > 0; + } + } + return FreeNormalAllocation(ptr); +} + +bool CGameAllocator::FreeNormalAllocation(const void*) { return true; }; + +void CGameAllocator::ReleaseAll() { + if (x74_mediumPool) { + x74_mediumPool->ClearPuddles(); + FreeNormalAllocation(x74_mediumPool); + x74_mediumPool = nullptr; + } + + SGameMemInfo* iter = xc_first; + while (iter != nullptr) { + SGameMemInfo* next = iter->GetNext(); + if (iter->IsAllocated()) { + FreeNormalAllocation(((u8*)iter) + sizeof(SGameMemInfo)); + } + iter = next; + } + + xc_first = nullptr; + x10_last = nullptr; +}; + +void* CGameAllocator::AllocSecondary(size_t size, EHint hint, EScope scope, EType type, const CCallStack& callstack) { + Alloc(size, hint, scope, type, callstack); +}; + +bool CGameAllocator::FreeSecondary(const void* ptr) { return Free(ptr); }; + +void CGameAllocator::ReleaseAllSecondary(){}; + +void CGameAllocator::SetOutOfMemoryCallback(FOutOfMemoryCb cb, const void* target) { + x58_oomCallback = cb; + x5c_oomTarget = target; +}; + +IAllocator::SAllocInfo CGameAllocator::GetAllocInfo(const void* ptr) const {}; + +IAllocator::SMetrics CGameAllocator::GetMetrics() const { + u32 mediumAllocTotalAllocated = x74_mediumPool != nullptr ? x74_mediumPool->GetTotalEntries() * 32 : 0; + u32 mediumAllocBlocksAvailable = x74_mediumPool != nullptr ? x74_mediumPool->GetNumBlocksAvailable() : 0; + u32 mediumAllocAllocatedSize = + x74_mediumPool != nullptr ? x74_mediumPool->GetTotalEntries() - x74_mediumPool->GetNumBlocksAvailable() : 0; + u32 mediumAllocNumAllocs = x74_mediumPool != nullptr ? x74_mediumPool->GetNumAllocs() : 0; + SMetrics ret(x8_heapSize, x80_, x84_, x88_, x8c_, x90_heapSize2, x94_, x98_, x9c_, xa0_, xa4_, + x60_smallAllocPool != nullptr ? x60_smallAllocPool->GetNumAllocs() : 0, + x60_smallAllocPool != nullptr ? x60_smallAllocPool->GetAllocatedSize() : 0, + x60_smallAllocPool != nullptr ? x60_smallAllocPool->GetNumBlocksAvailable() : 0, mediumAllocNumAllocs, + mediumAllocAllocatedSize, mediumAllocBlocksAvailable, x80_ - xb0_, (uint)xb4_physicalAddr, xbc_, mediumAllocTotalAllocated, + xb8_fakeStatics); + xb0_ = x80_; + return ret; +}; + +void CGameAllocator::EnumAllocations(FEnumAllocationsCb func, const void* ptr, bool b) const {}; + +uint CGameAllocator::GetFreeBinEntryForSize(uint size) { + uint maxLen = 0x20; + uint bin = 0; + + while (maxLen < 0x200000) { + if (size < maxLen) { + return bin; + } + + maxLen <<= 1; + ++bin; + } + + return 0xf; +} + +void CGameAllocator::AddFreeEntryToFreeList(SGameMemInfo* info) { + uint bin = GetFreeBinEntryForSize(info->GetLength()); + info->SetNextFree(x14_bins[bin]); + x14_bins[bin] = info; +} + +void CGameAllocator::RemoveFreeEntryFromFreeList(SGameMemInfo* memInfo) { + u32 bin = GetFreeBinEntryForSize(memInfo->GetLength()); + SGameMemInfo* curBin = nullptr; + SGameMemInfo* binIt = x14_bins[bin]; + + while (binIt != nullptr) { + if (binIt == memInfo) { + if (curBin == nullptr) { + x14_bins[bin] = binIt->GetNextFree(); + } else { + curBin->SetNextFree(binIt->GetNextFree()); + } + return; + } + + curBin = binIt; + binIt = binIt->GetNextFree(); + } +} + +static inline bool DoWait(int v) { return (v % 4) == 0; } + +void CGameAllocator::DumpAllocations() const { + GetLargestFreeChunk(); + u32 i = 0; + SGameMemInfo* iter = xc_first; + + while (iter != nullptr) { + ++i; + + if (DoWait(i)) { + CStopwatch::Wait(0.005f); + } + iter = iter->GetNext(); + } +} + +size_t CGameAllocator::GetLargestFreeChunk() const { + SGameMemInfo* iter = xc_first; + size_t ret = 0; + while (iter != nullptr) { + if (!iter->IsAllocated() && iter->GetLength() > ret) { + ret = iter->GetLength(); + } + iter = iter->GetNextFree(); + } + + return ret; +} +void CGameAllocator::OffsetFakeStatics(int offset) { xb8_fakeStatics += offset; }; diff --git a/src/MetroidPrime/CMemoryDrawEnum.cpp b/src/MetroidPrime/CMemoryDrawEnum.cpp new file mode 100644 index 00000000..23727790 --- /dev/null +++ b/src/MetroidPrime/CMemoryDrawEnum.cpp @@ -0,0 +1,28 @@ +//#include +#include + + +/* ODR strikes again! */ +IAllocator::SMetrics::SMetrics(const SMetrics& other) +: x0_heapSize(other.x0_heapSize) +, x4_(other.x4_) +, x8_(other.x8_) +, xc_(other.xc_) +, x10_(other.x10_) +, x14_heapSize2(other.x14_heapSize2) +, x18_(other.x18_) +, x1c_(other.x1c_) +, x20_(other.x20_) +, x24_(other.x24_) +, x28_(other.x28_) +, x2c_smallNumAllocs(other.x2c_smallNumAllocs) +, x30_smallAllocatedSize(other.x30_smallAllocatedSize) +, x34_smallRemainingSize(other.x34_smallRemainingSize) +, x38_mediumNumAllocs(other.x38_mediumNumAllocs) +, x3c_mediumAllocatedSize(other.x3c_mediumAllocatedSize) +, x40_mediumBlocksAvailable(other.x40_mediumBlocksAvailable) +, x44_(other.x44_) +, x48_(other.x48_) +, x4c_(other.x4c_) +, x50_mediumTotalAllocated(other.x50_mediumTotalAllocated) +, x54_fakeStatics(other.x54_fakeStatics) {}