Boost logo

Boost-Commit :

From: xushiweizh_at_[hidden]
Date: 2008-04-30 04:43:08


Author: xushiwei
Date: 2008-04-30 04:43:07 EDT (Wed, 30 Apr 2008)
New Revision: 44920
URL: http://svn.boost.org/trac/boost/changeset/44920

Log:
ticket #1885: release gc_alloc (pre-alpha)
Text files modified:
   sandbox/memory/boost/memory/basic.hpp | 4 -
   sandbox/memory/boost/memory/gc_alloc.hpp | 153 +++++++++++++++++++++++++++------------
   sandbox/memory/boost/memory/policy.hpp | 1
   3 files changed, 107 insertions(+), 51 deletions(-)

Modified: sandbox/memory/boost/memory/basic.hpp
==============================================================================
--- sandbox/memory/boost/memory/basic.hpp (original)
+++ sandbox/memory/boost/memory/basic.hpp 2008-04-30 04:43:07 EDT (Wed, 30 Apr 2008)
@@ -199,10 +199,6 @@
 }; \
 _NS_BOOST_END
 
-#define BOOST_INT_NO_DESTRUCTOR(Type) \
- BOOST_NO_DESTRUCTOR(unsigned Type); \
- BOOST_NO_DESTRUCTOR(signed Type)
-
 // -------------------------------------------------------------------------
 // BOOST_NO_CONSTRUCTOR
 

Modified: sandbox/memory/boost/memory/gc_alloc.hpp
==============================================================================
--- sandbox/memory/boost/memory/gc_alloc.hpp (original)
+++ sandbox/memory/boost/memory/gc_alloc.hpp 2008-04-30 04:43:07 EDT (Wed, 30 Apr 2008)
@@ -123,7 +123,11 @@
                         _MemHeader* BOOST_MEMORY_CALL first() const {
                                 return (_MemHeader*)m_start;
                         }
+ _MemHeader* BOOST_MEMORY_CALL current() const {
+ return (_MemHeader*)m_start;
+ }
                         _MemHeader* BOOST_MEMORY_CALL next() {
+ BOOST_MEMORY_ASSERT(!done());
                                 m_start += sizeof(_MemHeader) + ((_MemHeader*)m_start)->cbSize;
                                 return (_MemHeader*)m_start;
                         }
@@ -137,7 +141,7 @@
         struct _Pred : std::binary_function<_FreeMemHeader*, _FreeMemHeader*, bool>
         {
                 bool operator()(_FreeMemHeader* a, _FreeMemHeader* b) const {
- return a->cbSize > b->cbSize;
+ return a->cbSize < b->cbSize;
                 }
         };
         typedef std::deque<_FreeMemHeader*> _Cont;
@@ -150,9 +154,21 @@
         _MemBlock* m_blockList;
         _PriorityQ m_freeList;
         _HugeGCAlloc m_hugeAlloc;
+ size_t m_freeSize, m_GCLimitSize;
         static _FreeMemHeader _null;
 
 private:
+ enum { HeaderSize = sizeof(void*) };
+ enum { BlockSize = MemBlockSize - HeaderSize };
+ enum { _AllocSizeBigDef = MAX(_Policy::AllocSizeBig, BlockSize/4) };
+ enum { _AllocSizeHugeDef = MAX(_Policy::AllocSizeHuge, 64*1024) };
+ enum { _GCLimitSizeDef = MAX(_Policy::GCLimitSizeDef, 64*1024) };
+ enum { AllocSizeBig = MIN(_AllocSizeBigDef, BlockSize/2) };
+ enum { AllocSizeHuge = MIN(_AllocSizeHugeDef, (1 << 29)) };
+ enum { GCLimitSizeDef = MIN(_GCLimitSizeDef, (1 << 29)) };
+ enum { RecycleSizeMin = MAX(_Policy::RecycleSizeMin, 128) };
+
+private:
         const gen_alloc& operator=(const gen_alloc&);
 
         static bool BOOST_MEMORY_CALL _IsValid(void* obj, size_t cb, destructor_t fn)
@@ -198,35 +214,84 @@
                 }
         }
 
