Set default alignment for SysAllocator to cache-line size

Avoids memory corruptions when the memory is cleared via DCZeroRange. Seen in BotW with AX AUX buffers.
This commit is contained in:
Exzap 2023-10-18 10:49:12 +02:00
parent 9bb409314d
commit b0a7fd4e07

View File

@ -1,10 +1,10 @@
#pragma once #pragma once
#include <vector>
uint32 coreinit_allocFromSysArea(uint32 size, uint32 alignment); uint32 coreinit_allocFromSysArea(uint32 size, uint32 alignment);
class SysAllocatorBase; class SysAllocatorBase;
#define SYSALLOCATOR_GUARDS 0 // if 1, create a magic constant at the top of each memory allocation which is used to check for memory corruption
class SysAllocatorContainer class SysAllocatorContainer
{ {
public: public:
@ -29,9 +29,7 @@ private:
virtual void Initialize() = 0; virtual void Initialize() = 0;
}; };
template<typename T, size_t count = 1, size_t alignment = 32>
template<typename T, size_t count = 1, size_t alignment = 8>
class SysAllocator : public SysAllocatorBase class SysAllocator : public SysAllocatorBase
{ {
public: public:
@ -68,11 +66,17 @@ public:
T* GetPtr() const T* GetPtr() const
{ {
#if SYSALLOCATOR_GUARDS
cemu_assert(*(uint32*)((uint8*)m_sysMem.GetPtr()+(sizeof(T) * count)) == 0x112A33C4);
#endif
return m_sysMem.GetPtr(); return m_sysMem.GetPtr();
} }
uint32 GetMPTR() const uint32 GetMPTR() const
{ {
#if SYSALLOCATOR_GUARDS
cemu_assert(*(uint32*)((uint8*)m_sysMem.GetPtr()+(sizeof(T) * count)) == 0x112A33C4);
#endif
return m_sysMem.GetMPTR(); return m_sysMem.GetMPTR();
} }
@ -130,11 +134,17 @@ private:
{ {
if (m_sysMem.GetMPTR() != 0) if (m_sysMem.GetMPTR() != 0)
return; return;
// alloc mem // alloc mem
m_sysMem = { coreinit_allocFromSysArea(sizeof(T) * count, alignment) }; uint32 guardSize = 0;
#if SYSALLOCATOR_GUARDS
guardSize = 4;
#endif
m_sysMem = { coreinit_allocFromSysArea(sizeof(T) * count + guardSize, alignment) };
// copy temp buffer to mem and clear it // copy temp buffer to mem and clear it
memcpy(m_sysMem.GetPtr(), m_tempData.data(), sizeof(T)*count); memcpy(m_sysMem.GetPtr(), m_tempData.data(), sizeof(T)*count);
#if SYSALLOCATOR_GUARDS
*(uint32*)((uint8*)m_sysMem.GetPtr()+(sizeof(T) * count)) = 0x112A33C4;
#endif
m_tempData.clear(); m_tempData.clear();
} }
@ -197,9 +207,8 @@ private:
{ {
if (m_sysMem.GetMPTR() != 0) if (m_sysMem.GetMPTR() != 0)
return; return;
// alloc mem // alloc mem
m_sysMem = { coreinit_allocFromSysArea(sizeof(T), 8) }; m_sysMem = { coreinit_allocFromSysArea(sizeof(T), 32) };
// copy temp buffer to mem and clear it // copy temp buffer to mem and clear it
*m_sysMem = m_tempData; *m_sysMem = m_tempData;
} }