#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 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 }