2019-08-23 11:56:54 -07:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
//#define BUMPALLOC_ETW_TRACING
|
|
|
|
|
|
|
|
#include "../Common.h"
|
|
|
|
|
|
|
|
//#define BUMPALLOC_TRACKALLOCS
|
2020-04-03 12:32:42 -07:00
|
|
|
//#define BUMPALLOC_STOMPALLOC
|
2019-08-23 11:56:54 -07:00
|
|
|
|
|
|
|
#ifdef BUMPALLOC_ETW_TRACING
|
|
|
|
#include "VSCustomNativeHeapEtwProvider.h"
|
|
|
|
#endif
|
|
|
|
|
2020-04-03 12:32:42 -07:00
|
|
|
#ifdef BUMPALLOC_STOMPALLOC
|
|
|
|
void* StompAlloc(int size);
|
|
|
|
void StompFree(void* addr);
|
|
|
|
#endif
|
|
|
|
|
2019-08-23 11:56:54 -07:00
|
|
|
#ifdef BUMPALLOC_TRACKALLOCS
|
|
|
|
#include "Dictionary.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
NS_BF_BEGIN
|
|
|
|
|
|
|
|
#ifdef BUMPALLOC_TRACKALLOCS
|
|
|
|
struct BumpAllocTrackedEntry
|
|
|
|
{
|
|
|
|
int mCount;
|
|
|
|
int mSize;
|
|
|
|
|
|
|
|
BumpAllocTrackedEntry()
|
|
|
|
{
|
|
|
|
mCount = 0;
|
|
|
|
mSize = 0;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
|
|
|
template <int ALLOC_SIZE = 0x2000>
|
|
|
|
class BumpAllocatorT
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
Array<uint8*> mPools;
|
|
|
|
Array<int> mSizes;
|
|
|
|
uint8* mCurAlloc;
|
|
|
|
uint8* mCurPtr;
|
|
|
|
int mCurChunkNum;
|
|
|
|
int mPrevSizes;
|
|
|
|
bool mBumpAlloc;
|
|
|
|
bool mDisableDebugTracing;
|
|
|
|
#ifdef BUMPALLOC_ETW_TRACING
|
|
|
|
static VSHeapTracker::CHeapTracker* mVSHeapTracker;
|
|
|
|
#endif
|
|
|
|
#ifdef BUMPALLOC_TRACKALLOCS
|
|
|
|
Dictionary<String, BumpAllocTrackedEntry> mTrackedAllocs;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
public:
|
|
|
|
BumpAllocatorT()
|
|
|
|
{
|
|
|
|
#ifdef BUMPALLOC_ETW_TRACING
|
|
|
|
if (mVSHeapTracker == NULL)
|
|
|
|
mVSHeapTracker = new VSHeapTracker::CHeapTracker("BumpAllocator");
|
|
|
|
#endif
|
|
|
|
mCurAlloc = NULL;
|
|
|
|
mCurPtr = (uint8*)(intptr)ALLOC_SIZE;
|
|
|
|
mBumpAlloc = true;
|
|
|
|
mDisableDebugTracing = false;
|
|
|
|
mCurChunkNum = -1;
|
|
|
|
mPrevSizes = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
~BumpAllocatorT()
|
|
|
|
{
|
|
|
|
Clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Clear()
|
|
|
|
{
|
|
|
|
mCurAlloc = NULL;
|
|
|
|
mCurPtr = (uint8*)(intptr)ALLOC_SIZE;
|
|
|
|
for (auto ptr : mPools)
|
2020-04-03 12:32:42 -07:00
|
|
|
#ifdef BUMPALLOC_STOMPALLOC
|
|
|
|
StompFree(ptr);
|
|
|
|
#else
|
2019-08-23 11:56:54 -07:00
|
|
|
free(ptr);
|
2020-04-03 12:32:42 -07:00
|
|
|
#endif
|
2019-08-23 11:56:54 -07:00
|
|
|
mPools.Clear();
|
|
|
|
mSizes.Clear();
|
|
|
|
mCurChunkNum = -1;
|
|
|
|
mPrevSizes = 0;
|
|
|
|
|
|
|
|
#ifdef BUMPALLOC_TRACKALLOCS
|
|
|
|
mTrackedAllocs.Clear();
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
int GetAllocSize() const
|
|
|
|
{
|
|
|
|
return (int)(((mPools.size() - 1) * ALLOC_SIZE) + (mCurPtr - mCurAlloc));
|
|
|
|
}
|
|
|
|
|
|
|
|
int GetTotalAllocSize() const
|
|
|
|
{
|
|
|
|
return (int)mPools.size() * ALLOC_SIZE;
|
|
|
|
}
|
|
|
|
|
|
|
|
int CalcUsedSize() const
|
|
|
|
{
|
|
|
|
int totalSize = 0;
|
|
|
|
for (auto& size : mSizes)
|
|
|
|
totalSize += size;
|
|
|
|
totalSize += mCurPtr - mCurAlloc;
|
|
|
|
return totalSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef BUMPALLOC_ETW_TRACING
|
|
|
|
__declspec(allocator) void* RecordAlloc(void* addr, int size)
|
|
|
|
{
|
|
|
|
if (!mDisableDebugTracing)
|
|
|
|
mVSHeapTracker->AllocateEvent(addr, size);
|
|
|
|
return addr;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
bool ContainsPtr(void* ptr) const
|
|
|
|
{
|
|
|
|
for (auto poolPtr : mPools)
|
|
|
|
{
|
|
|
|
if ((ptr >= poolPtr) && (ptr < poolPtr + ALLOC_SIZE))
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void GrowPool()
|
|
|
|
{
|
|
|
|
mCurChunkNum = (int)mPools.size();
|
|
|
|
int curSize = (int)(mCurPtr - mCurAlloc);
|
|
|
|
mPrevSizes += curSize;
|
|
|
|
mSizes.push_back(curSize);
|
2020-04-03 12:32:42 -07:00
|
|
|
#ifdef BUMPALLOC_STOMPALLOC
|
|
|
|
mCurAlloc = (uint8*)StompAlloc(ALLOC_SIZE);
|
|
|
|
#else
|
|
|
|
mCurAlloc = (uint8*)malloc(ALLOC_SIZE);
|
|
|
|
#endif
|
2019-08-23 11:56:54 -07:00
|
|
|
memset(mCurAlloc, 0, ALLOC_SIZE);
|
|
|
|
mPools.push_back(mCurAlloc);
|
|
|
|
mCurPtr = mCurAlloc;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
T* Alloc(int extraBytes = 0)
|
|
|
|
{
|
|
|
|
int alignSize = alignof(T);
|
|
|
|
mCurPtr = (uint8*)(((intptr)mCurPtr + alignSize - 1) & ~(alignSize - 1));
|
|
|
|
|
|
|
|
//AutoPerf perf("Alloc");
|
|
|
|
int wantSize = sizeof(T) + extraBytes;
|
|
|
|
|
|
|
|
#ifdef BUMPALLOC_TRACKALLOCS
|
|
|
|
const char* name = typeid(T).name();
|
|
|
|
BumpAllocTrackedEntry* allocSizePtr;
|
|
|
|
mTrackedAllocs.TryAdd(name, NULL, &allocSizePtr);
|
|
|
|
allocSizePtr->mCount++;
|
|
|
|
allocSizePtr->mSize += wantSize;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (mCurPtr + wantSize >= mCurAlloc + ALLOC_SIZE)
|
|
|
|
GrowPool();
|
|
|
|
|
|
|
|
#ifdef BUMPALLOC_ETW_TRACING
|
|
|
|
//mVSHeapTracker->AllocateEvent(retVal, wantSize);
|
|
|
|
T* addr = (T*)RecordAlloc(mCurPtr, wantSize);
|
|
|
|
T* retVal = new (addr) T();
|
|
|
|
#else
|
|
|
|
T* retVal = new (mCurPtr) T();
|
|
|
|
#endif
|
|
|
|
//mWriteCurPtr = (uint8*)(((intptr)mWriteCurPtr + wantSize + 7) & ~7);
|
|
|
|
mCurPtr += wantSize;
|
|
|
|
|
|
|
|
return retVal;
|
|
|
|
}
|
|
|
|
|
|
|
|
int GetChunkedId(void* ptr) const
|
|
|
|
{
|
|
|
|
return (mCurChunkNum * ALLOC_SIZE) + (int)((uint8*)ptr - mCurAlloc);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8* GetChunkedPtr(int id) const
|
|
|
|
{
|
|
|
|
int chunkNum = id / ALLOC_SIZE;
|
|
|
|
int chunkOfs = id % ALLOC_SIZE;
|
|
|
|
return mPools[chunkNum] + chunkOfs;
|
|
|
|
}
|
|
|
|
|
|
|
|
int GetStreamPos(void* ptr) const
|
|
|
|
{
|
|
|
|
return mPrevSizes + (int)((uint8*)ptr - mCurAlloc);
|
|
|
|
}
|
|
|
|
|
2019-11-19 09:58:35 -08:00
|
|
|
uint8* AllocBytes(intptr wantSize, int alignSize, const char* dbgName = "AllocBytes")
|
2019-08-23 11:56:54 -07:00
|
|
|
{
|
|
|
|
mCurPtr = (uint8*)(((intptr)mCurPtr + alignSize - 1) & ~(alignSize - 1));
|
|
|
|
|
|
|
|
uint8* retVal = AllocBytes(wantSize, dbgName);
|
|
|
|
return retVal;
|
|
|
|
}
|
|
|
|
|
2019-11-19 09:58:35 -08:00
|
|
|
uint8* AllocBytes(intptr wantSize, const char* dbgName = "AllocBytes")
|
2019-08-23 11:56:54 -07:00
|
|
|
{
|
|
|
|
#ifdef BUMPALLOC_TRACKALLOCS
|
|
|
|
BumpAllocTrackedEntry* allocSizePtr;
|
|
|
|
mTrackedAllocs.TryAdd(dbgName, NULL, &allocSizePtr);
|
|
|
|
allocSizePtr->mCount++;
|
|
|
|
allocSizePtr->mSize += wantSize;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (wantSize > ALLOC_SIZE / 2)
|
|
|
|
{
|
2020-04-03 12:32:42 -07:00
|
|
|
#ifdef BUMPALLOC_STOMPALLOC
|
|
|
|
uint8* bigData = (uint8*)StompAlloc((int)wantSize);
|
|
|
|
#else
|
2019-08-23 11:56:54 -07:00
|
|
|
uint8* bigData = (uint8*)malloc(wantSize);
|
2020-04-03 12:32:42 -07:00
|
|
|
#endif
|
2019-08-23 11:56:54 -07:00
|
|
|
memset(bigData, 0, wantSize);
|
|
|
|
mPools.push_back(bigData);
|
|
|
|
return bigData;
|
|
|
|
}
|
2020-01-31 17:16:44 -08:00
|
|
|
|
2019-08-23 11:56:54 -07:00
|
|
|
if (mCurPtr + wantSize >= mCurAlloc + ALLOC_SIZE)
|
|
|
|
GrowPool();
|
|
|
|
|
|
|
|
#ifdef BUMPALLOC_ETW_TRACING
|
|
|
|
uint8* retVal = (uint8*)RecordAlloc(mCurPtr, wantSize);
|
|
|
|
#else
|
|
|
|
uint8* retVal = mCurPtr;
|
|
|
|
#endif
|
|
|
|
mCurPtr += wantSize;
|
|
|
|
|
|
|
|
return retVal;
|
|
|
|
}
|
2020-10-08 09:41:05 -07:00
|
|
|
|
|
|
|
char* AllocString(const StringImpl& str)
|
|
|
|
{
|
|
|
|
char* ptr = (char*)AllocBytes(str.length() + 1);
|
|
|
|
memcpy(ptr, str.c_str(), str.length() + 1);
|
|
|
|
return ptr;
|
|
|
|
}
|
2019-08-23 11:56:54 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
class BumpAllocator : public BumpAllocatorT<0x2000>
|
|
|
|
{
|
|
|
|
|
|
|
|
};
|
|
|
|
|
2024-12-29 11:02:17 -08:00
|
|
|
template <int ALLOC_SIZE = 0x2000>
|
|
|
|
class AllocatorBumpT
|
2019-08-23 11:56:54 -07:00
|
|
|
{
|
|
|
|
public:
|
2022-05-06 11:28:38 -07:00
|
|
|
BumpAllocatorT<ALLOC_SIZE>* mAlloc;
|
2019-08-23 11:56:54 -07:00
|
|
|
|
2024-12-29 11:02:17 -08:00
|
|
|
AllocatorBumpT()
|
2019-11-19 09:58:35 -08:00
|
|
|
{
|
|
|
|
mAlloc = NULL;
|
|
|
|
}
|
|
|
|
|
2024-12-29 11:02:17 -08:00
|
|
|
template <typename T>
|
2019-08-23 11:56:54 -07:00
|
|
|
T* allocate(intptr count)
|
|
|
|
{
|
|
|
|
return (T*)mAlloc->AllocBytes((int)(sizeof(T) * count), alignof(T));
|
|
|
|
}
|
|
|
|
|
2024-12-29 11:02:17 -08:00
|
|
|
void deallocate(void* ptr)
|
2019-08-23 11:56:54 -07:00
|
|
|
{
|
|
|
|
}
|
2019-11-19 09:58:35 -08:00
|
|
|
|
|
|
|
void* rawAllocate(intptr size)
|
|
|
|
{
|
|
|
|
return mAlloc->AllocBytes(size, 16);
|
|
|
|
}
|
|
|
|
|
|
|
|
void rawDeallocate(void* ptr)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
2019-08-23 11:56:54 -07:00
|
|
|
};
|
|
|
|
|
2024-12-29 11:02:17 -08:00
|
|
|
class AllocatorBump : public AllocatorBumpT<0x2000>
|
2022-05-06 11:28:38 -07:00
|
|
|
{
|
|
|
|
|
|
|
|
};
|
2019-08-23 11:56:54 -07:00
|
|
|
|
|
|
|
NS_BF_END
|
|
|
|
|