mirror of https://github.com/AxioDL/metaforce.git
Initial CGameAllocator RE
This commit is contained in:
parent
91996ab561
commit
f660266750
|
@ -1,57 +1,26 @@
|
||||||
#include "Runtime/CGameAllocator.hpp"
|
#include "Runtime/CGameAllocator.hpp"
|
||||||
|
#include <new>
|
||||||
|
|
||||||
namespace metaforce {
|
namespace metaforce {
|
||||||
logvisor::Module AllocLog("metaforce::CGameAllocator");
|
logvisor::Module AllocLog("metaforce::CGameAllocator");
|
||||||
|
|
||||||
#pragma GCC diagnostic ignored "-Wclass-memaccess"
|
#pragma GCC diagnostic ignored "-Wclass-memaccess"
|
||||||
|
|
||||||
std::vector<CGameAllocator::SAllocationDescription> CGameAllocator::m_allocations;
|
u32 CGameAllocator::GetFreeBinEntryForSize(size_t len) {
|
||||||
|
size_t bin = 0;
|
||||||
u8* CGameAllocator::Alloc(size_t len) {
|
size_t binSize = 32;
|
||||||
size_t roundedLen = ROUND_UP_64(len + sizeof(SChunkDescription));
|
while (true) {
|
||||||
for (SAllocationDescription& alloc : m_allocations) {
|
if (binSize > 0x200000) {
|
||||||
/* We need to supply enough room for allocation information */
|
return 15;
|
||||||
if (alloc.freeOffset + roundedLen < alloc.allocSize) {
|
|
||||||
u8* ptr = alloc.memptr.get() + alloc.freeOffset;
|
|
||||||
SChunkDescription* chunkInfo = reinterpret_cast<SChunkDescription*>(ptr);
|
|
||||||
*chunkInfo = SChunkDescription();
|
|
||||||
chunkInfo->parent = &alloc;
|
|
||||||
chunkInfo->len = len;
|
|
||||||
alloc.freeOffset += roundedLen;
|
|
||||||
return ptr + sizeof(SChunkDescription);
|
|
||||||
}
|
}
|
||||||
|
if (len < binSize) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
binSize <<= 1;
|
||||||
|
++bin;
|
||||||
|
}
|
||||||
|
return bin;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 1MiB minimum allocation to prevent constantly allocating small amounts of memory */
|
bool CGameAllocator::Initialize() { return true; }
|
||||||
size_t allocSz = len;
|
|
||||||
if (allocSz < (1 * 1024 * 1024 * 1024))
|
|
||||||
allocSz = 1 * 1024 * 1024 * 1024;
|
|
||||||
|
|
||||||
/* Pad size to allow for allocation information */
|
|
||||||
allocSz = ROUND_UP_64(allocSz + sizeof(SChunkDescription));
|
|
||||||
auto& alloc = m_allocations.emplace_back();
|
|
||||||
alloc.memptr.reset(new u8[allocSz]);
|
|
||||||
u8* ptr = alloc.memptr.get();
|
|
||||||
alloc.allocSize = allocSz;
|
|
||||||
alloc.freeOffset += roundedLen;
|
|
||||||
SChunkDescription* chunkInfo = reinterpret_cast<SChunkDescription*>(ptr);
|
|
||||||
*chunkInfo = SChunkDescription();
|
|
||||||
chunkInfo->parent = &alloc;
|
|
||||||
chunkInfo->len = len;
|
|
||||||
return ptr + sizeof(SChunkDescription);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CGameAllocator::Free(u8* ptr) {
|
|
||||||
SChunkDescription* info = reinterpret_cast<SChunkDescription*>(ptr - sizeof(SChunkDescription));
|
|
||||||
if (info->magic != 0xE8E8E8E8 || info->sentinal != 0xEFEFEFEF) {
|
|
||||||
AllocLog.report(logvisor::Fatal, FMT_STRING("Invalid chunk description, memory corruption!"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SAllocationDescription& alloc = *info->parent;
|
|
||||||
size_t roundedLen = ROUND_UP_32(info->len + sizeof(SChunkDescription));
|
|
||||||
alloc.freeOffset -= roundedLen;
|
|
||||||
/* Invalidate chunk allocation descriptor */
|
|
||||||
memset(info, 0, ROUND_UP_64(info->len + sizeof(SChunkDescription)));
|
|
||||||
}
|
|
||||||
} // namespace metaforce
|
} // namespace metaforce
|
||||||
|
|
|
@ -7,24 +7,29 @@
|
||||||
#include "Runtime/RetroTypes.hpp"
|
#include "Runtime/RetroTypes.hpp"
|
||||||
|
|
||||||
namespace metaforce {
|
namespace metaforce {
|
||||||
class CGameAllocator {
|
class CCallStack {
|
||||||
struct SAllocationDescription {
|
const char* x0_line;
|
||||||
std::unique_ptr<u8[]> memptr;
|
const char* x4_type;
|
||||||
size_t allocSize = 0;
|
|
||||||
ptrdiff_t freeOffset = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SChunkDescription {
|
|
||||||
u32 magic = 0xE8E8E8E8;
|
|
||||||
SAllocationDescription* parent;
|
|
||||||
size_t len = 0;
|
|
||||||
u32 sentinal = 0xEFEFEFEF;
|
|
||||||
};
|
|
||||||
|
|
||||||
static std::vector<SAllocationDescription> m_allocations;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static u8* Alloc(size_t len);
|
CCallStack(int lineNum, const char* lineStr, const char* type) : x0_line(lineStr), x4_type(type) {}
|
||||||
static void Free(u8* ptr);
|
};
|
||||||
|
|
||||||
|
class CGameAllocator {
|
||||||
|
struct SGameMemInfo {
|
||||||
|
u32 x0_sentinel = 0xefefefef;
|
||||||
|
size_t x4_len = 0;
|
||||||
|
const char* x8_line;
|
||||||
|
const char* xc_type;
|
||||||
|
SGameMemInfo* x10_prev = nullptr;
|
||||||
|
void* x14_ = nullptr;
|
||||||
|
void* x18_ = nullptr;
|
||||||
|
u32 x1c_canary = 0xeaeaeaea;
|
||||||
|
};
|
||||||
|
static u32 GetFreeBinEntryForSize(size_t len);
|
||||||
|
std::array<SGameMemInfo, 16> x14_bins;
|
||||||
|
public:
|
||||||
|
|
||||||
|
bool Initialize();//const COsContext& ctx);
|
||||||
};
|
};
|
||||||
} // namespace metaforce
|
} // namespace metaforce
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue