diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index bb4594cd..070692ab 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -226,6 +226,10 @@ f/f_manager.cpp: .sbss start:0x80575BB8 end:0x80575BC0 .bss start:0x805B84D8 end:0x805B8588 +m/m_allocator.cpp: + .text start:0x802EE0E0 end:0x802EE5EC + .data start:0x80542820 end:0x80542848 + m/m_angle.cpp: .text start:0x802EE5F0 end:0x802EE6B8 .ctors start:0x804DB8CC end:0x804DB8D0 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index ea51f79e..8c3ce6c7 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -17695,21 +17695,21 @@ fn_802EE0A0 = .text:0x802EE0A0; // type:function size:0x4 fn_802EE0B0 = .text:0x802EE0B0; // type:function size:0x4 fn_802EE0C0 = .text:0x802EE0C0; // type:function size:0x4 fn_802EE0D0 = .text:0x802EE0D0; // type:function size:0x8 -fn_802EE0E0 = .text:0x802EE0E0; // type:function size:0x44 -fn_802EE130 = .text:0x802EE130; // type:function size:0x58 -fn_802EE190 = .text:0x802EE190; // type:function size:0x50 -fn_802EE1E0 = .text:0x802EE1E0; // type:function size:0x4 -fn_802EE1F0 = .text:0x802EE1F0; // type:function size:0x4 +__ct__12mAllocator_cFv = .text:0x802EE0E0; // type:function size:0x44 +__dt__12mAllocator_cFv = .text:0x802EE130; // type:function size:0x58 +attach__12mAllocator_cFPQ23EGG4Heapi = .text:0x802EE190; // type:function size:0x50 +alloc__12mAllocator_cFUl = .text:0x802EE1E0; // type:function size:0x4 +free__12mAllocator_cFPv = .text:0x802EE1F0; // type:function size:0x4 __ct__16mHeapAllocator_cFv = .text:0x802EE200; // type:function size:0x3C __dt__16mHeapAllocator_cFv = .text:0x802EE240; // type:function size:0x6C -fn_802EE2B0 = .text:0x802EE2B0; // type:function size:0x84 -fn_802EE340 = .text:0x802EE340; // type:function size:0x84 -fn_802EE3D0 = .text:0x802EE3D0; // type:function size:0x54 -fn_802EE430 = .text:0x802EE430; // type:function size:0x70 -fn_802EE4A0 = .text:0x802EE4A0; // type:function size:0x70 -fn_802EE510 = .text:0x802EE510; // type:function size:0x4C +replaceWithNewFrmHeap__16mHeapAllocator_cFlPQ23EGG4HeapPclUl = .text:0x802EE2B0; // type:function size:0x84 +replaceWithNewExpHeap__16mHeapAllocator_cFlPQ23EGG4HeapPclUl = .text:0x802EE340; // type:function size:0x84 +destroyHeap__16mHeapAllocator_cFv = .text:0x802EE3D0; // type:function size:0x54 +adjustFrmHeap__16mHeapAllocator_cFv = .text:0x802EE430; // type:function size:0x70 +adjustExpHeap__16mHeapAllocator_cFv = .text:0x802EE4A0; // type:function size:0x70 +createNewTempFrmHeap__16mHeapAllocator_cFlPQ23EGG4HeapPclUl = .text:0x802EE510; // type:function size:0x4C adjustFrmHeapRestoreCurrent__16mHeapAllocator_cFv = .text:0x802EE560; // type:function size:0x64 -fn_802EE5D0 = .text:0x802EE5D0; // type:function size:0x1C +allocOnHeap__16mHeapAllocator_cFUlP16mHeapAllocator_c = .text:0x802EE5D0; // type:function size:0x1C step__4mAngFslss = .text:0x802EE5F0; // type:function size:0xA4 __sinit_\m_angle_cpp = .text:0x802EE6A0; // type:function size:0x18 scope:local fn_802EE6C0 = .text:0x802EE6C0; // type:function size:0x114 @@ -26219,7 +26219,7 @@ alloc__Q23EGG7ExpHeapFUll = .text:0x80495D90; // type:function size:0xB8 free__Q23EGG7ExpHeapFPv = .text:0x80495E50; // type:function size:0x68 resizeForMBlock__Q23EGG7ExpHeapFPvUl = .text:0x80495EC0; // type:function size:0x8 getTotalFreeSize__Q23EGG7ExpHeapFv = .text:0x80495ED0; // type:function size:0x8 -getAllocatableSize__Q23EGG7ExpHeapFi = .text:0x80495EE0; // type:function size:0x8 +getAllocatableSize__Q23EGG7ExpHeapFl = .text:0x80495EE0; // type:function size:0x8 setGroupID__Q23EGG7ExpHeapFUs = .text:0x80495EF0; // type:function size:0x8 adjust__Q23EGG7ExpHeapFv = .text:0x80495F00; // type:function size:0x78 getSizeForMBlock__Q23EGG7ExpHeapFPCv = .text:0x80495F80; // type:function size:0x4 @@ -35714,8 +35714,8 @@ lbl_805427A8 = .data:0x805427A8; // type:object size:0x2C lbl_805427D4 = .data:0x805427D4; // type:object size:0xC lbl_805427E0 = .data:0x805427E0; // type:object size:0x10 lbl_805427F0 = .data:0x805427F0; // type:object size:0x30 -lbl_80542820 = .data:0x80542820; // type:object size:0x14 -lbl_80542834 = .data:0x80542834; // type:object size:0x14 +__vt__16mHeapAllocator_c = .data:0x80542820; // type:object size:0x14 +__vt__12mAllocator_c = .data:0x80542834; // type:object size:0x14 lbl_80542848 = .data:0x80542848; // type:object size:0x28 __vt__Q24mDvd10MyThread_c = .data:0x80542870; // type:object size:0x18 __vt__23mDvd_toMainRam_normal_c = .data:0x80542888; // type:object size:0x14 diff --git a/configure.py b/configure.py index 083b2c8c..674b9369 100644 --- a/configure.py +++ b/configure.py @@ -305,6 +305,7 @@ config.libs = [ Object(NonMatching, "f/f_base.cpp"), Object(Matching, "f/f_list.cpp"), Object(Matching, "f/f_manager.cpp"), + Object(Matching, "m/m_allocator.cpp"), Object(Matching, "m/m_angle.cpp"), Object(Matching, "m/m_dvd.cpp"), Object(Matching, "m/m_heap.cpp"), diff --git a/include/m/m_allocator.h b/include/m/m_allocator.h index d2d69cb3..e4f2a175 100644 --- a/include/m/m_allocator.h +++ b/include/m/m_allocator.h @@ -10,7 +10,7 @@ public: /* 0x08 */ virtual ~mAllocator_c(); /* 0x0C */ virtual void *alloc(u32 size); /* 0x10 */ virtual void free(void *block); - bool attach(EGG::Heap *heap, s32 align); + bool attach(EGG::Heap *heap, int align); }; class mHeapAllocator_c : public mAllocator_c { public: @@ -19,13 +19,13 @@ public: /* 0x08 */ virtual ~mHeapAllocator_c(); /* 0x0C */ // virtual void* alloc(u32 size); // see mAlloctor::alloc /* 0x10 */ // virtual void free(void* block); // see mAlloctor::free - int replaceWithNewFrmHeap(s32 size, EGG::Heap *newHeap, char *heapName, s32 align, u32 unk); - int replaceWithNewExpHeap(s32 size, EGG::Heap *newHeap, char *heapName, s32 align, u32 unk); + bool replaceWithNewFrmHeap(s32 size, EGG::Heap *newHeap, char *heapName, s32 align, u32 unk); + bool replaceWithNewExpHeap(s32 size, EGG::Heap *newHeap, char *heapName, s32 align, u32 unk); void destroyHeap(); s32 adjustFrmHeap(); s32 adjustExpHeap(); - s32 createNewTempFrmHeap(s32 size, EGG::Heap *newHeap, char *heapName, s32 align, u32 unk); + bool createNewTempFrmHeap(s32 size, EGG::Heap *newHeap, char *heapName, s32 align, u32 unk); void adjustFrmHeapRestoreCurrent(); - static void *allocOnHeap(s32 size, mHeapAllocator_c *allocator); + static void *allocOnHeap(u32 size, mHeapAllocator_c *allocator); }; #endif diff --git a/src/egg/core/eggHeap.cpp b/src/egg/core/eggHeap.cpp index 49234e0d..95590c4b 100644 --- a/src/egg/core/eggHeap.cpp +++ b/src/egg/core/eggHeap.cpp @@ -18,13 +18,15 @@ namespace EGG { /* 80576764 */ HeapCreateCallback Heap::sCreateCallback; /* 80576764 */ HeapDestroyCallback Heap::sDestroyCallback; -/* 804953f0 */ void Heap::initialize() { +/* 804953f0 */ +void Heap::initialize() { nw4r::ut::List_Init(&sHeapList, 0x1c /* todo offsetof() */); OSInitMutex(&sRootMutex); sIsHeapListInitialized = true; } -/* 80495430 */ Heap::Heap(MEMiHeapHead *head) : mHeapHandle(head), mParentBlock(nullptr), mName("NoName"), mFlag() { +/* 80495430 */ +Heap::Heap(MEMiHeapHead *head) : mHeapHandle(head), mParentBlock(nullptr), mName("NoName"), mFlag() { mFlag.value = 0; nw4r::ut::List_Init(&mChildren, 0x8 /* todo offsetof() */); OSLockMutex(&sRootMutex); @@ -32,13 +34,15 @@ namespace EGG { OSUnlockMutex(&sRootMutex); } -/* 804954c0 */ Heap::~Heap() { +/* 804954c0 */ +Heap::~Heap() { OSLockMutex(&sRootMutex); nw4r::ut::List_Remove(&sHeapList, this); OSUnlockMutex(&sRootMutex); } -/* 80495560 */ void *Heap::alloc(size_t size, int align, Heap *heap) { +/* 80495560 */ +void *Heap::alloc(size_t size, int align, Heap *heap) { Heap *currentHeap = sCurrentHeap; Thread *thread = Thread::findThread(OSGetCurrentThread()); Heap *threadHeap = nullptr; @@ -79,7 +83,8 @@ namespace EGG { return ptr; } -/* 80495690 */ Heap *Heap::findHeap(MEMiHeapHead *head) { +/* 80495690 */ +Heap *Heap::findHeap(MEMiHeapHead *head) { Heap *heap = nullptr; OSLockMutex(&sRootMutex); if (sIsHeapListInitialized) { @@ -95,7 +100,8 @@ namespace EGG { return heap; } -/* 80495730 */ Heap *Heap::findParentHeap() { +/* 80495730 */ +Heap *Heap::findParentHeap() { Heap *retHeap = nullptr; MEMiHeapHead *heap = MEMFindContainHeap(mHeapHandle); if (heap) { @@ -107,7 +113,8 @@ namespace EGG { extern "C" MEMiHeapHead *fn_803CC670(const void *memBlock); -/* 80495780 */ Heap *Heap::findContainHeap(const void *memBlock) { +/* 80495780 */ +Heap *Heap::findContainHeap(const void *memBlock) { Heap *retHeap = nullptr; MEMiHeapHead *heap = fn_803CC670(memBlock); if (heap) { @@ -117,7 +124,8 @@ extern "C" MEMiHeapHead *fn_803CC670(const void *memBlock); return retHeap; } -/* 804957c0 */ void Heap::free(void *ptr, Heap *heap) { +/* 804957c0 */ +void Heap::free(void *ptr, Heap *heap) { if (heap == nullptr) { MEMiHeapHead *iheap = fn_803CC670(ptr); if (iheap == nullptr) { @@ -132,7 +140,8 @@ extern "C" MEMiHeapHead *fn_803CC670(const void *memBlock); heap->free(ptr); } -/* 80495830 */ void Heap::dispose() { +/* 80495830 */ +void Heap::dispose() { mFlag.setBit(1); Heap *heap; while ((heap = (Heap *)nw4r::ut::List_GetFirst(&mChildren)) != nullptr) { @@ -141,14 +150,17 @@ extern "C" MEMiHeapHead *fn_803CC670(const void *memBlock); mFlag.resetBit(1); } -/* 804958a0 */ void Heap::dump() {} +/* 804958a0 */ +void Heap::dump() {} // TODO: This debugging function with stripped out error reports doesn't match yet -/* 804958b0 */ void Heap::dumpAll() { +/* 804958b0 */ +void Heap::dumpAll() { u32 mem[2] = {0, 0}; OSLockMutex(&sRootMutex); - for (Heap *heap = nullptr; heap != nullptr; heap = (Heap *)nw4r::ut::List_GetNext(&sHeapList, &heap)) { + Heap *heap = nullptr; + while ((heap = (Heap *)nw4r::ut::List_GetNext(&sHeapList, &heap)) != nullptr) { Heap *childHeap = nullptr; Heap *parentHeap = heap->findParentHeap(); if ((u32)heap < 0x90000000) { @@ -166,7 +178,8 @@ extern "C" MEMiHeapHead *fn_803CC670(const void *memBlock); OSUnlockMutex(&sRootMutex); } -/* 804959a0 */ Heap *Heap::becomeCurrentHeap() { +/* 804959a0 */ +Heap *Heap::becomeCurrentHeap() { OSLockMutex(&sRootMutex); Heap *h = sCurrentHeap; sCurrentHeap = this; @@ -174,7 +187,8 @@ extern "C" MEMiHeapHead *fn_803CC670(const void *memBlock); return h; } -/* 80495a00 */ Heap *Heap::_becomeCurrentHeapWithoutLock() { +/* 80495a00 */ +Heap *Heap::_becomeCurrentHeapWithoutLock() { Heap *h = sCurrentHeap; sCurrentHeap = this; DCStoreRange(&sCurrentHeap, sizeof(sCurrentHeap)); @@ -185,25 +199,31 @@ extern "C" MEMiHeapHead *fn_803CC670(const void *memBlock); extern "C" void MEMInitAllocatorForHeap(Allocator *alloc, s32 align, Heap *heap); // TODO this could be an inline virtual function -/* 80495a40 */ void Heap::initAllocator(Allocator *alloc, s32 align) { +/* 80495a40 */ +void Heap::initAllocator(Allocator *alloc, s32 align) { MEMInitAllocatorForHeap(alloc, align, this); } } // namespace EGG -/* 80495a60 */ void *operator new(size_t, void *p) { +/* 80495a60 */ +void *operator new(size_t, void *p) { return p; } -/* 80495a70 */ void *operator new(size_t size, EGG::Heap *heap, int align) { +/* 80495a70 */ +void *operator new(size_t size, EGG::Heap *heap, int align) { return EGG::Heap::alloc(size, align, heap); } -/* 80495a80 */ void *operator new(size_t size, EGG::Allocator *alloc) { +/* 80495a80 */ +void *operator new(size_t size, EGG::Allocator *alloc) { return MEMAllocFromAllocator(alloc->getHandle(), size); } -/* 80495a90 */ void *operator new[](size_t size, int align) { +/* 80495a90 */ +void *operator new[](size_t size, int align) { return EGG::Heap::alloc(size, align, nullptr); } -/* 80495aa0 */ void *operator new[](size_t size, EGG::Heap *heap, int align) { +/* 80495aa0 */ +void *operator new[](size_t size, EGG::Heap *heap, int align) { return EGG::Heap::alloc(size, align, heap); } diff --git a/src/m/m_allocator.cpp b/src/m/m_allocator.cpp new file mode 100644 index 00000000..e03651df --- /dev/null +++ b/src/m/m_allocator.cpp @@ -0,0 +1,104 @@ +#include +#include +#include + +// TODO this include is weird +#include +#include + +mAllocator_c::mAllocator_c() : EGG::Allocator(mHeap::g_assertHeap, 0x04) {} + +mAllocator_c::~mAllocator_c() {} + +bool mAllocator_c::attach(EGG::Heap *heap, int align) { + if (heap == nullptr) { + heap = EGG::Heap::sCurrentHeap; + } + this->align = align; + this->mHeap = heap; + heap->initAllocator(this, align); + return true; +} + +void *mAllocator_c::alloc(u32 size) { + return EGG::Allocator::alloc(size); +} + +void mAllocator_c::free(void *block) { + EGG::Allocator::free(block); +} + +mHeapAllocator_c::mHeapAllocator_c() {} +mHeapAllocator_c::~mHeapAllocator_c() { + destroyHeap(); +} + +bool mHeapAllocator_c::replaceWithNewFrmHeap(s32 size, EGG::Heap *newHeap, char *heapName, s32 align, u32 attrs) { + destroyHeap(); + EGG::Heap *heap = mHeap::createFrmHeap(size, newHeap, heapName, align, attrs); + if (heap == nullptr) { + return false; + } + attach(heap, align); + return true; +} + +bool mHeapAllocator_c::replaceWithNewExpHeap(s32 size, EGG::Heap *newHeap, char *heapName, s32 align, u32 attrs) { + destroyHeap(); + EGG::Heap *heap = mHeap::createExpHeap(size, newHeap, heapName, align, attrs); + if (heap == nullptr) { + return false; + } + attach(heap, align); + return true; +} + +void mHeapAllocator_c::destroyHeap() { + EGG::Heap *assertHeap = mHeap::g_assertHeap; + if (mHeap != assertHeap) { + mHeap->destroy(); + mHeap = assertHeap; + } +} + +inline EGG::Heap *getHeapOfKind(EGG::Heap *heap, EGG::Heap::eHeapKind kind) { + if (heap != nullptr && heap->getHeapKind() == kind) { + return heap; + } + return nullptr; +} + +s32 mHeapAllocator_c::adjustFrmHeap() { + EGG::Heap *heap = mHeap; + if (heap == mHeap::g_assertHeap) { + return 0; + } + return mHeap::adjustFrmHeap(static_cast(getHeapOfKind(heap, EGG::Heap::HEAP_KIND_FRAME))); +} + +s32 mHeapAllocator_c::adjustExpHeap() { + EGG::Heap *heap = mHeap; + if (heap == mHeap::g_assertHeap) { + return 0; + } + return mHeap::adjustExpHeap(static_cast(getHeapOfKind(heap, EGG::Heap::HEAP_KIND_EXPANDED))); +} + +bool mHeapAllocator_c::createNewTempFrmHeap(s32 size, EGG::Heap *newHeap, char *heapName, s32 align, u32 attrs) { + if (!replaceWithNewFrmHeap(size, newHeap, heapName, align, attrs)) { + return false; + } + mHeap::saveCurrentHeap(); + mHeap::setCurrentHeap(mHeap); + return true; +} + +void mHeapAllocator_c::adjustFrmHeapRestoreCurrent() { + mHeap::restoreCurrentHeap(); + EGG::Heap *heap = mHeap; + mHeap::adjustFrmHeap(static_cast(getHeapOfKind(heap, EGG::Heap::HEAP_KIND_FRAME))); +} + +void *mHeapAllocator_c::allocOnHeap(u32 size, mHeapAllocator_c *allocator) { + return allocator->alloc(size); +}