Boost logo

Boost-Commit :

From: xushiweizh_at_[hidden]
Date: 2008-05-07 10:02:10


Author: xushiwei
Date: 2008-05-07 10:02:10 EDT (Wed, 07 May 2008)
New Revision: 45196
URL: http://svn.boost.org/trac/boost/changeset/45196

Log:
gc_alloc: memory align
Text files modified:
   sandbox/memory/boost/memory/gc_alloc.hpp | 160 ++++++++++++++++++++++------------------
   1 files changed, 88 insertions(+), 72 deletions(-)

Modified: sandbox/memory/boost/memory/gc_alloc.hpp
==============================================================================
--- sandbox/memory/boost/memory/gc_alloc.hpp (original)
+++ sandbox/memory/boost/memory/gc_alloc.hpp 2008-05-07 10:02:10 EDT (Wed, 07 May 2008)
@@ -35,6 +35,10 @@
 #define BOOST_MEMORY_TRACE_GC
 #endif
 
+#ifndef BOOST_MEMORY_ALIGN
+#define BOOST_MEMORY_ALIGN(x, y) (((x)+((y)-1)) & ~((y)-1))
+#endif
+
 #ifndef MAX
 #define MAX(a, b) ((a) < (b) ? (b) : (a))
 #endif
@@ -49,7 +53,7 @@
 private:
         typedef typename PolicyT::allocator_type AllocT;
         typedef typename PolicyT::huge_gc_allocator HugeGCAllocT;
- typedef size_t HeaderSizeT;
+ typedef unsigned HeaderSizeT;
 
 public:
         enum { MemBlockSize = PolicyT::MemBlockSize };
@@ -60,18 +64,43 @@
 
 #pragma pack(1)
 private:
+ enum { NodeSizeBits = 30 };
         enum MemNodeType {
- nodeFree = 0,
- nodeAlloced = 1,
- nodeAllocedWithDestructor = 3,
+ nodeFree = 0 << NodeSizeBits,
+ nodeAlloced = 1 << NodeSizeBits,
+ nodeAllocedWithDestructor = 3 << NodeSizeBits,
+ };
+ enum {
+ NodeTypeMask = 3 << NodeSizeBits,
+ NodeSizeMask = (1 << NodeSizeBits) - 1,
         };
         
         struct MemHeader
         {
- HeaderSizeT cbNodeSize : 30; // cbNodeSize = cbSize + sizeof(MemHeader)
- HeaderSizeT nodeType : 2;
+ HeaderSizeT dataMemHeader;
+ // HeaderSizeT cbNodeSize : 30; // cbNodeSize = cbSize + sizeof(MemHeader)
+ // HeaderSizeT nodeType : 2; // enum MemNodeType
+
+ HeaderSizeT BOOST_MEMORY_CALL getNodeType() const {
+ return NodeTypeMask & dataMemHeader;
+ }
+ HeaderSizeT BOOST_MEMORY_CALL getNodeSize() const {
+ return NodeSizeMask & dataMemHeader;
+ }
+ char* BOOST_MEMORY_CALL begin() const {
+ return (char*)this + sizeof(MemHeader);
+ }
+ char* BOOST_MEMORY_CALL end() const {
+ BOOST_MEMORY_ASSERT(getNodeType() == nodeFree);
+ return (char*)this + dataMemHeader;
+ }
+ void BOOST_MEMORY_CALL freeNode() {
+ dataMemHeader &= ~NodeTypeMask;
+ }
         };
 
+ typedef MemHeader FreeMemHeader;
+
         struct MemHeaderEx;
         struct DestroyInfo
         {
@@ -79,38 +108,22 @@
                 destructor_t fnDestroy;
         };
 
