diff options
author | Max Horn | 2008-10-12 22:05:26 +0000 |
---|---|---|
committer | Max Horn | 2008-10-12 22:05:26 +0000 |
commit | 95474b048aa742f500f276f782e9998eccfce8d9 (patch) | |
tree | d1724aeabc9af30742c64a2cb85e27970bfd648a | |
parent | 24dea3aff2e635f19695ac680a33bb6738bbad97 (diff) | |
download | scummvm-rg350-95474b048aa742f500f276f782e9998eccfce8d9.tar.gz scummvm-rg350-95474b048aa742f500f276f782e9998eccfce8d9.tar.bz2 scummvm-rg350-95474b048aa742f500f276f782e9998eccfce8d9.zip |
COMMON: Added a new ObjectPool class, with matching operator new/delete overloads
svn-id: r34785
-rw-r--r-- | common/hashmap.h | 27 | ||||
-rw-r--r-- | common/memorypool.cpp | 4 | ||||
-rw-r--r-- | common/memorypool.h | 34 | ||||
-rw-r--r-- | common/str.cpp | 4 | ||||
-rw-r--r-- | common/xmlparser.h | 10 |
5 files changed, 43 insertions, 36 deletions
diff --git a/common/hashmap.h b/common/hashmap.h index 81f5ee84b4..bbc227b3ae 100644 --- a/common/hashmap.h +++ b/common/hashmap.h @@ -37,15 +37,6 @@ #define USE_HASHMAP_MEMORY_POOL #ifdef USE_HASHMAP_MEMORY_POOL #include "common/memorypool.h" -// FIXME: we sadly can't assume standard C++ to be present -// on every system we support, so we should get rid of this. -// The solution should be to write a simple placement new -// on our own. - -// Symbian does not have <new> but the new operator -#if !defined(__SYMBIAN32__) -#include <new> -#endif #endif namespace Common { @@ -100,27 +91,15 @@ public: }; -#ifdef USE_HASHMAP_MEMORY_POOL - FixedSizeMemoryPool<sizeof(Node), HASHMAP_MEMORYPOOL_SIZE> _nodePool; + ObjectPool<Node, HASHMAP_MEMORYPOOL_SIZE> _nodePool; Node *allocNode(const Key &key) { - void* mem = _nodePool.malloc(); - return new (mem) Node(key); + return new (_nodePool) Node(key); } void freeNode(Node *node) { - node->~Node(); - _nodePool.free(node); + _nodePool.deleteChunk(node); } -#else - Node* allocNode(const Key &key) { - return new Node(key); - } - - void freeNode(Node *node) { - delete node; - } -#endif Node **_storage; // hashtable of size arrsize. uint _mask; /**< Capacity of the HashMap minus one; must be a power of two of minus one */ diff --git a/common/memorypool.cpp b/common/memorypool.cpp index 12307ba5d6..b117d13931 100644 --- a/common/memorypool.cpp +++ b/common/memorypool.cpp @@ -79,7 +79,7 @@ void MemoryPool::addPageToPool(const Page &page) { _next = page.start; } -void *MemoryPool::malloc() { +void *MemoryPool::allocChunk() { if (!_next) // No free chunks left? Allocate a new page allocPage(); @@ -89,7 +89,7 @@ void *MemoryPool::malloc() { return result; } -void MemoryPool::free(void* ptr) { +void MemoryPool::freeChunk(void *ptr) { // Add the chunk back to (the start of) the list of free chunks *(void**)ptr = _next; _next = ptr; diff --git a/common/memorypool.h b/common/memorypool.h index dd2e8f13a4..22326941f3 100644 --- a/common/memorypool.h +++ b/common/memorypool.h @@ -29,6 +29,7 @@ #include "common/scummsys.h" #include "common/array.h" + namespace Common { class MemoryPool { @@ -54,10 +55,12 @@ public: MemoryPool(size_t chunkSize); ~MemoryPool(); - void *malloc(); - void free(void *ptr); + void *allocChunk(); + void freeChunk(void *ptr); void freeUnusedPages(); + + size_t getChunkSize() const { return _chunkSize; } }; template<size_t CHUNK_SIZE, size_t NUM_INTERNAL_CHUNKS = 32> @@ -83,6 +86,33 @@ public: FixedSizeMemoryPool() : MemoryPool(CHUNK_SIZE) {} }; + +template<class T, size_t NUM_INTERNAL_CHUNKS = 32> +class ObjectPool : public FixedSizeMemoryPool<sizeof(T), NUM_INTERNAL_CHUNKS> { +public: + void deleteChunk(T *ptr) { + ptr->~T(); + freeChunk(ptr); + } +}; + } // End of namespace Common +// Provide a custom placement new operator, using an arbitrary +// MemoryPool. +// +// This *should* work with all C++ implementations, but may not. +// +// For details on using placement new for custom allocators, see e.g. +// <http://www.parashift.com/c++-faq-lite/dtors.html#faq-11.14> + +inline void* operator new(size_t nbytes, Common::MemoryPool& pool) { + assert(nbytes <= pool.getChunkSize()); + return pool.allocChunk(); +} + +inline void operator delete(void* p, Common::MemoryPool& pool) { + pool.freeChunk(p); +} + #endif diff --git a/common/str.cpp b/common/str.cpp index 303ed7bfac..00e88bfc3b 100644 --- a/common/str.cpp +++ b/common/str.cpp @@ -193,7 +193,7 @@ void String::incRefCount() const { if (g_refCountPool == 0) g_refCountPool = new MemoryPool(sizeof(int)); - _extern._refCount = (int *)g_refCountPool->malloc(); + _extern._refCount = (int *)g_refCountPool->allocChunk(); *_extern._refCount = 2; } else { ++(*_extern._refCount); @@ -212,7 +212,7 @@ void String::decRefCount(int *oldRefCount) { // and the ref count storage. if (oldRefCount) { assert(g_refCountPool); - g_refCountPool->free(oldRefCount); + g_refCountPool->freeChunk(oldRefCount); } free(_str); diff --git a/common/xmlparser.h b/common/xmlparser.h index cd2580b448..31ba4e594e 100644 --- a/common/xmlparser.h +++ b/common/xmlparser.h @@ -51,7 +51,7 @@ namespace Common { #define MAX_XML_DEPTH 8 #define XML_KEY(keyName) {\ - lay = new CustomXMLKeyLayout;\ + lay = new CustomXMLKeyLayout;\ lay->callback = (&kLocalParserName::parserCallback_##keyName);\ layout.top()->children[#keyName] = lay;\ layout.push(lay); \ @@ -169,16 +169,14 @@ public: XMLKeyLayout *layout; }; - FixedSizeMemoryPool<sizeof(ParserNode), MAX_XML_DEPTH> _nodePool; + ObjectPool<ParserNode, MAX_XML_DEPTH> _nodePool; ParserNode *allocNode() { - void* mem = _nodePool.malloc(); - return new (mem) ParserNode; + return new (_nodePool) ParserNode; } void freeNode(ParserNode *node) { - node->~ParserNode(); - _nodePool.free(node); + _nodePool.deleteChunk(node); } /** |