2019-12-22 20:04:07 +00:00
|
|
|
#include "Runtime/CGameAllocator.hpp"
|
2017-09-12 15:27:48 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
namespace urde {
|
2017-09-12 15:27:48 +00:00
|
|
|
logvisor::Module AllocLog("urde::CGameAllocator");
|
|
|
|
|
2019-06-12 02:05:17 +00:00
|
|
|
#pragma GCC diagnostic ignored "-Wclass-memaccess"
|
|
|
|
|
2017-09-12 15:27:48 +00:00
|
|
|
std::vector<CGameAllocator::SAllocationDescription> CGameAllocator::m_allocations;
|
|
|
|
|
2018-12-08 05:30:43 +00: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);
|
2017-09-12 15:27:48 +00:00
|
|
|
}
|
2018-12-08 05:30:43 +00:00
|
|
|
}
|
2017-09-12 15:27:48 +00:00
|
|
|
|
2018-12-08 05:30:43 +00: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;
|
2017-09-12 15:27:48 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
/* Pad size to allow for allocation information */
|
|
|
|
allocSz = ROUND_UP_64(allocSz + sizeof(SChunkDescription));
|
2020-03-13 20:32:24 +00:00
|
|
|
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-08 05:30:43 +00:00
|
|
|
SChunkDescription* chunkInfo = reinterpret_cast<SChunkDescription*>(ptr);
|
|
|
|
*chunkInfo = SChunkDescription();
|
2020-03-13 20:32:24 +00:00
|
|
|
chunkInfo->parent = &alloc;
|
2018-12-08 05:30:43 +00:00
|
|
|
chunkInfo->len = len;
|
|
|
|
return ptr + sizeof(SChunkDescription);
|
2017-09-12 15:27:48 +00:00
|
|
|
}
|
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
void CGameAllocator::Free(u8* ptr) {
|
|
|
|
SChunkDescription* info = reinterpret_cast<SChunkDescription*>(ptr - sizeof(SChunkDescription));
|
|
|
|
if (info->magic != 0xE8E8E8E8 || info->sentinal != 0xEFEFEFEF) {
|
2019-07-20 04:27:21 +00:00
|
|
|
AllocLog.report(logvisor::Fatal, fmt(_SYS_STR("Invalid chunk description, memory corruption!")));
|
2018-12-08 05:30:43 +00:00
|
|
|
return;
|
|
|
|
}
|
2017-09-12 15:27:48 +00:00
|
|
|
|
2018-12-08 05:30:43 +00: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)));
|
2017-09-12 15:27:48 +00:00
|
|
|
}
|
2018-12-08 05:30:43 +00:00
|
|
|
} // namespace urde
|