- struct MemHeaderEx // = MemHeader + DestroyInfo
+ struct MemHeaderEx : public MemHeader
         {
- HeaderSizeT cbNodeSize : 30;
- HeaderSizeT nodeType : 2;
-
                 MemHeaderEx* pPrev;
                 destructor_t fnDestroy;
 
                 void BOOST_MEMORY_CALL destruct() {
- if (nodeType == nodeAllocedWithDestructor) {
- nodeType = nodeFree;
+ if (getNodeType() == nodeAllocedWithDestructor) {
+ freeNode();
                                 fnDestroy(this + 1);
                         }
                 }
         };
 
+ friend struct MemHeader;
         friend struct MemHeaderEx;
 
- struct FreeMemHeader
- {
- HeaderSizeT cbNodeSize;
- HeaderSizeT BOOST_MEMORY_CALL getNodeType() const {
- return ((MemHeader*)this)->nodeType;
- }
- char* BOOST_MEMORY_CALL begin() const {
- return (char*)this + sizeof(FreeMemHeader);
- }
- char* BOOST_MEMORY_CALL end() const {
- return (char*)this + cbNodeSize;
- }
- };
-
         struct MemBlock
         {
                 MemBlock* pPrev;
@@ -135,7 +148,7 @@
                         }
                         MemHeader* BOOST_MEMORY_CALL next() {
                                 BOOST_MEMORY_ASSERT(!done());
- m_start += ((MemHeader*)m_start)->cbNodeSize;
+ m_start += ((MemHeader*)m_start)->getNodeSize();
                                 return (MemHeader*)m_start;
                         }
                         bool BOOST_MEMORY_CALL done() const {
@@ -148,7 +161,7 @@
         struct Pred : std::binary_function<FreeMemHeader*, FreeMemHeader*, bool>
         {
                 bool operator()(FreeMemHeader* a, FreeMemHeader* b) const {
- return a->cbNodeSize < b->cbNodeSize;
+ return a->dataMemHeader < b->dataMemHeader;
                 }
         };
         typedef std::vector<FreeMemHeader*> Container;
@@ -166,6 +179,7 @@
 
 private:
         enum { HeaderSize = sizeof(void*) };
+ enum { AlignSize = sizeof(HeaderSizeT) };
         enum { BlockSize = MemBlockSize - HeaderSize };
         enum { AllocSizeBigDef_ = MAX(PolicyT::AllocSizeBig, BlockSize/4) };
         enum { AllocSizeHugeDef_ = MAX(PolicyT::AllocSizeHuge, 64*1024) };
@@ -187,20 +201,20 @@
         {
                 MemHeaderEx* node = (MemHeaderEx*)obj - 1;
                 BOOST_MEMORY_ASSERT(node->fnDestroy == fn);
- BOOST_MEMORY_ASSERT(_isEqual(node->cbNodeSize, cb + sizeof(MemHeaderEx)));
- BOOST_MEMORY_ASSERT(node->nodeType == nodeAllocedWithDestructor);
+ BOOST_MEMORY_ASSERT(_isEqual(node->getNodeSize(), cb + sizeof(MemHeaderEx)));
+ BOOST_MEMORY_ASSERT(node->getNodeType() == nodeAllocedWithDestructor);
                 return node->fnDestroy == fn &&
- _isEqual(node->cbNodeSize, cb + sizeof(MemHeaderEx)) &&
- node->nodeType == nodeAllocedWithDestructor;
+ _isEqual(node->getNodeSize(), cb + sizeof(MemHeaderEx)) &&
+ node->getNodeType() == nodeAllocedWithDestructor;
         }
 
         static bool BOOST_MEMORY_CALL _isValid(void* obj, size_t cb, int fnZero)
         {
                 MemHeader* node = (MemHeader*)obj - 1;
- BOOST_MEMORY_ASSERT(_isEqual(node->cbNodeSize, sizeof(MemHeader) + cb));
- BOOST_MEMORY_ASSERT(node->nodeType == nodeAlloced);
- return _isEqual(node->cbNodeSize, sizeof(MemHeader) + cb) &&
- node->nodeType == nodeAlloced;
+ BOOST_MEMORY_ASSERT(_isEqual(node->getNodeSize(), sizeof(MemHeader) + cb));
+ BOOST_MEMORY_ASSERT(node->getNodeType() == nodeAlloced);
+ return _isEqual(node->getNodeSize(), sizeof(MemHeader) + cb) &&
+ node->getNodeType() == nodeAlloced;
         }
 
         template <class Type>
@@ -264,9 +278,9 @@
                                                 FreeMemHeader* it2 = (FreeMemHeader*)coll.next();
                                                 if (coll.done() || it2->getNodeType() != nodeFree)
                                                         break;
- it->cbNodeSize += it2->cbNodeSize;
+ it->dataMemHeader += it2->dataMemHeader;
                                         }
- if (it->cbNodeSize >= RecycleSizeMin)
+ if (it->dataMemHeader >= RecycleSizeMin)
                                                 m_freeList.push(it);
                                         if (coll.done())
                                                 break;
@@ -302,7 +316,7 @@
                 while (m_destroyCount)
                 {
                         MemHeaderEx* curr = *pp;
- if (curr->nodeType == nodeFree) {
+ if (curr->getNodeType() == nodeFree) {
                                 *pp = curr->pPrev;
                                 --m_destroyCount;
                         }
@@ -320,7 +334,7 @@
                         pNode->getNodeType() == nodeAlloced &&
                         _null.begin() == m_begin && m_begin == m_end);
                 
- pNode->cbNodeSize = sizeof(FreeMemHeader) + (m_end - m_begin);
+ pNode->dataMemHeader = sizeof(FreeMemHeader) + (m_end - m_begin);
         }
 
         FreeMemHeader* BOOST_MEMORY_CALL _newBlock(size_t cbBlock)
@@ -330,7 +344,7 @@
                 m_blockList = pBlock;
 
                 FreeMemHeader* pNew = (FreeMemHeader*)pBlock->buffer;
- pNew->cbNodeSize = m_alloc.alloc_size(pBlock) - HeaderSize;
+ pNew->dataMemHeader = m_alloc.alloc_size(pBlock) - HeaderSize;
                 return pNew;
         }
 