- void BOOST_MEMORY_CALL _ReduceDestroyChain() const
+public:
+ void BOOST_MEMORY_CALL force_gc()
         {
- _MemHeaderEx** pp = &m_destroyChain;
- while (*pp)
- {
- _MemHeaderEx* curr = (*pp)->pPrev;
- if (curr->blkType == nodeFree) {
- *pp = curr->pPrev;
- }
- else {
- pp = &curr->pPrev;
- }
- }
- }
+ // 0. Prepare
 
- void BOOST_MEMORY_CALL _Travel() const
- {
+ // 0.1. Commit current block:
+ _CommitCurrentBlock();
+ m_begin = m_end = _null.getData();
+
+ // 0.2. Clear destroy chain
+ m_destroyChain = NULL;
+
+ // 0.3. Clear free list
+ m_freeList.clear();
+ m_freeSize = 0;
+
+ // 1. Collect free nodes
                 _MemBlock* pHeader = m_blockList;
                 while (pHeader)
                 {
- _MemBlock::Enumerator coll(pHeader->pPrev);
+ _MemBlock::Enumerator coll(m_alloc, pHeader);
                         pHeader = pHeader->pPrev;
- for (_MemHeader* it = coll.first(); !coll.done(); it = coll.next())
- it;
+ for (;;)
+ {
+ if (coll.done())
+ break;
+ _MemHeader* it = coll.current();
+ if (it->blkType == nodeFree)
+ {
+ // merge nodes marked with nodeFree
+ UINT cbFree = it->cbSize;
+ for (;;) {
+ _MemHeader* it2 = coll.next();
+ if (coll.done() || it2->blkType != nodeFree)
+ break;
+ cbFree += it2->cbSize;
+ }
+ it->cbSize = cbFree;
+ if (cbFree >= RecycleSizeMin)
+ m_freeList.push((_FreeMemHeader*)it);
+ if (coll.done())
+ break;
+ it = coll.current();
+ }
+ if (it->blkType == nodeAllocedWithDestructor)
+ {
+ _MemHeaderEx* itEx = (_MemHeaderEx*)it;
+ itEx->pPrev = m_destroyChain;
+ m_destroyChain = itEx;
+ }
+ // skip nodes marked with nodeAlloced
+ coll.next();
+ }
                 }
         }
+
+ void BOOST_MEMORY_CALL try_gc()
+ {
+ if (m_freeSize >= m_GCLimitSize)
+ force_gc();
+ }
 
- void BOOST_MEMORY_CALL _TryGC()
+ size_t BOOST_MEMORY_CALL get_free_size() const
         {
+ return m_freeSize;
+ }
+
+ void BOOST_MEMORY_CALL set_gclim(size_t gcLimit)
+ {
+ m_GCLimitSize = gcLimit;
+ }
+
+private:
+ void BOOST_MEMORY_CALL _CommitCurrentBlock()
+ {
+ _FreeMemHeader* old = (_FreeMemHeader*)m_begin - 1;
+ BOOST_MEMORY_ASSERT(old->getBlockType() == nodeFree);
+ old->cbSize = (m_end - m_begin);
         }
 
         _MemHeader* BOOST_MEMORY_CALL _NewBlock(size_t cbBlock)
@@ -241,42 +306,26 @@
                 return pNew;
         }
 
- void BOOST_MEMORY_CALL _CommitCurrentBlock()
- {
- _FreeMemHeader* old = (_FreeMemHeader*)m_begin - 1;
- BOOST_MEMORY_ASSERT(old->getBlockType() == nodeFree);
- old->cbSize = (m_end - m_begin);
- }
-
         void BOOST_MEMORY_CALL _Init()
         {
+ m_blockList = NULL;
+ m_destroyChain = NULL;
+ m_freeSize = 0;
+ m_GCLimitSize = GCLimitSizeDef;
+
                 _MemHeader* pNew = _NewBlock(MemBlockSize);
                 m_begin = (char*)(pNew + 1);
                 m_end = m_begin + pNew->cbSize;
         }
 
-private:
- enum { HeaderSize = sizeof(void*) };
- enum { BlockSize = MemBlockSize - HeaderSize };
- enum { _AllocSizeBigDef = MAX(_Policy::AllocSizeBig, BlockSize/4) };
- enum { _AllocSizeHugeDef = MAX(_Policy::AllocSizeHuge, 64*1024) };
- enum { AllocSizeBig = MIN(_AllocSizeBigDef, BlockSize/2) };
- enum { AllocSizeHuge = MIN(_AllocSizeHugeDef, (1 << 29)) };
- enum { RecycleSizeMin = MAX(_Policy::RecycleSizeMin, 128) };
-
 public:
