MEM_TempAlloc: fix for CPUs that don't support misalignment

This commit is contained in:
L 2023-02-01 23:12:26 +01:00
parent 08f151c665
commit c3456e7af4
2 changed files with 73 additions and 23 deletions

View file

@ -36,44 +36,86 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define MEM_TempFree(x) Z_Free(x)
#endif
class tempBlock_t
{
public:
void* GetData();
void* GetData(size_t pos);
public:
tempBlock_t* prev;
};
MEM_TempAlloc::MEM_TempAlloc()
{
m_CurrentMemoryBlock = nullptr;
m_CurrentMemoryPos = 0;
m_BlockSize = 0;
m_LastPos = 0;
}
void *MEM_TempAlloc::Alloc( size_t len )
void* MEM_TempAlloc::Alloc(size_t len)
{
unsigned char *prev_block = m_CurrentMemoryBlock;
unsigned char *result;
if( m_CurrentMemoryBlock && m_CurrentMemoryPos + len <= 65536 )
if (m_CurrentMemoryBlock && m_CurrentMemoryPos + len <= m_BlockSize)
{
result = m_CurrentMemoryBlock + m_CurrentMemoryPos + sizeof( unsigned char * );
void* data = m_CurrentMemoryBlock->GetData(m_CurrentMemoryPos);
m_LastPos = m_CurrentMemoryPos;
m_CurrentMemoryPos += len;
return data;
}
else
{
m_CurrentMemoryPos = len;
return CreateBlock(len);
}
}
if( len < 65536 )
len = 65536;
void* MEM_TempAlloc::Alloc(size_t len, size_t alignment)
{
if (m_CurrentMemoryBlock)
{
if (m_CurrentMemoryPos % alignment != 0) {
m_CurrentMemoryPos += alignment - m_CurrentMemoryPos % alignment;
}
m_CurrentMemoryBlock = ( unsigned char * )MEM_TempAllocate( len + sizeof( unsigned char * ) );
*( unsigned char ** )m_CurrentMemoryBlock = prev_block;
result = m_CurrentMemoryBlock + sizeof( unsigned char * );
if (m_CurrentMemoryPos + len <= m_BlockSize)
{
void* data = m_CurrentMemoryBlock->GetData(m_CurrentMemoryPos);
m_LastPos = m_CurrentMemoryPos;
m_CurrentMemoryPos += len;
return data;
}
}
return result;
return CreateBlock(len);
}
void MEM_TempAlloc::FreeAll( void )
{
unsigned char *prev_block;
while( m_CurrentMemoryBlock )
while (m_CurrentMemoryBlock)
{
prev_block = *( unsigned char ** )m_CurrentMemoryBlock;
MEM_TempFree( m_CurrentMemoryBlock );
tempBlock_t* prev_block = m_CurrentMemoryBlock->prev;
MEM_TempFree(m_CurrentMemoryBlock);
m_CurrentMemoryBlock = prev_block;
}
}
void* MEM_TempAlloc::CreateBlock(size_t len)
{
m_CurrentMemoryPos = len;
// allocate a new block
tempBlock_t* prev_block = m_CurrentMemoryBlock;
m_CurrentMemoryBlock = (tempBlock_t*)MEM_TempAllocate(sizeof(tempBlock_t) + max(m_BlockSize, len));
m_CurrentMemoryBlock->prev = prev_block;
return m_CurrentMemoryBlock->GetData();
}
void* tempBlock_t::GetData()
{
return (void*)(this + 1);
}
void* tempBlock_t::GetData(size_t pos)
{
return (uint8_t*)(this + 1) + pos;
}