BfAstAllocator.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. #include "BfAstAllocator.h"
  2. #include "BfSource.h"
  3. #include "BfSystem.h"
  4. //Craps();
  5. USING_NS_BF;
  6. BfBitSet::BfBitSet()
  7. {
  8. mBits = NULL;
  9. }
  10. BfBitSet::~BfBitSet()
  11. {
  12. delete [] mBits;
  13. }
  14. void BfBitSet::Init(int numBits)
  15. {
  16. BF_ASSERT(mBits == NULL);
  17. int numInts = (numBits + 31) / 32;
  18. mBits = new uint32[numInts];
  19. memset(mBits, 0, numInts * 4);
  20. }
  21. bool BfBitSet::IsSet(int idx)
  22. {
  23. return (mBits[idx / 32] & (1 << (idx % 32))) != 0;
  24. }
  25. void BfBitSet::Set(int idx)
  26. {
  27. mBits[idx / 32] |= (1 << (idx % 32));
  28. }
  29. void BfBitSet::Clear(int idx)
  30. {
  31. mBits[idx / 32] &= ~(1 << (idx % 32));
  32. }
  33. //////////////////////////////////////////////////////////////////////////
  34. BfAstAllocator::BfAstAllocator()
  35. {
  36. mSourceData = NULL;
  37. mCurPtr = NULL;
  38. mCurPageEnd = mCurPtr;
  39. mLargeAllocSizes = 0;
  40. mNumPagesUsed = 0;
  41. mUsedSize = 0;
  42. }
  43. BfAstAllocator::~BfAstAllocator()
  44. {
  45. for (auto addr : mLargeAllocs)
  46. delete [] (uint8*)addr;
  47. if (mPages.size() != 0)
  48. mSourceData->mAstAllocManager->FreePages(mPages);
  49. }
  50. void BfAstAllocator::InitChunkHead(int wantSize)
  51. {
  52. mCurPtr = mSourceData->mAstAllocManager->AllocPage();
  53. mPages.push_back(mCurPtr);
  54. mCurPageEnd = mCurPtr + BfAstAllocManager::PAGE_SIZE;
  55. mNumPagesUsed++;
  56. #ifdef BF_AST_ALLOCATOR_USE_PAGES
  57. BfAstPageHeader* pageHeader = (BfAstPageHeader*)mCurPtr;
  58. pageHeader->mSourceData = mSourceData;
  59. BF_ASSERT(sizeof(BfAstPageHeader) <= 16);
  60. mCurPtr += 16;
  61. #endif
  62. }
  63. //////////////////////////////////////////////////////////////////////////
  64. BfAstAllocManager::BfAstAllocManager()
  65. {
  66. #ifdef BF_AST_ALLOCATOR_USE_PAGES
  67. mFreePageCount = 0;
  68. #endif
  69. }
  70. BfAstAllocManager::~BfAstAllocManager()
  71. {
  72. #ifdef BF_AST_ALLOCATOR_USE_PAGES
  73. for (int chunkIdx = (int)mAllocChunks.size() - 1; chunkIdx >= 0; chunkIdx--)
  74. {
  75. auto chunk = mAllocChunks[chunkIdx];
  76. ::VirtualFree(chunk, 0, MEM_RELEASE);
  77. //BfLog("BfAstAllocManager free %p\n", chunk);
  78. }
  79. #endif
  80. }
  81. //TODO: Remove this
  82. //static int gAstChunkAllocCount = 0;
  83. uint8* BfAstAllocManager::AllocPage()
  84. {
  85. #ifdef BF_AST_ALLOCATOR_USE_PAGES
  86. AutoCrit autoCrit(mCritSect);
  87. if (mFreePageCount != 0)
  88. {
  89. mFreePageCount--;
  90. return (uint8*)mFreePages.PopFront();
  91. }
  92. BF_ASSERT(mFreePages.mHead == NULL);
  93. //auto newChunk = (uint8*)::VirtualAlloc((void*)(0x4200000000 + gAstChunkAllocCount*CHUNK_SIZE), CHUNK_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
  94. //gAstChunkAllocCount++;
  95. auto newChunk = (uint8*)::VirtualAlloc(NULL, CHUNK_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
  96. BF_ASSERT(newChunk != NULL);
  97. BF_ASSERT(((intptr)newChunk & (PAGE_SIZE - 1)) == 0);
  98. mAllocChunks.push_back(newChunk);
  99. //BfLog("BfAstAllocManager alloc %p\n", newChunk);
  100. for (uint8* ptr = newChunk; ptr < newChunk + CHUNK_SIZE; ptr += PAGE_SIZE)
  101. {
  102. auto freePage = (BfAstFreePage*)ptr;
  103. mFreePages.PushBack(freePage);
  104. mFreePageCount++;
  105. }
  106. mFreePageCount--;
  107. return (uint8*)mFreePages.PopFront();
  108. #else
  109. return new uint8[PAGE_SIZE];
  110. #endif
  111. }
  112. void BfAstAllocManager::FreePage(uint8* page)
  113. {
  114. #ifdef BF_AST_ALLOCATOR_USE_PAGES
  115. AutoCrit autoCrit(mCritSect);
  116. mFreePageCount++;
  117. auto pageVal = (BfAstFreePage*)page;
  118. pageVal->mNext = NULL;
  119. mFreePages.PushFront(pageVal);
  120. #else
  121. delete[] page;
  122. #endif
  123. }
  124. void BfAstAllocManager::FreePages(Array<uint8*> pages)
  125. {
  126. #ifdef BF_AST_ALLOCATOR_USE_PAGES
  127. AutoCrit autoCrit(mCritSect);
  128. for (auto page : pages)
  129. {
  130. mFreePageCount++;
  131. auto pageVal = (BfAstFreePage*)page;
  132. pageVal->mNext = NULL;
  133. mFreePages.PushFront(pageVal);
  134. }
  135. #else
  136. for (auto page : pages)
  137. delete[] page;
  138. #endif
  139. }
  140. void BfAstAllocManager::GetStats(int& allocPages, int& usedPages)
  141. {
  142. #ifdef BF_AST_ALLOCATOR_USE_PAGES
  143. AutoCrit autoCrit(mCritSect);
  144. //mShowStats = true;
  145. allocPages = (int)mAllocChunks.size() * CHUNK_SIZE / PAGE_SIZE;
  146. usedPages = allocPages - mFreePageCount;
  147. #else
  148. allocPages = 0;
  149. usedPages = 0;
  150. #endif
  151. }