metaforce/Runtime/CGameAllocator.cpp

60 lines
2.2 KiB
C++
Raw Normal View History

#include "Runtime/CGameAllocator.hpp"
2022-02-18 21:33:56 -08:00
#include <logvisor/logvisor.hpp>
2021-04-10 01:42:06 -07:00
namespace metaforce {
2022-02-18 21:33:56 -08:00
static logvisor::Module Log("metaforce::CGameAllocator");
#pragma GCC diagnostic ignored "-Wclass-memaccess"
std::vector<CGameAllocator::SAllocationDescription> CGameAllocator::m_allocations;
2018-12-07 21:30:43 -08:00
u8* CGameAllocator::Alloc(size_t len) {
size_t roundedLen = ROUND_UP_64(len + sizeof(SChunkDescription));
for (SAllocationDescription& alloc : m_allocations) {
/* We need to supply enough room for allocation information */
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);
}
2018-12-07 21:30:43 -08:00
}
2018-12-07 21:30:43 -08:00
/* 1MiB minimum allocation to prevent constantly allocating small amounts of memory */
size_t allocSz = len;
if (allocSz < (1 * 1024 * 1024 * 1024))
allocSz = 1 * 1024 * 1024 * 1024;
2018-12-07 21:30:43 -08:00
/* 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;
2018-12-07 21:30:43 -08:00
SChunkDescription* chunkInfo = reinterpret_cast<SChunkDescription*>(ptr);
*chunkInfo = SChunkDescription();
chunkInfo->parent = &alloc;
2018-12-07 21:30:43 -08:00
chunkInfo->len = len;
return ptr + sizeof(SChunkDescription);
}
2018-12-07 21:30:43 -08:00
void CGameAllocator::Free(u8* ptr) {
SChunkDescription* info = reinterpret_cast<SChunkDescription*>(ptr - sizeof(SChunkDescription));
if (info->magic != 0xE8E8E8E8 || info->sentinal != 0xEFEFEFEF) {
2022-02-18 21:33:56 -08:00
Log.report(logvisor::Fatal, FMT_STRING("Invalid chunk description, memory corruption!"));
2018-12-07 21:30:43 -08:00
return;
}
2018-12-07 21:30:43 -08:00
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)));
}
2021-04-10 01:42:06 -07:00
} // namespace metaforce