浏览代码

Merge pull request #1786 from jamesu/datachunker_mem

Reduce the amount of blocks of memory DataChunker uses
Areloch 9 年之前
父节点
当前提交
e77642f6cb
共有 2 个文件被更改,包括 59 次插入27 次删除
  1. 18 12
      Engine/source/core/dataChunker.cpp
  2. 41 15
      Engine/source/core/dataChunker.h

+ 18 - 12
Engine/source/core/dataChunker.cpp

@@ -41,7 +41,9 @@ void *DataChunker::alloc(S32 size)
 {
    if (size > mChunkSize)
    {
-      DataBlock * temp = new DataBlock(size);
+      DataBlock * temp = (DataBlock*)dMalloc(DataChunker::PaddDBSize + size);
+      AssertFatal(temp, "Malloc failed");
+      constructInPlace(temp);
       if (mCurBlock)
       {
          temp->next = mCurBlock->next;
@@ -52,30 +54,32 @@ void *DataChunker::alloc(S32 size)
          mCurBlock = temp;
          temp->curIndex = mChunkSize;
       }
-      return temp->data;
+      return temp->getData();
    }
 
    if(!mCurBlock || size + mCurBlock->curIndex > mChunkSize)
    {
-      DataBlock *temp = new DataBlock(mChunkSize);
+      const U32 paddDBSize = (sizeof(DataBlock) + 3) & ~3;
+      DataBlock *temp = (DataBlock*)dMalloc(paddDBSize+ mChunkSize);
+      AssertFatal(temp, "Malloc failed");
+      constructInPlace(temp);
       temp->next = mCurBlock;
-      temp->curIndex = 0;
       mCurBlock = temp;
    }
-
-   void *ret = mCurBlock->data + mCurBlock->curIndex;
+   
+   void *ret = mCurBlock->getData() + mCurBlock->curIndex;
    mCurBlock->curIndex += (size + 3) & ~3; // dword align
    return ret;
 }
 
-DataChunker::DataBlock::DataBlock(S32 size)
+DataChunker::DataBlock::DataBlock()
 {
-   data = new U8[size];
+   curIndex = 0;
+   next = NULL;
 }
 
 DataChunker::DataBlock::~DataBlock()
 {
-   delete[] data;
 }
 
 void DataChunker::freeBlocks(bool keepOne)
@@ -83,15 +87,17 @@ void DataChunker::freeBlocks(bool keepOne)
    while(mCurBlock && mCurBlock->next)
    {
       DataBlock *temp = mCurBlock->next;
-      delete mCurBlock;
+      dFree(mCurBlock);
       mCurBlock = temp;
    }
    if (!keepOne)
    {
-      delete mCurBlock;
+      if (mCurBlock) dFree(mCurBlock);
       mCurBlock = NULL;
    }
    else if (mCurBlock)
+   {
       mCurBlock->curIndex = 0;
+      mCurBlock->next = NULL;
+   }
 }
-

+ 41 - 15
Engine/source/core/dataChunker.h

@@ -46,8 +46,21 @@
 class DataChunker
 {
 public:
+   /// Block of allocated memory.
+   ///
+   /// <b>This has nothing to do with datablocks as used in the rest of Torque.</b>
+   struct DataBlock
+   {
+      DataBlock* next;        ///< linked list pointer to the next DataBlock for this chunker
+      S32 curIndex;           ///< current allocation point within this DataBlock
+      DataBlock();
+      ~DataBlock();
+      inline U8 *getData();
+   };
+
    enum {
-      ChunkSize = 16376 ///< Default size of each DataBlock page in the DataChunker
+      PaddDBSize = (sizeof(DataBlock) + 3) & ~3, ///< Padded size of DataBlock
+      ChunkSize = 16384 - PaddDBSize ///< Default size of each DataBlock page in the DataChunker
    };
 
    /// Return a pointer to a chunk of memory from a pre-allocated block.
@@ -81,27 +94,40 @@ public:
       mCurBlock = temp;
    }
    
-private:
-   /// Block of allocated memory.
-   ///
-   /// <b>This has nothing to do with datablocks as used in the rest of Torque.</b>
-   struct DataBlock
+public:
+   U32 countUsedBlocks()
    {
-      DataBlock* prev;
-      DataBlock* next;        ///< linked list pointer to the next DataBlock for this chunker
-      U8 *data;               ///< allocated pointer for the base of this page
-      S32 curIndex;           ///< current allocation point within this DataBlock
-      DataBlock(S32 size);
-      ~DataBlock();
-   };
+      U32 count = 0;
+      if (!mCurBlock)
+         return 0;
+      for (DataBlock *ptr = mCurBlock; ptr != NULL; ptr = ptr->next)
+      {
+         count++;
+      }
+      return count;
+   }
+   
+   void setChunkSize(U32 size)
+   {
+      AssertFatal(mCurBlock == NULL, "Cant resize now");
+      mChunkSize = size;
+   }
+
+   
+public:
 
-   DataBlock*  mFirstBlock;
-   DataBlock   *mCurBlock;    ///< current page we're allocating data from.  If the
+   DataBlock*  mCurBlock;    ///< current page we're allocating data from.  If the
                               ///< data size request is greater than the memory space currently
                               ///< available in the current page, a new page will be allocated.
    S32         mChunkSize;    ///< The size allocated for each page in the DataChunker
 };
 
+
+inline U8 *DataChunker::DataBlock::getData()
+{
+   return (U8*)this + DataChunker::PaddDBSize;
+}
+
 //----------------------------------------------------------------------------
 
 template<class T>