@@ -400,16 +414,15 @@
                 m_destroyCount = 0;
         }
 
- void* BOOST_MEMORY_CALL allocate(size_t cbData)
+ void* BOOST_MEMORY_CALL allocate(const size_t cbData)
         {
- const size_t cb = cbData + sizeof(MemHeader);
+ const size_t cb = BOOST_MEMORY_ALIGN(cbData, AlignSize) + sizeof(MemHeader);
                 if ((size_t)(m_end - m_begin) < cb)
                 {
                         if ((size_t)(m_end - m_begin) >= cbData)
                         {
                                 MemHeader* pAlloc = (MemHeader*)m_begin - 1;
- pAlloc->nodeType = nodeAlloced;
- pAlloc->cbNodeSize = m_end - (char*)pAlloc;
+ pAlloc->dataMemHeader = (nodeAlloced | (m_end - (char*)pAlloc));
                                 m_begin = m_end = _null.begin();
                                 return pAlloc + 1;
                         }
@@ -422,7 +435,7 @@
                                                 return m_hugeAlloc.allocate(cbData);
 
                                         MemHeader* pAlloc = (MemHeader*)_newBlock(cb + HeaderSize);
- pAlloc->nodeType = nodeAlloced;
+ pAlloc->dataMemHeader |= nodeAlloced;
                                         return pAlloc + 1;
                                 }
                                 pNew = _newBlock(MemBlockSize);
@@ -430,7 +443,7 @@
                         else
                         {
                                 try_gc();
- if (m_freeList.empty() || (pNew = m_freeList.top())->cbNodeSize < cb) {
+ if (m_freeList.empty() || (pNew = m_freeList.top())->getNodeSize() < cb) {
                                         pNew = _newBlock(MemBlockSize);
                                 }
                                 else {
@@ -445,21 +458,21 @@
                 BOOST_MEMORY_ASSERT((size_t)(m_end - m_begin) >= cb);
 
                 MemHeader* pAlloc = (MemHeader*)(m_end -= cb);
- pAlloc->nodeType = nodeAlloced;
- pAlloc->cbNodeSize = cb;
+ pAlloc->dataMemHeader = (nodeAlloced | cb);
                 return pAlloc + 1;
         }
 
- void* BOOST_MEMORY_CALL allocate(size_t cb, destructor_t fn)
+ void* BOOST_MEMORY_CALL allocate(const size_t cbData0, destructor_t fn)
         {
- const size_t cbAlloc = cb + sizeof(MemHeaderEx);
+ const size_t cbData = sizeof(DestroyInfo) + cbData0;
+ const size_t cbAlloc = BOOST_MEMORY_ALIGN(cbData, AlignSize) + sizeof(MemHeader);
                 if (cbAlloc >= AllocSizeHuge)
- return m_hugeAlloc.allocate(cb, fn);
+ return m_hugeAlloc.allocate(cbData0, fn);
                 
- MemHeaderEx* pNode = (MemHeaderEx*)((char*)allocate(sizeof(DestroyInfo) + cb) - sizeof(MemHeader));
+ MemHeaderEx* pNode = (MemHeaderEx*)((char*)allocate(cbData) - sizeof(MemHeader));
                 pNode->fnDestroy = fn;
                 pNode->pPrev = m_destroyChain;
- pNode->nodeType = nodeAllocedWithDestructor;
+ pNode->dataMemHeader |= nodeAllocedWithDestructor;
                 m_destroyChain = pNode;
                 return pNode + 1;
         }
@@ -469,11 +482,14 @@
                 return allocate(cb);
         }
 
- void* BOOST_MEMORY_CALL unmanaged_alloc(size_t cb, destructor_t fn)
+ void* BOOST_MEMORY_CALL unmanaged_alloc(size_t cbData0, destructor_t fn)
         {
- BOOST_MEMORY_ASSERT(cb + sizeof(MemHeaderEx) < AllocSizeHuge);
+ const size_t cbData = sizeof(DestroyInfo) + cbData0;
+
+ BOOST_MEMORY_ASSERT(
+ BOOST_MEMORY_ALIGN(cbData, AlignSize) + sizeof(MemHeader) < AllocSizeHuge);
 
- DestroyInfo* pInfo = (DestroyInfo*)allocate(sizeof(DestroyInfo) + cb);
+ DestroyInfo* pInfo = (DestroyInfo*)allocate(cbData);
                 pInfo->fnDestroy = fn;
                 return pInfo + 1;
         }
@@ -482,10 +498,10 @@
         {
                 MemHeaderEx* pNode = (MemHeaderEx*)p - 1;
                 BOOST_MEMORY_ASSERT(pNode->fnDestroy == fn);
- BOOST_MEMORY_ASSERT(pNode->nodeType == nodeAlloced);
+ BOOST_MEMORY_ASSERT(pNode->getNodeType() == nodeAlloced);
 
                 pNode->pPrev = m_destroyChain;
- pNode->nodeType = nodeAllocedWithDestructor;
+ pNode->dataMemHeader |= nodeAllocedWithDestructor;
                 m_destroyChain = pNode;
                 return p;
         }
@@ -500,9 +516,9 @@
                 return p;
         }
 
- void BOOST_MEMORY_CALL deallocate(void* pData, size_t cbData)
+ void BOOST_MEMORY_CALL deallocate(void* pData, const size_t cbData)
         {
- const size_t cb = cbData + sizeof(MemHeader);
+ const size_t cb = BOOST_MEMORY_ALIGN(cbData, AlignSize) + sizeof(MemHeader);
                 
                 if (cb >= AllocSizeHuge)
                 {
@@ -511,10 +527,10 @@
                 else
                 {
                         MemHeader* p = (MemHeader*)pData - 1;
- BOOST_MEMORY_ASSERT(p->cbNodeSize == cb);
- BOOST_MEMORY_ASSERT(p->nodeType == nodeAlloced);
+ BOOST_MEMORY_ASSERT(p->getNodeSize() >= cb);
+ BOOST_MEMORY_ASSERT(p->getNodeType() == nodeAlloced);
 
- ((FreeMemHeader*)p)->cbNodeSize = cb;
+ p->freeNode();
                         m_freeSize += cb;
                 }
         }
@@ -532,11 +548,12 @@
         void BOOST_MEMORY_CALL _destroy(Type* obj, destructor_t)
         {
                 const size_t cb = sizeof(Type) + sizeof(MemHeaderEx);
+ BOOST_MEMORY_ASSERT( BOOST_MEMORY_ALIGN(cb, AlignSize) < AllocSizeHuge );
                 
                 obj->~Type();
                 MemHeaderEx* p = (MemHeaderEx*)obj - 1;
                 
- ((FreeMemHeader*)p)->cbNodeSize = cb;
+ p->freeNode();
                 m_freeSize += cb;
                 ++m_destroyCount;
         }
@@ -545,10 +562,11 @@
         void BOOST_MEMORY_CALL _destroy(Type* obj, int)
         {
                 const size_t cb = sizeof(Type) + sizeof(MemHeader);
+ BOOST_MEMORY_ASSERT( BOOST_MEMORY_ALIGN(cb, AlignSize) < AllocSizeHuge );
                 
                 MemHeader* p = (MemHeader*)obj - 1;
                 
- ((FreeMemHeader*)p)->cbNodeSize = cb;
+ p->freeNode();
                 m_freeSize += cb;
         }
 
@@ -563,7 +581,7 @@
                 void* pData = Traits::getArrayBuffer(array);
                 MemHeaderEx* p = (MemHeaderEx*)pData - 1;
                 
- ((FreeMemHeader*)p)->cbNodeSize = cb;
+ p->freeNode();
                 m_freeSize += cb;
                 ++m_destroyCount;
         }
@@ -575,7 +593,7 @@
 
                 MemHeader* p = (MemHeader*)array - 1;
 
- ((FreeMemHeader*)p)->cbNodeSize = cb;
+ p->freeNode();
                 m_freeSize += cb;
         }
 