- gen_alloc() : m_blockList(NULL), m_destroyChain(NULL)
- {
+ gen_alloc() {
                 _Init();
         }
- explicit gen_alloc(_Alloc alloc)
- : m_alloc(alloc), m_blockList(NULL), m_destroyChain(NULL)
- {
+ explicit gen_alloc(_Alloc alloc) : m_alloc(alloc) {
                 _Init();
         }
- explicit gen_alloc(gen_alloc& owner)
- : m_alloc(owner.m_alloc), m_blockList(NULL), m_destroyChain(NULL)
- {
+ explicit gen_alloc(gen_alloc& owner) : m_alloc(owner.m_alloc) {
                 _Init();
         }
 
@@ -291,6 +340,8 @@
                 std::swap(m_end, o.m_end);
                 std::swap(m_blockList, o.m_blockList);
                 std::swap(m_destroyChain, o.m_destroyChain);
+ std::swap(m_freeSize, o.m_freeSize);
+ std::swap(m_GCLimitSize, o.m_GCLimitSize);
                 m_alloc.swap(o.m_alloc);
                 m_freeList.swap(o.m_freeList);
                 m_hugeAlloc.swap(o.m_hugeAlloc);
@@ -315,6 +366,7 @@
                 m_begin = m_end = _null.getData();
                 m_blockList = NULL;
                 m_freeList.clear();
+ m_freeSize = 0;
         }
 
         void* BOOST_MEMORY_CALL allocate(size_t cbData)
@@ -338,7 +390,7 @@
                         }
                         else
                         {
- _TryGC();
+ try_gc();
                                 _FreeMemHeader* p;
                                 if (m_freeList.empty() || (p = m_freeList.top())->cbSize < cb) {
                                         pNew = _NewBlock(MemBlockSize);
@@ -392,6 +444,7 @@
                         BOOST_MEMORY_ASSERT(p->blkType == nodeAlloced);
 
                         p->blkType = nodeFree;
+ m_freeSize += cbData + sizeof(_MemHeader);
                 }
         }
 
@@ -402,6 +455,7 @@
                 obj->~Type();
                 _MemHeaderEx* p = (_MemHeaderEx*)obj - 1;
                 p->blkType = nodeFree;
+ m_freeSize += sizeof(Type) + sizeof(_MemHeaderEx);
         }
 
         template <class Type>
@@ -409,15 +463,19 @@
         {
                 _MemHeader* p = (_MemHeader*)obj - 1;
                 p->blkType = nodeFree;
+ m_freeSize += sizeof(Type) + sizeof(_MemHeader);
         }
 
         template <class Type>
         void BOOST_MEMORY_CALL _DestroyArray(Type* array, size_t count, destructor_t)
         {
- destructor_traits<Type>::destructArrayN(array, count);
- void* pData = destructor_traits<Type>::getArrayBuffer(array);
+ typedef destructor_traits<Type> _Traits;
+
+ _Traits::destructArrayN(array, count);
+ void* pData = _Traits::getArrayBuffer(array);
                 _MemHeaderEx* p = (_MemHeaderEx*)pData - 1;
                 p->blkType = nodeFree;
+ m_freeSize += _Traits::getArrayAllocSize(count) + sizeof(_MemHeaderEx);
         }
 
         template <class Type>
@@ -425,6 +483,7 @@
         {
                 _MemHeader* p = (_MemHeader*)array - 1;
                 p->blkType = nodeFree;
+ m_freeSize += sizeof(Type) * count + sizeof(_MemHeaderEx);
         }
 
 public:

Modified: sandbox/memory/boost/memory/policy.hpp
==============================================================================
--- sandbox/memory/boost/memory/policy.hpp (original)
+++ sandbox/memory/boost/memory/policy.hpp 2008-04-30 04:43:07 EDT (Wed, 30 Apr 2008)
@@ -131,6 +131,7 @@
         enum { RecycleSizeMin = 256 };
         enum { AllocSizeBig = Default };
         enum { AllocSizeHuge = 1024*1024 };
+ enum { GCLimitSizeDef = 1024*1024 };
 
         typedef simple_gc_alloc<system_alloc> huge_gc_allocator;
 };


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk