14#ifdef TOSHI_PROFILER_MEMORY
18#ifdef TMEMORY_USE_DLMALLOC
22#ifndef TMEMORY_USE_DLMALLOC
25# define TMEMORY_ROUNDUP 4
26# define TMEMORY_FLAGS_HOLE_PROCESS 1
27# define TMEMORY_FLAGS_MASK ( ( 1 << 2 ) - 1 )
28# define TMEMORY_NUM_FREELISTS 9
29# define TMEMORY_NUM_BLOCK_SLOTS 128
30# define TMEMORY_ALLOC_MEMNODE_SIZE sizeof( Toshi::TMemory::MemNode )
31# define TMEMORY_ALLOC_RESERVED_SIZE ( TMEMORY_ALLOC_MEMNODE_SIZE - sizeof( void* ) )
256 TBOOL FreeMemBlock( MemBlock* a_pMemBlock );
257 void SetMemBlockUnused( MemBlock* a_pMemBlock );
259 static MemNode* GetMemNodeFromAddress(
void* a_pMem );
260 static void ExtendNodeSize( MemNode* a_pNode,
TSIZE a_uiExtendSize ) { a_pNode->uiSize = a_uiExtendSize | ( a_pNode->uiSize &
TMEMORY_FLAGS_MASK ); }
261 static void SetHoleSize(
MemNode* a_pNode,
TSIZE a_uiHoleSize ) { a_pNode->uiSize = a_uiHoleSize; }
266 a_pNode->pMemBlock = a_pMemBlock;
269 static MemBlock* GetProcessMemBlock(
MemNode* a_pNode ) {
return a_pNode->pMemBlock; }
270 static void ConvertProcessToHole(
MemNode* a_pNode ) { a_pNode->uiSize &= ~TMEMORY_FLAGS_MASK; }
271 static int TestMemIntegrity(
MemBlock* a_pMemBlock );
272 static int DebugTestMemoryBlock(
MemBlock* a_pMemBlock );
283 inline static class TMutex* ms_pGlobalMutex;
286 TSIZE m_TotalAllocatedSize;
287 TSIZE m_ReservedSize;
288 TSIZE m_MainBlockSize;
289 TNodeList<MemBlockSlot> m_UsedBlocks;
290 TNodeList<MemBlockSlot> m_FreeBlocks;
294 TUINT m_uiGlobalFlags;
351 void SetMemModule( TMemoryDL* a_pMemModule ) { m_pMemModule = a_pMemModule; }
352 TMemoryDL* GetMemModule() {
return m_pMemModule; }
355 static TBOOL Initialise(
TUINT a_uiHeapSize,
TUINT a_uiReservedSize, TMemoryDL::Flags a_eFlags = TMemoryDL::Flags_Standard );
362 TMemoryDL* m_pMemModule;
363 TCHAR PADDING[ 2092 ];
397void*
TMalloc(
TSIZE a_uiSize, Toshi::TMemory::MemBlock* a_pMemBlock,
const TCHAR* a_szFileName =
TNULL,
TINT a_iLineNum = -1 );
414void*
TMemalign(
TSIZE a_uiAlignment,
TSIZE a_uiSize, Toshi::TMemory::MemBlock* a_pMemBlock );
420void TFree(
void* a_pMem );
430template <
class T,
class... Args>
433 return new ( a_pMemory ) T( std::forward<Args>( args )... );
445template <
class T,
class... Args>
448 for (
TSIZE i = 0; i < a_uiNumTimes; i++ )
450 new ( a_pMemory + i ) T( std::forward<Args>( args )... );
476TFORCEINLINE void* __CRTDECL
operator new(
size_t size, Toshi::TMemory::MemBlock* block )
478#ifdef TOSHI_PROFILER_MEMORY
479 return TMalloc( size, block, TMemory__FILE__, TMemory__LINE__ );
491TFORCEINLINE void* __CRTDECL
operator new[](
size_t size, Toshi::TMemory::MemBlock* block )
493#ifdef TOSHI_PROFILER_MEMORY
494 return TMalloc( size, block, TMemory__FILE__, TMemory__LINE__ );
505TFORCEINLINE void __CRTDECL
operator delete(
void* ptr, Toshi::TMemory::MemBlock* block )
noexcept
515TFORCEINLINE void __CRTDECL
operator delete[](
void* ptr, Toshi::TMemory::MemBlock* block )
noexcept
#define TMEMORY_NUM_FREELISTS
Number of free list buckets for different sizes.
void * TMemalign(TSIZE a_uiSize, TSIZE a_uiAlignment)
Allocates aligned memory.
TOSHI_NAMESPACE_START class TMemory * g_pMemory
#define TMEMORY_NUM_BLOCK_SLOTS
Maximum number of memory block slots.
TOSHI_NAMESPACE_END void * TMalloc(TSIZE a_uiSize)
Allocates memory with default alignment.
TFORCEINLINE T * TConstructArray(T *a_pMemory, TSIZE a_uiNumTimes, Args &&... args)
Constructs an array of objects in place.
#define TMEMORY_FLAGS_HOLE_PROCESS
Flag indicating a memory block is in use.
TFORCEINLINE void TDestruct(T *a_pPtr)
Destructs an object.
TFORCEINLINE T * TConstruct(T *a_pMemory, Args &&... args)
Constructs an object in place.
void TFree(void *a_pMem)
Frees previously allocated memory.
#define TMEMORY_FLAGS_MASK
Mask for memory block flags.
#define HASANYFLAG(STATE, FLAG)
#define TOSHI_NAMESPACE_START
#define TOSHI_NAMESPACE_END
TFORCEINLINE constexpr T TAlignNumDown(T a_iValue, TSIZE a_uiAlignment=4)
Core memory management class that handles all memory allocations and deallocations.
static TBOOL Initialise(TSIZE a_uiHeapSize, TSIZE a_uiReservedSize, TUINT a_uiUnused=0)
Initializes the memory system.
TBOOL Free(const void *a_pMem)
Frees previously allocated memory.
static TUINT MapSizeToFreeList(TSIZE a_uiSize)
TUINT GetGlobalFlags() const
static void GetMemInfo(MemInfo &a_rMemInfo, MemBlock *a_pMemBlock)
static void Deinitialise()
Deinitializes the memory system.
MemBlock * GetGlobalBlock() const
Gets the global memory block.
MemBlock * CreateMemBlockInPlace(void *a_pMem, TSIZE a_uiSize, const TCHAR *a_szName)
Creates a memory block at a specific location.
static void GetHALMemInfo(HALMemInfo &a_rHALMemInfo)
void DestroyMemBlock(MemBlock *a_pMemBlock)
Destroys a memory block.
static void DebugPrintHALMemInfo(const TCHAR *a_szFormat,...)
Debug print of HAL memory info.
void * Alloc(TSIZE a_uiSize, TSIZE a_uiAlignment, MemBlock *a_pMemBlock, const TCHAR *a_szFileName, TINT a_iLineNum)
Allocates memory with specified size and alignment.
void * SysAlloc(TSIZE a_uiSize)
Allocates memory from the system heap.
void SysFree(void *a_pMem)
Frees memory back to the system heap.
TMemory::MemBlock * SetGlobalBlock(MemBlock *a_pMemBlock)
Sets the global memory block.
MemBlock * CreateMemBlock(TSIZE a_uiSize, const TCHAR *a_szName, MemBlock *a_pOwnerBlock, TINT a_iUnused)
Creates a new memory block.
TMemory()
Constructor for TMemory class Initializes the memory management system.
~TMemory()
Destructor for TMemory class Cleans up the memory management system.
Represents a node in the memory allocation system.
MemNode * pOwner
Owner node if this is a sub-allocation.
TSIZE uiSize
Size of the memory region.
MemNode * pNextHole
Next free hole in the list.
MemNode * pPrevHole
Previous free hole in the list.
void * GetDataRegionEnd() const
Gets the end address of the data region for this node.
MemBlock * pMemBlock
Memory block this node belongs to.
void * GetDataRegionStart() const
Gets the start address of the data region for this node.
Represents a contiguous block of memory that can be allocated from.
TSIZE m_uiTotalSize2
Duplicate of total size for validation.
MemBlock * m_pNextBlock
Next block in the chain.
MemNode * m_apHoles[9]
Array of free lists by size.
MemNode m_RootHole
Root node for the block.
MemNode * m_pFirstHole
First free hole in the block.
TCHAR m_szSignature[8]
Block signature for validation.
MemBlockSlot * m_pSlot
Slot tracking this block.
TCHAR m_szName[52]
Name of the memory block.
TSIZE m_uiTotalSize1
Total size of the block.
Footer structure at the end of each memory block for validation.
TUINT m_Unk1
Unknown field 1.
TUINT m_Unk2
Unknown field 2.
TUINT m_Unk4
Unknown field 4.
MemBlock * m_pBlockOwner
Pointer to the owning block.
Slot for tracking memory blocks in the block list.
MemBlock * m_pPtr
Pointer to the memory block.
Structure containing memory usage statistics.
TSIZE m_uiTotalFree
Total free memory.
TSIZE m_uiSmallestProcess
Size of smallest allocation.
TINT m_iNumProcesses
Number of allocated regions.
TSIZE m_uiUnk4
Unknown field 4.
TSIZE m_uiLogicTotalSize
Logical total size.
TSIZE m_uiUnk3
Unknown field 3.
TSIZE m_uiLogicTotalUsed
Logical total used memory.
TSIZE m_uiSmallestHole
Size of smallest free hole.
TSIZE m_uiLargestProcess
Size of largest allocation.
TSIZE m_uiLargestHole
Size of largest free hole.
TSIZE m_uiLogicTotalFree
Logical total free memory.
TSIZE m_uiTotalSize
Total size of memory block.
TINT m_iNumHoles
Number of free holes.
TSIZE m_uiTotalUsed
Total used memory.
Hardware abstraction layer memory information.
TUINT m_Unknown1[10]
Unknown fields 1-10.
TUINT m_Unknown2[15]
Unknown fields 11-25.
HALMemInfo()
Constructor for HALMemInfo Initializes all fields to zero.
TSIZE m_uiMemUsage
Total memory usage.