@@ -584,8 +602,6 @@
         void BOOST_MEMORY_CALL destroy(Type* obj)
         {
                 BOOST_MEMORY_ASSERT( _isValid(obj) );
- BOOST_MEMORY_ASSERT( sizeof(Type) < AllocSizeHuge );
-
                 _destroy(obj, destructor_traits<Type>::destruct);
         }
 
@@ -596,7 +612,7 @@
                         destructor_traits<Type>::HasDestructor * sizeof(DestroyInfo) +
                         destructor_traits<Type>::getArrayAllocSize(count);
 
- if (cb >= AllocSizeHuge)
+ if (BOOST_MEMORY_ALIGN(cb, AlignSize) >= AllocSizeHuge)
                         return m_hugeAlloc.newArray(count, zero);
 
                 Type* array = (Type*)destructor_traits<Type>::allocArray(*this, count);
@@ -612,7 +628,7 @@
                         destructor_traits<Type>::HasDestructor * sizeof(DestroyInfo) +
                         destructor_traits<Type>::getArrayAllocSize(count);
 
- if (cb >= AllocSizeHuge)
+ if (BOOST_MEMORY_ALIGN(cb, AlignSize) >= AllocSizeHuge)
                 {
                         m_hugeAlloc.destroyArray(array, count);
                 }


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