void xHeap::FreeLarge(void * p) { ASSERT("Trying to free NULL pointer" && p); ASSERT("Heap corrupted!" && largeStats.allocCount > largeStats.freeCount); #ifdef DEBUG_APP_HEAP p = (uint8*)p - sizeof(int); ASSERT("Heap corrupted!" && *(int*)p == DUMMY_LARGE_USED_ID_PRE); *(int*)p = DUMMY_LARGE_FREE_ID_PRE; #endif Block * block = ((Block*)p) - 1; ASSERT("Double deallocation!" && !block->isFree); #ifdef DEBUG_APP_HEAP { int * check_p = (int*)((uint8*)p + block->DataSize() + sizeof(int)); ASSERT("Heap corrupted!" && *check_p == DUMMY_LARGE_USED_ID_POST); *check_p = DUMMY_LARGE_FREE_ID_POST; } #endif uint32 size = block->size; largeStats.RegisterFree(size, block->DataSize()); largeStats.allocSize -= size; block->RemoveLink(); // MEMSET(block, 0, size); FREE(block); }
xHeap::~xHeap() { #if defined(_DEBUG) || defined(DEBUG_APP_HEAP_DUMP_LEAK_ON_EXIT) const char * dumpFilename = "dump-err-exit.log"; if(smallStats.allocCount != smallStats.freeCount #ifndef USE_APP_HEAP_SAVING_MODE || mediumStats.allocCount != mediumStats.freeCount #endif // USE_APP_HEAP_SAVING_MODE || largeStats.allocCount != largeStats.freeCount ) { DumpUsage(dumpFilename); } else { // IFILEMGR_Remove(fileMgr, dumpFilename); } #endif #ifdef _MSC_VER ASSERT("Memory leak found!" && smallStats.allocCount == smallStats.freeCount); #ifndef USE_APP_HEAP_SAVING_MODE ASSERT("Memory leak found!" && mediumStats.allocCount == mediumStats.freeCount); #endif // USE_APP_HEAP_SAVING_MODE ASSERT("Memory leak found!" && largeStats.allocCount == largeStats.freeCount); #endif // _MSC_VER // if(smallStats.allocCount == smallStats.freeCount) { while(smallPage != &dummySmallPage) { SmallPage * curPage = smallPage; smallPage = smallPage->next; FREE(curPage); } } // if(largeStats.allocCount == largeStats.freeCount) { while(dummyLargeBlock.next != &dummyLargeBlock) { void * p = (char*)(dummyLargeBlock.next+1) + DUMMY_ID_SIZE/2; Free(p); } } #ifndef USE_APP_HEAP_SAVING_MODE // if(mediumStats.allocCount == mediumStats.freeCount) { for(Block * block = dummyBlock.next, * next; block != &dummyBlock; block = next) { next = block->next; if(!block->isFree) { void * p = (char*)(block+1) + DUMMY_ID_SIZE/2; Free(p); } } while(dummyBlock.next != &dummyBlock) { Block * curBlockPage = dummyBlock.next; curBlockPage->RemoveLink(); #ifdef _MSC_VER ASSERT("Heap corrupted!" && curBlockPage->page != curBlockPage->next->page); ASSERT("Heap corrupted!" && curBlockPage->page != curBlockPage->prev->page); #endif // _MSC_VER FREE(curBlockPage); } } #endif // USE_APP_HEAP_SAVING_MODE if(instance == this) { *((xHeap**)(&instance)) = NULL; } }
void xHeap::FreeMedium(void * p) { ASSERT("Trying to free NULL pointer" && p); ASSERT("Heap corrupted!" && mediumStats.allocCount > mediumStats.freeCount); #ifdef DEBUG_APP_HEAP p = (uint8*)p - sizeof(int); ASSERT("Heap corrupted!" && *(int*)p == DUMMY_MEDIUM_USED_ID_PRE); // *(int*)p = DUMMY_MEDIUM_FREE_ID_PRE; #endif Block * block = ((Block*)p) - 1; ASSERT("Double deallocation!" && !block->isFree); #ifdef DEBUG_APP_HEAP { ASSERT("Heap corrupted!" && *((int*)((uint8*)p + block->DataSize() + sizeof(int))) == DUMMY_MEDIUM_USED_ID_POST); // *check_p = DUMMY_MEDIUM_FREE_ID_POST; } #endif mediumStats.RegisterFree(block->size, block->DataSize()); Block * prev = block->prev; if(prev->isFree && prev->page == block->page) { ASSERT("Heap corrupted!" && ((uint8*)prev) + prev->size == (uint8*)block); prev->size += block->size; ((FreeBlock*)prev)->RemoveFreeLink(); block->RemoveLink(); block = prev; mediumStats.mergeCount++; } Block * next = block->next; if(next->isFree && next->page == block->page) { ASSERT("Heap corrupted!" && ((uint8*)block) + block->size == (uint8*)next); block->size += next->size; ((FreeBlock*)next)->RemoveFreeLink(); next->RemoveLink(); mediumStats.mergeCount++; } block->isFree = true; #ifdef DEBUG_APP_HEAP *(int*)(block+1) = DUMMY_MEDIUM_FREE_ID_PRE; *(int*)((uint8*)(block+1) + block->DataSize() + sizeof(int)) = DUMMY_MEDIUM_FREE_ID_POST; #endif InsertFreeBlock((FreeBlock*)block); #if defined(DEBUG_APP_HEAP) && defined(AEE_SIMULATOR) // CheckMemory(); #endif }