mirror of https://github.com/AxioDL/metaforce.git
More Allocator work, fully working CSmallAllocPool
This commit is contained in:
parent
4ba5db133d
commit
d9d79a460b
|
@ -23,24 +23,80 @@ u32 CGameAllocator::GetFreeBinEntryForSize(size_t len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CGameAllocator::Initialize() { return true; }
|
bool CGameAllocator::Initialize() { return true; }
|
||||||
|
|
||||||
void* CGameAllocator::Alloc() { return nullptr; }
|
void* CGameAllocator::Alloc() { return nullptr; }
|
||||||
s32 CGameAllocator::Free(void* ptr) { return 0; }
|
bool CGameAllocator::Free(void* ptr) { return 0; }
|
||||||
void CGameAllocator::ReleaseAll() {}
|
void CGameAllocator::ReleaseAll() {}
|
||||||
void CGameAllocator::AllocSecondary() {}
|
void CGameAllocator::AllocSecondary() {}
|
||||||
void CGameAllocator::FreeSecondary() {}
|
void CGameAllocator::FreeSecondary() {}
|
||||||
void CGameAllocator::ReleaseAllSecondary() {}
|
void CGameAllocator::ReleaseAllSecondary() {}
|
||||||
void CGameAllocator::SetOutOfMemoryCallback() {}
|
|
||||||
void CGameAllocator::EnumAllocations() {}
|
void CGameAllocator::SetOutOfMemoryCallback(IAllocator::FOutOfMemoryCb cb, void* target) {
|
||||||
|
x58_oomCallBack = cb;
|
||||||
|
x5c_oomTarget = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 CGameAllocator::EnumAllocations(IAllocator::FEnumAllocationsCb cb, const void* ptr, bool b) {
|
||||||
|
s32 ret = 0;
|
||||||
|
SAllocInfo info;
|
||||||
|
info.x0_infoPtr = xc_first;
|
||||||
|
while (true) {
|
||||||
|
if (info.x0_infoPtr == nullptr) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (static_cast<SGameMemInfo*>(info.x0_infoPtr)->x1c_postGuard != 0xeaeaeaea) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (static_cast<SGameMemInfo*>(info.x0_infoPtr)->x0_priorGuard != 0xefefefef) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* next = static_cast<SGameMemInfo*>(info.x0_infoPtr)->GetNext();
|
||||||
|
info.x10_type = static_cast<SGameMemInfo*>(info.x0_infoPtr)->xc_type;
|
||||||
|
info.x8_hasPrevious = static_cast<SGameMemInfo*>(info.x0_infoPtr)->x10_prev != nullptr;
|
||||||
|
info.xc_fileAndLne = static_cast<SGameMemInfo*>(info.x0_infoPtr)->x8_fileAndLine;
|
||||||
|
info.x4_len = static_cast<SGameMemInfo*>(info.x0_infoPtr)->x4_len;
|
||||||
|
info.x9_ = false;
|
||||||
|
(*cb)(info, ptr);
|
||||||
|
|
||||||
|
++ret;
|
||||||
|
info.x0_infoPtr = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(next) & ~sizeof(SGameMemInfo));
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
IAllocator::SAllocInfo CGameAllocator::GetAllocInfo(void* ptr) {
|
IAllocator::SAllocInfo CGameAllocator::GetAllocInfo(void* ptr) {
|
||||||
SGameMemInfo* info = GetMemInfoFromBlockPtr(ptr);
|
SGameMemInfo* info = GetMemInfoFromBlockPtr(ptr);
|
||||||
return {.x0_infoPtr = info,
|
return {.x0_infoPtr = info,
|
||||||
.x4_len = info->x4_len,
|
.x4_len = info->x4_len,
|
||||||
.x8_hasPrevious = info->x10_prev != nullptr,
|
.x8_hasPrevious = info->x10_prev != nullptr,
|
||||||
.x9_ = false,
|
.x9_ = false,
|
||||||
.xc_fileAndLne = info->x8_line,
|
.xc_fileAndLne = info->x8_fileAndLine,
|
||||||
.x10_type = info->xc_type};
|
.x10_type = info->xc_type};
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameAllocator::OffsetFakeStatics(s32 offset) { xb8_fakeStatics += offset; }
|
void CGameAllocator::OffsetFakeStatics(s32 offset) { xb8_fakeStatics += offset; }
|
||||||
void CGameAllocator::GetMetrics() {}
|
IAllocator::SMetrics CGameAllocator::GetMetrics() {
|
||||||
|
u32 mediumAllocTotalAllocated = x74_mediumPool == nullptr ? 0 : x74_mediumPool->GetTotalEntries();
|
||||||
|
u32 mediumAllocBlocksAvailable = x74_mediumPool == nullptr ? 0 : x74_mediumPool->GetNumBlocksAvailable();
|
||||||
|
u32 mediumAllocAllocatedSize =
|
||||||
|
x74_mediumPool == nullptr ? 0 : x74_mediumPool->GetTotalEntries() - x74_mediumPool->GetNumBlocksAvailable();
|
||||||
|
u32 mediumAllocNumAllocs = x74_mediumPool == nullptr ? 0 : x74_mediumPool->GetNumAllocs();
|
||||||
|
|
||||||
|
u32 smallAllocRemainingSize = 0;
|
||||||
|
u32 smallAllocAllocatedSize = 0;
|
||||||
|
u32 smallAllocNumAllocs = 0;
|
||||||
|
if (x60_smallPool == nullptr) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
smallAllocRemainingSize = x60_smallPool->GetNumBlocksAvailable();
|
||||||
|
smallAllocAllocatedSize = x60_smallPool->GetTotalEntries();
|
||||||
|
smallAllocNumAllocs = x60_smallPool->GetNumAllocs();
|
||||||
|
}
|
||||||
|
|
||||||
|
return SMetrics(x8_heapSize, x80_, x84_, x88_, x8c_, x90_heapSize2, x94_, x98_, x9c_, xa0_, xa4_, smallAllocNumAllocs,
|
||||||
|
smallAllocAllocatedSize, smallAllocRemainingSize, mediumAllocNumAllocs, mediumAllocAllocatedSize,
|
||||||
|
mediumAllocBlocksAvailable, x80_ - xb0_, xb4_, xbc_, mediumAllocTotalAllocated, xb8_fakeStatics);
|
||||||
|
}
|
||||||
} // namespace metaforce
|
} // namespace metaforce
|
||||||
|
|
|
@ -4,76 +4,75 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "Runtime/IAllocator.hpp"
|
||||||
#include "Runtime/RetroTypes.hpp"
|
#include "Runtime/RetroTypes.hpp"
|
||||||
|
#include "Runtime/CSmallAllocPool.hpp"
|
||||||
|
#include "Runtime/CMediumAllocPool.hpp"
|
||||||
|
|
||||||
namespace metaforce {
|
namespace metaforce {
|
||||||
class CCallStack {
|
|
||||||
const char* x0_line;
|
|
||||||
const char* x4_type;
|
|
||||||
|
|
||||||
public:
|
|
||||||
CCallStack(int lineNum, const char* lineStr, const char* type) : x0_line(lineStr), x4_type(type) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class EHint {
|
|
||||||
Unk = (1 << 0),
|
|
||||||
RoundUpLen = (1 << 1),
|
|
||||||
};
|
|
||||||
|
|
||||||
ENABLE_BITWISE_ENUM(EHint);
|
|
||||||
|
|
||||||
enum class EScope {
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class EType {
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class IAllocator {
|
|
||||||
public:
|
|
||||||
struct SAllocInfo {
|
|
||||||
void* x0_infoPtr;
|
|
||||||
size_t x4_len;
|
|
||||||
bool x8_hasPrevious;
|
|
||||||
bool x9_;
|
|
||||||
const char* xc_fileAndLne;
|
|
||||||
const char* x10_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
virtual bool Initialize() = 0; // const COSContext& ctx) = 0;
|
|
||||||
|
|
||||||
virtual void* Alloc(size_t size) = 0;
|
|
||||||
virtual bool Free(void* ptr) = 0;
|
|
||||||
virtual void ReleaseAll() = 0;
|
|
||||||
virtual void* AllocSecondary(size_t size) = 0;
|
|
||||||
virtual bool FreeSecondary(void* ptr) = 0;
|
|
||||||
virtual void ReleaseAllSecondary() = 0;
|
|
||||||
virtual void SetOutOfMemoryCallback() = 0;
|
|
||||||
virtual void EnumAllocations() = 0;
|
|
||||||
virtual SAllocInfo GetAllocInfo(void* ptr) = 0;
|
|
||||||
virtual void OffsetFakeStatics(s32 offset) = 0;
|
|
||||||
virtual void GetMetrics() = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class CGameAllocator : public IAllocator {
|
class CGameAllocator : public IAllocator {
|
||||||
struct SGameMemInfo {
|
public:
|
||||||
u32 x0_sentinel = 0xefefefef;
|
private:
|
||||||
|
class SGameMemInfo {
|
||||||
|
public:
|
||||||
|
u32 x0_priorGuard = 0xefefefef;
|
||||||
size_t x4_len = 0;
|
size_t x4_len = 0;
|
||||||
const char* x8_line;
|
const char* x8_fileAndLine;
|
||||||
const char* xc_type;
|
const char* xc_type;
|
||||||
SGameMemInfo* x10_prev = nullptr;
|
void* x10_prev = nullptr;
|
||||||
void* x14_ = nullptr;
|
void* x14_next = nullptr;
|
||||||
void* x18_ = nullptr;
|
void* x18_ = nullptr;
|
||||||
u32 x1c_canary = 0xeaeaeaea;
|
u32 x1c_postGuard = 0xeaeaeaea;
|
||||||
|
public:
|
||||||
|
void* GetPrev() { return x10_prev; }
|
||||||
|
void SetPrev(void* prev) { x10_prev = prev; }
|
||||||
|
void* GetNext() { return x14_next; }
|
||||||
|
void SetNext(void* next) { x14_next = next; }
|
||||||
|
u32 GetPrevMaskedFlags();
|
||||||
|
u32 GetNextMaskedFlags();
|
||||||
|
void SetTopOfHeapAllocated(bool topOfHeap);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
u8 x4_;
|
||||||
|
u8 x5_;
|
||||||
|
u8 x6_;
|
||||||
|
u8 x7_;
|
||||||
|
u32 x8_heapSize;
|
||||||
|
SGameMemInfo* xc_first;
|
||||||
|
SGameMemInfo* x10_last;
|
||||||
|
std::array<SGameMemInfo*, 16> x14_bins;
|
||||||
|
u32 x54_;
|
||||||
|
FOutOfMemoryCb x58_oomCallBack;
|
||||||
|
void* x5c_oomTarget;
|
||||||
|
std::unique_ptr<CSmallAllocPool> x60_smallPool;
|
||||||
|
void* x64_smallAllocBookKeeping;
|
||||||
|
void* x68_smallAllocMainData;
|
||||||
|
bool x6c_;
|
||||||
|
u32 x70_;
|
||||||
|
std::unique_ptr<CMediumAllocPool> x74_mediumPool;
|
||||||
|
void* x78_;
|
||||||
|
bool x7c_;
|
||||||
|
u32 x80_;
|
||||||
|
u32 x84_;
|
||||||
|
u32 x88_;
|
||||||
|
u32 x8c_;
|
||||||
|
u32 x90_heapSize2;
|
||||||
|
u32 x94_;
|
||||||
|
u32 x98_;
|
||||||
|
u32 x9c_;
|
||||||
|
u32 xa0_;
|
||||||
|
u32 xa4_;
|
||||||
|
u32 xa8_;
|
||||||
|
u32 xac_;
|
||||||
|
u32 xb0_;
|
||||||
|
u32 xb4_;
|
||||||
|
u32 xb8_fakeStatics = 0;
|
||||||
|
u32 xbc_;
|
||||||
|
|
||||||
static u32 GetFreeBinEntryForSize(size_t len);
|
static u32 GetFreeBinEntryForSize(size_t len);
|
||||||
SGameMemInfo* GetMemInfoFromBlockPtr(void* ptr) {
|
SGameMemInfo* GetMemInfoFromBlockPtr(void* ptr) {
|
||||||
return reinterpret_cast<SGameMemInfo*>(reinterpret_cast<void*>(intptr_t(ptr) - sizeof(SGameMemInfo)));
|
return reinterpret_cast<SGameMemInfo*>(reinterpret_cast<void*>(intptr_t(ptr) - sizeof(SGameMemInfo)));
|
||||||
}
|
}
|
||||||
std::array<SGameMemInfo*, 16> x14_bins;
|
|
||||||
|
|
||||||
s32 xb8_fakeStatics = 0;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool Initialize() override; // const COsContext& ctx);
|
bool Initialize() override; // const COsContext& ctx);
|
||||||
|
@ -83,10 +82,13 @@ public:
|
||||||
void* AllocSecondary(size_t size) override;
|
void* AllocSecondary(size_t size) override;
|
||||||
bool FreeSecondary(void* ptr) override;
|
bool FreeSecondary(void* ptr) override;
|
||||||
void ReleaseAllSecondary() override;
|
void ReleaseAllSecondary() override;
|
||||||
void SetOutOfMemoryCallback() override;
|
void SetOutOfMemoryCallback(FOutOfMemoryCb cb, void* target) override;
|
||||||
void EnumAllocations() override;
|
s32 EnumAllocations(IAllocator::FEnumAllocationsCb cb, const void* ptr, bool b) override;
|
||||||
SAllocInfo GetAllocInfo(void* ptr) override;
|
SAllocInfo GetAllocInfo(void* ptr) override;
|
||||||
void OffsetFakeStatics(s32 offset) override;
|
void OffsetFakeStatics(s32 offset) override;
|
||||||
void GetMetrics() override;
|
SMetrics GetMetrics() override;
|
||||||
|
void AllocSecondary();
|
||||||
|
void FreeSecondary();
|
||||||
|
void* Alloc();
|
||||||
};
|
};
|
||||||
} // namespace metaforce
|
} // namespace metaforce
|
||||||
|
|
|
@ -73,6 +73,9 @@ set(RUNTIME_SOURCES_B
|
||||||
ITweak.hpp
|
ITweak.hpp
|
||||||
IMain.hpp
|
IMain.hpp
|
||||||
CStopwatch.hpp
|
CStopwatch.hpp
|
||||||
|
IAllocator.hpp IAllocator.cpp
|
||||||
|
CSmallAllocPool.hpp CSmallAllocPool.cpp
|
||||||
|
CMediumAllocPool.hpp CMediumAllocPool.cpp
|
||||||
CGameAllocator.hpp CGameAllocator.cpp
|
CGameAllocator.hpp CGameAllocator.cpp
|
||||||
CMemoryCardSys.hpp CMemoryCardSys.cpp
|
CMemoryCardSys.hpp CMemoryCardSys.cpp
|
||||||
CScannableObjectInfo.hpp CScannableObjectInfo.cpp
|
CScannableObjectInfo.hpp CScannableObjectInfo.cpp
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
#include "CMediumAllocPool.hpp"
|
||||||
|
|
||||||
|
namespace metaforce {
|
||||||
|
|
||||||
|
//CMediumAllocPool::CMediumAllocPool()
|
||||||
|
u32 CMediumAllocPool::GetTotalEntries() const {
|
||||||
|
u32 ret = 0;
|
||||||
|
for (const auto& puddle : x0_puddles) {
|
||||||
|
ret += puddle.x1c_numEntries;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 CMediumAllocPool::GetNumBlocksAvailable() const {
|
||||||
|
u32 ret = 0;
|
||||||
|
for (const auto& puddle : x0_puddles) {
|
||||||
|
ret += puddle.x14_numBlocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 CMediumAllocPool::GetNumAllocs() const {
|
||||||
|
u32 ret = 0;
|
||||||
|
for (const auto& puddle : x0_puddles) {
|
||||||
|
ret += puddle.x18_numAllocs;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
#pragma once
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
#include <GCNTypes.hpp>
|
||||||
|
|
||||||
|
namespace metaforce {
|
||||||
|
class CMediumAllocPool {
|
||||||
|
struct SMediumAllocPuddle {
|
||||||
|
u8 x0_;
|
||||||
|
void* x4_;
|
||||||
|
void* x8_;
|
||||||
|
void* xc_;
|
||||||
|
u32 x10_;
|
||||||
|
u32 x14_numBlocks;
|
||||||
|
u32 x18_numAllocs;
|
||||||
|
u32 x1c_numEntries;
|
||||||
|
u8 x20_;
|
||||||
|
};
|
||||||
|
std::list<SMediumAllocPuddle> x0_puddles;
|
||||||
|
std::list<SMediumAllocPuddle>::iterator x18_lastAlloc;
|
||||||
|
public:
|
||||||
|
//CMediumAllocPool();
|
||||||
|
|
||||||
|
u32 GetTotalEntries() const;
|
||||||
|
u32 GetNumBlocksAvailable() const;
|
||||||
|
u32 GetNumAllocs() const;
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,131 @@
|
||||||
|
#include "CSmallAllocPool.hpp"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
namespace metaforce {
|
||||||
|
CSmallAllocPool::CSmallAllocPool(u32 len, void* mainData, void* bookKeeping)
|
||||||
|
: x0_mainData(mainData), x4_bookKeeping(bookKeeping), x8_numBlocks(len), x18_numBlocksAvailable(len) {
|
||||||
|
memset(x4_bookKeeping, 0, len / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* CSmallAllocPool::FindFree(u32 len) {
|
||||||
|
if (xc_cachedBookKeepingOffset == nullptr) {
|
||||||
|
xc_cachedBookKeepingOffset = x4_bookKeeping;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* curKeepingOffset = static_cast<u8*>(xc_cachedBookKeepingOffset);
|
||||||
|
auto* bookKeepingPtr = static_cast<u8*>(x4_bookKeeping);
|
||||||
|
auto* bookKeepingEndPtr = bookKeepingPtr + (x8_numBlocks >> 1);
|
||||||
|
auto* curKeepingIter = curKeepingOffset;
|
||||||
|
while (true) {
|
||||||
|
u8* tmpIter = nullptr;
|
||||||
|
if (static_cast<u8*>(curKeepingIter)[0] == 0 && curKeepingIter != bookKeepingEndPtr) {
|
||||||
|
tmpIter = curKeepingIter;
|
||||||
|
do {
|
||||||
|
++tmpIter;
|
||||||
|
if (tmpIter == curKeepingOffset || tmpIter == bookKeepingEndPtr || tmpIter == curKeepingIter + len / 2) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (static_cast<u8*>(tmpIter)[0] == 0);
|
||||||
|
|
||||||
|
if (tmpIter == curKeepingIter + len / 2) {
|
||||||
|
if (tmpIter == bookKeepingEndPtr) {
|
||||||
|
xc_cachedBookKeepingOffset = bookKeepingPtr;
|
||||||
|
} else {
|
||||||
|
xc_cachedBookKeepingOffset = curKeepingIter;
|
||||||
|
}
|
||||||
|
return curKeepingIter;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tmpIter == curKeepingOffset) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
if (tmpIter == bookKeepingEndPtr) {
|
||||||
|
tmpIter = bookKeepingPtr;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tmpIter = bookKeepingPtr;
|
||||||
|
if (curKeepingIter != bookKeepingEndPtr) {
|
||||||
|
u32 tmp = static_cast<u8*>(curKeepingIter)[0];
|
||||||
|
tmpIter = curKeepingIter + (tmp >> 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
curKeepingIter = tmpIter;
|
||||||
|
if (tmpIter == curKeepingOffset) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void* CSmallAllocPool::Alloc(uint32_t size) {
|
||||||
|
uint32_t len = 1;
|
||||||
|
if (size > 3) {
|
||||||
|
len = (size + 3) / 4;
|
||||||
|
}
|
||||||
|
if ((len & 1) != 0) {
|
||||||
|
len += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* freePtr = static_cast<uint8_t*>(FindFree(len));
|
||||||
|
if (freePtr == nullptr) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* bookKeepingStart = static_cast<uint8_t*>(x4_bookKeeping);
|
||||||
|
uint32_t blockCount = (len - 2) / 2;
|
||||||
|
auto* bufPtr = static_cast<uint8_t*>(x0_mainData);
|
||||||
|
|
||||||
|
static_cast<uint8_t*>(freePtr)[0] = (len << 4) | 0xf;
|
||||||
|
uint8_t* freePtrIter = freePtr + 1;
|
||||||
|
if (blockCount != 0) {
|
||||||
|
uint32_t uVar5 = blockCount >> 3;
|
||||||
|
if (uVar5 != 0) {
|
||||||
|
do {
|
||||||
|
static_cast<uint8_t*>(freePtrIter)[0] = 0xff;
|
||||||
|
static_cast<uint8_t*>(freePtrIter)[1] = 0xff;
|
||||||
|
static_cast<uint8_t*>(freePtrIter)[2] = 0xff;
|
||||||
|
static_cast<uint8_t*>(freePtrIter)[3] = 0xff;
|
||||||
|
static_cast<uint8_t*>(freePtrIter)[4] = 0xff;
|
||||||
|
static_cast<uint8_t*>(freePtrIter)[5] = 0xff;
|
||||||
|
static_cast<uint8_t*>(freePtrIter)[6] = 0xff;
|
||||||
|
static_cast<uint8_t*>(freePtrIter)[7] = 0xff;
|
||||||
|
freePtrIter += 8;
|
||||||
|
} while (--uVar5 != 0u);
|
||||||
|
|
||||||
|
blockCount &= 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blockCount != 0) {
|
||||||
|
do {
|
||||||
|
static_cast<uint8_t*>(freePtrIter)[0] = 0xff;
|
||||||
|
++freePtrIter;
|
||||||
|
} while (--blockCount != 0u);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
x18_numBlocksAvailable = x18_numBlocksAvailable - len;
|
||||||
|
++x1c_numAllocs;
|
||||||
|
|
||||||
|
return bufPtr + ((freePtr - bookKeepingStart) * 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSmallAllocPool::Free(void* buf) {
|
||||||
|
u32 offset = static_cast<u8*>(buf) - static_cast<u8*>(x0_mainData);
|
||||||
|
u32 block = (offset >> 2) + static_cast<u32>(static_cast<s32>(offset < 0 && ((offset & 3) != 0u)) != 0);
|
||||||
|
u32 numBlocks = (static_cast<u8*>(x4_bookKeeping)[0] + (block >> 1)) >> (~-(block & 1) & 4) & 0xf;
|
||||||
|
x18_numBlocksAvailable += numBlocks;
|
||||||
|
--x1c_numAllocs;
|
||||||
|
x14_ = block;
|
||||||
|
if (block == x10_) {
|
||||||
|
x10_ = -1;
|
||||||
|
}
|
||||||
|
u8* puVar1 = static_cast<u8*>(x4_bookKeeping) + (block >> 1);
|
||||||
|
for (; numBlocks != 0; numBlocks -= 2) {
|
||||||
|
static_cast<u8*>(puVar1)[0] = 0;
|
||||||
|
++puVar1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace metaforce
|
|
@ -0,0 +1,63 @@
|
||||||
|
#pragma once
|
||||||
|
#include "GCNTypes.hpp"
|
||||||
|
|
||||||
|
namespace metaforce {
|
||||||
|
class CSmallAllocPool {
|
||||||
|
void* x0_mainData;
|
||||||
|
void* x4_bookKeeping;
|
||||||
|
uint32_t x8_numBlocks;
|
||||||
|
void* xc_cachedBookKeepingOffset = nullptr;
|
||||||
|
int32_t x10_ = -1;
|
||||||
|
uint32_t x14_ = -1;
|
||||||
|
uint32_t x18_numBlocksAvailable = 0;
|
||||||
|
uint32_t x1c_numAllocs = 0;
|
||||||
|
|
||||||
|
[[nodiscard]] void* FindFree(uint32_t len);
|
||||||
|
public:
|
||||||
|
CSmallAllocPool(uint32_t len, void* mainData, void* bookKeeping);
|
||||||
|
|
||||||
|
[[nodiscard]] void* Alloc(uint32_t size);
|
||||||
|
[[nodiscard]] bool Free(void* buf);
|
||||||
|
|
||||||
|
[[nodiscard]] uint32_t GetNumUsedBlocks() const {
|
||||||
|
uint32_t usedBlocks = 0;
|
||||||
|
for (uint32_t i = 0; i < x8_numBlocks / 2;) {
|
||||||
|
uint8_t p = static_cast<uint8_t*>(x4_bookKeeping)[i];
|
||||||
|
// Don't check the header directly, make sure we extract the block count, as it's actually possible to allocate a
|
||||||
|
// 0 block buffer, Retro worked around this in retail by not allowing CGameAllocator to allocate buffers >= 0x39
|
||||||
|
// bytes
|
||||||
|
if (((p >> 4) & 0xf) != 0) {
|
||||||
|
uint32_t numBlocks = (p >> 4) & 0xf;
|
||||||
|
usedBlocks += numBlocks;
|
||||||
|
// skip over blocks used by this allocation
|
||||||
|
i += numBlocks / 2;
|
||||||
|
} else {
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return usedBlocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] uint32_t GetNumUnusedBlocks() const {
|
||||||
|
uint32_t unusedBlocks = 0;
|
||||||
|
for (uint32_t i = 0; i < x8_numBlocks / 2;) {
|
||||||
|
uint8_t p = static_cast<uint8_t*>(x4_bookKeeping)[i];
|
||||||
|
// Don't check the header directly, make sure we extract the block count, as it's actually possible to allocate a
|
||||||
|
// 0 block buffer, Retro worked around this in retail by not allowing CGameAllocator to allocate buffers >= 0x39
|
||||||
|
// bytes
|
||||||
|
if (((p >> 4) & 0xf) != 0) {
|
||||||
|
// skip over blocks used by this allocation
|
||||||
|
i += ((p >> 4) & 0xf) / 2;
|
||||||
|
} else {
|
||||||
|
++i;
|
||||||
|
unusedBlocks += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return unusedBlocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] u32 GetNumBlocksAvailable() const { return x18_numBlocksAvailable; }
|
||||||
|
[[nodiscard]] u32 GetTotalEntries() const { return x8_numBlocks - x18_numBlocksAvailable; }
|
||||||
|
[[nodiscard]] u32 GetNumAllocs() const { return x1c_numAllocs; }
|
||||||
|
};
|
||||||
|
} // namespace metaforce
|
|
@ -0,0 +1,31 @@
|
||||||
|
#include "IAllocator.hpp"
|
||||||
|
|
||||||
|
namespace metaforce {
|
||||||
|
IAllocator::SMetrics::SMetrics(u32 heapSize, u32 unk1, u32 unk2, u32 unk3, u32 unk4, u32 heapSize2, u32 unk5, u32 unk6,
|
||||||
|
u32 unk7, u32 unk8, u32 unk9, u32 smallAllocNumAllocs, u32 smallAllocAllocatedSize,
|
||||||
|
u32 smallAllocRemainingSize, u32 mediumAllocNumAllocs, u32 mediumAllocAllocatedSize,
|
||||||
|
u32 mediumAllocBlocksAvailable, u32 unk10, u32 unk11, u32 unk12,
|
||||||
|
u32 mediumAllocTotalAllocated, u32 fakeStatics)
|
||||||
|
: x0_heapSize(heapSize)
|
||||||
|
, x4_(unk1)
|
||||||
|
, x8_(unk2)
|
||||||
|
, xc_(unk3)
|
||||||
|
, x10_(unk4)
|
||||||
|
, x14_heapSize2(heapSize2)
|
||||||
|
, x18_(unk5)
|
||||||
|
, x1c_(unk6)
|
||||||
|
, x20_(unk7)
|
||||||
|
, x24_(unk8)
|
||||||
|
, x28_(unk9)
|
||||||
|
, x2c_smallNumAllocs(smallAllocNumAllocs)
|
||||||
|
, x30_smallAllocatedSize(smallAllocAllocatedSize)
|
||||||
|
, x34_smallRemainingSize(smallAllocRemainingSize)
|
||||||
|
, x38_mediumNumAllocs(mediumAllocNumAllocs)
|
||||||
|
, x3c_mediumAllocatedSize(mediumAllocAllocatedSize)
|
||||||
|
, x40_mediumBlocksAvailable(mediumAllocBlocksAvailable)
|
||||||
|
, x44_(unk10)
|
||||||
|
, x48_(unk11)
|
||||||
|
, x4c_(unk12)
|
||||||
|
, x50_mediumTotalAllocated(mediumAllocTotalAllocated)
|
||||||
|
, x54_fakeStatics(fakeStatics) {}
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <athena/Global.hpp>
|
||||||
|
#include "Runtime/GCNTypes.hpp"
|
||||||
|
|
||||||
|
namespace metaforce {
|
||||||
|
class CCallStack {
|
||||||
|
const char* x0_line;
|
||||||
|
const char* x4_type;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CCallStack(int lineNum, const char* lineStr, const char* type) : x0_line(lineStr), x4_type(type) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class EHint {
|
||||||
|
Unk = (1 << 0),
|
||||||
|
RoundUpLen = (1 << 1),
|
||||||
|
};
|
||||||
|
ENABLE_BITWISE_ENUM(EHint);
|
||||||
|
|
||||||
|
enum class EScope {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class EType {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class IAllocator {
|
||||||
|
public:
|
||||||
|
using FOutOfMemoryCb = bool (*)(void*, u32);
|
||||||
|
struct SMetrics {
|
||||||
|
u32 x0_heapSize;
|
||||||
|
u32 x4_;
|
||||||
|
u32 x8_;
|
||||||
|
u32 xc_;
|
||||||
|
u32 x10_;
|
||||||
|
u32 x14_heapSize2; // Remaining heap size?
|
||||||
|
u32 x18_;
|
||||||
|
u32 x1c_;
|
||||||
|
u32 x20_;
|
||||||
|
u32 x24_;
|
||||||
|
u32 x28_;
|
||||||
|
u32 x2c_smallNumAllocs;
|
||||||
|
u32 x30_smallAllocatedSize;
|
||||||
|
u32 x34_smallRemainingSize;
|
||||||
|
u32 x38_mediumNumAllocs;
|
||||||
|
u32 x3c_mediumAllocatedSize;
|
||||||
|
u32 x40_mediumBlocksAvailable;
|
||||||
|
u32 x44_;
|
||||||
|
u32 x48_;
|
||||||
|
u32 x4c_;
|
||||||
|
u32 x50_mediumTotalAllocated;
|
||||||
|
u32 x54_fakeStatics;
|
||||||
|
SMetrics(u32 heapSize, u32 unk1, u32 unk2, u32 unk3, u32 unk4, u32 heapSize2, u32 unk5, u32 unk6, u32 unk7,
|
||||||
|
u32 unk8, u32 unk9, u32 smallAllocNumAllocs, u32 smallAllocAllocatedSize, u32 smallAllocRemainingSize,
|
||||||
|
u32 mediumAllocNumAllocs, u32 mediumAllocAllocatedSize, u32 mediumAllocBlocksAvailable, u32 unk10, u32 unk11, u32 unk12,
|
||||||
|
u32 mediumAllocTotalAllocated, u32 fakeStatics);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SAllocInfo {
|
||||||
|
void* x0_infoPtr;
|
||||||
|
size_t x4_len;
|
||||||
|
bool x8_hasPrevious;
|
||||||
|
bool x9_;
|
||||||
|
const char* xc_fileAndLne;
|
||||||
|
const char* x10_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
using FEnumAllocationsCb = const bool (*)(const SAllocInfo& info, const void* ptr);
|
||||||
|
virtual bool Initialize() = 0; // const COSContext& ctx) = 0;
|
||||||
|
|
||||||
|
virtual void* Alloc(size_t size) = 0;
|
||||||
|
virtual bool Free(void* ptr) = 0;
|
||||||
|
virtual void ReleaseAll() = 0;
|
||||||
|
virtual void* AllocSecondary(size_t size) = 0;
|
||||||
|
virtual bool FreeSecondary(void* ptr) = 0;
|
||||||
|
virtual void ReleaseAllSecondary() = 0;
|
||||||
|
virtual void SetOutOfMemoryCallback(FOutOfMemoryCb cb, void* target) = 0;
|
||||||
|
virtual s32 EnumAllocations(FEnumAllocationsCb cb, const void* ptr, bool b) = 0;
|
||||||
|
virtual SAllocInfo GetAllocInfo(void* ptr) = 0;
|
||||||
|
virtual void OffsetFakeStatics(s32 offset) = 0;
|
||||||
|
virtual SMetrics GetMetrics() = 0;
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in New Issue