Esempio n. 1
0
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);
}
Esempio n. 2
0
uint32 xHeap::SizeLarge(void * p)
{
  ASSERT("Trying to free NULL pointer" && p);

#ifdef DEBUG_APP_HEAP
  p = (uint8*)p - sizeof(int);
  ASSERT("Heap corrupted!" && *(int*)p == DUMMY_LARGE_USED_ID_PRE);
#endif

  Block * block = ((Block*)p) - 1;

#ifdef DEBUG_APP_HEAP
  ASSERT("Heap corrupted!" && *(int*)((uint8*)p + block->DataSize() +
        sizeof(int)) == DUMMY_LARGE_USED_ID_POST);
#endif

  return block->DataSize();
}
Esempio n. 3
0
void * xHeap::AllocLarge(uint32 size, const char * filename, int line)
{
#else
void * xHeap::AllocLarge(uint32 size)
{
#endif
  size = (size + ALIGN - 1 + sizeof(Block) + DUMMY_ID_SIZE) & ~(ALIGN - 1);
  Block * block = (Block *)MALLOC(size);
  if(!block)
  {
    return NULL;
  }

#ifdef DEBUG_APP_HEAP
  block->filename = filename;
  block->line = line;
#endif
  block->page = (uint16)-1;
  block->size = size;
  block->isFree = false;
  block->InsertBefore(dummyLargeBlock.next);

  largeStats.allocSize += size;
  
  uint32 dataSize = block->DataSize();
  largeStats.RegisterAlloc(block->size, dataSize);

  uint8 * p = (uint8*)(block + 1);
#ifndef USE_APP_HEAP_SAVING_MODE
  p[-1] = BT_LARGE;
#else
  p[-1] &= ~BLOCK_TYPE_MASK;
#endif

#ifdef DEBUG_APP_HEAP
  *(int*)p = DUMMY_LARGE_USED_ID_PRE;
  p += sizeof(int);
  *(int*)(p + dataSize) = DUMMY_LARGE_USED_ID_POST;
#endif

  MEMSET(p, 0, dataSize);

#if defined(DEBUG_APP_HEAP) && defined(AEE_SIMULATOR)
  // CheckMemory();
#endif

  return p;
}
Esempio n. 4
0
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
}
Esempio n. 5
0
void * xHeap::AllocMedium(uint32 size, const char * filename, int line)
{
#else
void * xHeap::AllocMedium(uint32 size)
{
#endif

#ifdef DEBUG_APP_HEAP
  // static int step = 0;
  // step++;
#endif

  uint32 saveSize = size;
  size = (size + ALIGN - 1 + sizeof(Block) + DUMMY_ID_SIZE) & ~(ALIGN - 1);
  Block * block = dummyFree.nextFree;
  if(block->size < size) // block == &dummyFree => dummyFree.size == 0
  {
    if(size > pageSize / 2)
    {
#ifdef DEBUG_APP_HEAP
      return AllocLarge(saveSize, filename, line);
#else
      return AllocLarge(saveSize);
#endif
    }
    block = (Block*)MALLOC(pageSize);
    if(!block)
    {
      return NULL;
    }
#ifdef DEBUG_APP_HEAP
    block->filename = filename;
    block->line = line;
#endif
    block->page = nextPage++;
    block->size = pageSize;
    block->isFree = true;
    block->InsertBefore(dummyBlock.next);
    ((FreeBlock*)block)->InsertBeforeFreeLink(dummyFree.nextFree);

    mediumStats.allocSize += block->size;
  }
  else
  {
    mediumStats.hitCount++;
#ifdef FIND_BEST_FREE_BLOCK
    for(FreeBlock * next = ((FreeBlock*)block)->nextFree; next->size >= size; )
    {
      block = next;
      next = ((FreeBlock*)block)->nextFree;
    }
#endif
  }

  block->size -= size;
  if(block->size < MAX_SMALL_SIZE && (block->size < MAX_SMALL_SIZE/2 || block->next->page != block->page))
  {
#ifdef DEBUG_APP_HEAP
    block->filename = filename;
    block->line = line;
#endif
    block->size += size;
    ((FreeBlock*)block)->RemoveFreeLink();
  }
  else
  {
#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

    if(block->size < ((FreeBlock*)block)->nextFree->size)
    {
      ((FreeBlock*)block)->RemoveFreeLink();
      InsertFreeBlock((FreeBlock*)block);
    }
    ASSERT("Heap corrupted!" && (block->size & 3) == 0);
    Block * newBlock = (Block*)(((uint8*)block) + block->size);
#ifdef DEBUG_APP_HEAP
    newBlock->filename = filename;
    newBlock->line = line;
#endif
    newBlock->page = block->page;
    newBlock->size = size;
    newBlock->InsertAfter(block);    
    block = newBlock;
  }
  block->isFree = false;

  uint32 dataSize = block->DataSize();
  mediumStats.RegisterAlloc(block->size, dataSize);

  uint8 * p = (uint8*)(block+1);
  p[-1] = BT_MEDIUM;

#ifdef DEBUG_APP_HEAP
  *(int*)p = DUMMY_MEDIUM_USED_ID_PRE;
  p += sizeof(int);
  *(int*)(p + dataSize) = DUMMY_MEDIUM_USED_ID_POST;
#endif

  MEMSET(p, 0, dataSize);

#if defined(DEBUG_APP_HEAP) && defined(AEE_SIMULATOR)
  // CheckMemory();
#endif

  return p;
}
Esempio n. 6
0
void xHeap::CheckMemory()
{
#ifdef DEBUG_APP_HEAP

  uint32 allocSize, usedSize, dataSize;

  allocSize = usedSize = dataSize = 0;
  for(SmallPage * smallPage = this->smallPage; smallPage;
      smallPage = smallPage->next)
  {
    allocSize += smallPage->size;
  }
  ASSERT("Heap corrupted!" && allocSize == smallStats.allocSize);

  for(SmallBlock * smallBlock = dummySmallBlock.next;
      smallBlock != &dummySmallBlock; smallBlock = smallBlock->next)
  {
    ASSERT("Heap corrupted!" && smallBlock->next->prev == smallBlock);
    ASSERT("Heap corrupted!" && smallBlock->prev->next == smallBlock);

    uint32 blockDataSize = smallBlock->DataSize();
    ASSERT("Heap corrupted!" && (blockDataSize & 3) == 0);
    ASSERT("Heap corrupted!" && blockDataSize <= MAX_SMALL_SIZE);
    ASSERT("Heap corrupted!" && blockDataSize >=
        smallStats.minBlockDataSize);
    ASSERT("Heap corrupted!" && blockDataSize <=
        smallStats.maxBlockDataSize);

    ASSERT("Heap corrupted!" && *(int *)(smallBlock + 1) ==
        DUMMY_SMALL_USED_ID_PRE);
    ASSERT("Heap corrupted!" && *(int *)((uint8 *)(smallBlock + 1) +
          blockDataSize + sizeof(int)) == DUMMY_SMALL_USED_ID_POST);

    usedSize += smallBlock->Size();
    dataSize += blockDataSize;
  }
  ASSERT("Heap corrupted!" && usedSize == smallStats.usedSize);
  ASSERT("Heap corrupted!" && dataSize == smallStats.dataSize);

  for(int i = 0; i < SMALL_SLOT_COUNT; i++)
  {
    for(FreeSmallBlock * freeSmallBlock = freeSmallBlocks[i];
        freeSmallBlock; freeSmallBlock = freeSmallBlock->next)
    {
#ifndef NDEBUG /* fixing warning with unused smallBlock variable */
      SmallBlock * smallBlock = (SmallBlock*)freeSmallBlock;
      ASSERT("Heap corrupted!" && (smallBlock->DataSize() & 3) == 0);
      ASSERT("Heap corrupted!" && smallBlock->sizeSlot == (uint8)i);
      ASSERT("Heap corrupted!" && *(int *)(smallBlock + 1) ==
          DUMMY_SMALL_FREE_ID_PRE);
      ASSERT("Heap corrupted!" && *(int *)((uint8 *)(smallBlock + 1) +
            smallBlock->DataSize() + sizeof(int)) ==
          DUMMY_SMALL_FREE_ID_POST);
#endif/*NDEBUG*/
    }
  }

#ifndef USE_APP_HEAP_SAVING_MODE

  allocSize = usedSize = dataSize = 0;
  for(Block * block = dummyBlock.next; block != &dummyBlock;
      block = block->next)
  {
    ASSERT("Heap corrupted!" && block->isFree == 0 || block->isFree == 1);
    ASSERT("Heap corrupted!" && block->page < nextPage);
    ASSERT("Heap corrupted!" && block->next->prev == block);
    ASSERT("Heap corrupted!" && block->prev->next == block);
    
    uint32 blockDataSize = block->DataSize();
    ASSERT("Heap corrupted!" && (blockDataSize & 3) == 0);
    if(!block->isFree)
    {
      ASSERT("Heap corrupted!" && blockDataSize >=
          mediumStats.minBlockDataSize);
      ASSERT("Heap corrupted!" && blockDataSize <=
          mediumStats.maxBlockDataSize);
      ASSERT("Heap corrupted!" && *(int *)(block + 1) ==
          DUMMY_MEDIUM_USED_ID_PRE);
      ASSERT("Heap corrupted!" && *(int *)((uint8 *)(block + 1) +
            blockDataSize + sizeof(int)) == DUMMY_MEDIUM_USED_ID_POST);
      
      usedSize += block->size;
      dataSize += blockDataSize;
    }
    else
    {
      // ASSERT("Heap corrupted!" && dataSize < pageSize);
      ASSERT("Heap corrupted!" && *(int *)(block + 1) ==
          DUMMY_MEDIUM_FREE_ID_PRE);
      ASSERT("Heap corrupted!" && *(int *)((uint8 *)(block + 1) +
            blockDataSize + sizeof(int)) == DUMMY_MEDIUM_FREE_ID_POST);
    }
    allocSize += block->size;
  }
  ASSERT("Heap corrupted!" && allocSize == mediumStats.allocSize);
  ASSERT("Heap corrupted!" && usedSize == mediumStats.usedSize);
  ASSERT("Heap corrupted!" && dataSize == mediumStats.dataSize);

  for(FreeBlock * block = dummyFree.nextFree; block != &dummyFree;
      block = block->nextFree)
  {
    ASSERT("Heap corrupted!" && block->isFree == 1);
    ASSERT("Heap corrupted!" && block->page < nextPage);
    ASSERT("Heap corrupted!" && block->nextFree->prevFree == block);
    ASSERT("Heap corrupted!" && block->prevFree->nextFree == block);
  }
#endif // USE_APP_HEAP_SAVING_MODE

  allocSize = usedSize = dataSize = 0;

  for(Block * largeBlock = dummyLargeBlock.next;
      largeBlock != &dummyLargeBlock; largeBlock = largeBlock->next)
  {
    ASSERT("Heap corrupted!" && largeBlock->next->prev == largeBlock);
    ASSERT("Heap corrupted!" && largeBlock->prev->next == largeBlock);

    uint32 blockDataSize = largeBlock->DataSize();
    ASSERT("Heap corrupted!" && blockDataSize >=
        largeStats.minBlockDataSize);
    ASSERT("Heap corrupted!" && blockDataSize <=
        largeStats.maxBlockDataSize);

    allocSize += largeBlock->size;
    usedSize += largeBlock->size;
    dataSize += blockDataSize;
  }
  ASSERT("Heap corrupted!" && allocSize == largeStats.allocSize);
  ASSERT("Heap corrupted!" && usedSize == largeStats.usedSize);
  ASSERT("Heap corrupted!" && dataSize == largeStats.dataSize);
#endif // DEBUG_APP_HEAP
}