1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 03:28:20 +02:00
Beef/IDEHelper/Compiler/BfAstAllocator.cpp
2019-08-23 11:56:54 -07:00

180 lines
No EOL
3.7 KiB
C++

#include "BfAstAllocator.h"
#include "BfSource.h"
#include "BfSystem.h"
//Craps();
USING_NS_BF;
BfBitSet::BfBitSet()
{
mBits = NULL;
}
BfBitSet::~BfBitSet()
{
delete [] mBits;
}
void BfBitSet::Init(int numBits)
{
BF_ASSERT(mBits == NULL);
int numInts = (numBits + 31) / 32;
mBits = new uint32[numInts];
memset(mBits, 0, numInts * 4);
}
bool BfBitSet::IsSet(int idx)
{
return (mBits[idx / 32] & (1 << (idx % 32))) != 0;
}
void BfBitSet::Set(int idx)
{
mBits[idx / 32] |= (1 << (idx % 32));
}
void BfBitSet::Clear(int idx)
{
mBits[idx / 32] &= ~(1 << (idx % 32));
}
//////////////////////////////////////////////////////////////////////////
BfAstAllocator::BfAstAllocator()
{
mSourceData = NULL;
mCurPtr = NULL;
mCurPageEnd = mCurPtr;
mLargeAllocSizes = 0;
mNumPagesUsed = 0;
mUsedSize = 0;
}
BfAstAllocator::~BfAstAllocator()
{
for (auto addr : mLargeAllocs)
delete [] (uint8*)addr;
if (mPages.size() != 0)
mSourceData->mAstAllocManager->FreePages(mPages);
}
void BfAstAllocator::InitChunkHead(int wantSize)
{
mCurPtr = mSourceData->mAstAllocManager->AllocPage();
mPages.push_back(mCurPtr);
mCurPageEnd = mCurPtr + BfAstAllocManager::PAGE_SIZE;
mNumPagesUsed++;
#ifdef BF_AST_ALLOCATOR_USE_PAGES
BfAstPageHeader* pageHeader = (BfAstPageHeader*)mCurPtr;
pageHeader->mSourceData = mSourceData;
BF_ASSERT(sizeof(BfAstPageHeader) <= 16);
mCurPtr += 16;
#endif
}
//////////////////////////////////////////////////////////////////////////
BfAstAllocManager::BfAstAllocManager()
{
#ifdef BF_AST_ALLOCATOR_USE_PAGES
mFreePageCount = 0;
#endif
}
BfAstAllocManager::~BfAstAllocManager()
{
#ifdef BF_AST_ALLOCATOR_USE_PAGES
for (int chunkIdx = (int)mAllocChunks.size() - 1; chunkIdx >= 0; chunkIdx--)
{
auto chunk = mAllocChunks[chunkIdx];
::VirtualFree(chunk, 0, MEM_RELEASE);
//BfLog("BfAstAllocManager free %p\n", chunk);
}
#endif
}
//TODO: Remove this
//static int gAstChunkAllocCount = 0;
uint8* BfAstAllocManager::AllocPage()
{
#ifdef BF_AST_ALLOCATOR_USE_PAGES
AutoCrit autoCrit(mCritSect);
if (mFreePageCount != 0)
{
mFreePageCount--;
return (uint8*)mFreePages.PopFront();
}
BF_ASSERT(mFreePages.mHead == NULL);
//auto newChunk = (uint8*)::VirtualAlloc((void*)(0x4200000000 + gAstChunkAllocCount*CHUNK_SIZE), CHUNK_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
//gAstChunkAllocCount++;
auto newChunk = (uint8*)::VirtualAlloc(NULL, CHUNK_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
BF_ASSERT(newChunk != NULL);
BF_ASSERT(((intptr)newChunk & (PAGE_SIZE - 1)) == 0);
mAllocChunks.push_back(newChunk);
//BfLog("BfAstAllocManager alloc %p\n", newChunk);
for (uint8* ptr = newChunk; ptr < newChunk + CHUNK_SIZE; ptr += PAGE_SIZE)
{
auto freePage = (BfAstFreePage*)ptr;
mFreePages.PushBack(freePage);
mFreePageCount++;
}
mFreePageCount--;
return (uint8*)mFreePages.PopFront();
#else
return new uint8[PAGE_SIZE];
#endif
}
void BfAstAllocManager::FreePage(uint8* page)
{
#ifdef BF_AST_ALLOCATOR_USE_PAGES
AutoCrit autoCrit(mCritSect);
mFreePageCount++;
auto pageVal = (BfAstFreePage*)page;
pageVal->mNext = NULL;
mFreePages.PushFront(pageVal);
#else
delete[] page;
#endif
}
void BfAstAllocManager::FreePages(Array<uint8*> pages)
{
#ifdef BF_AST_ALLOCATOR_USE_PAGES
AutoCrit autoCrit(mCritSect);
for (auto page : pages)
{
mFreePageCount++;
auto pageVal = (BfAstFreePage*)page;
pageVal->mNext = NULL;
mFreePages.PushFront(pageVal);
}
#else
for (auto page : pages)
delete[] page;
#endif
}
void BfAstAllocManager::GetStats(int& allocPages, int& usedPages)
{
#ifdef BF_AST_ALLOCATOR_USE_PAGES
AutoCrit autoCrit(mCritSect);
//mShowStats = true;
allocPages = (int)mAllocChunks.size() * CHUNK_SIZE / PAGE_SIZE;
usedPages = allocPages - mFreePageCount;
#else
allocPages = 0;
usedPages = 0;
#endif
}