Index: memorypool.h =================================================================== --- memorypool.h (Revision 34748) +++ memorypool.h (Arbeitskopie) @@ -29,6 +29,7 @@ #include "common/scummsys.h" #include "common/array.h" + namespace Common { class MemoryPool { @@ -54,10 +55,12 @@ 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 @@ -83,6 +86,28 @@ FixedSizeMemoryPool() : MemoryPool(CHUNK_SIZE) {} }; + +template +class ObjectPool : public FixedSizeMemoryPool { +}; + } // 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. +// + +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 Index: str.cpp =================================================================== --- str.cpp (Revision 34748) +++ str.cpp (Arbeitskopie) @@ -193,7 +193,7 @@ 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 @@ // and the ref count storage. if (oldRefCount) { assert(g_refCountPool); - g_refCountPool->free(oldRefCount); + g_refCountPool->freeChunk(oldRefCount); } free(_str); Index: memorypool.cpp =================================================================== --- memorypool.cpp (Revision 34748) +++ memorypool.cpp (Arbeitskopie) @@ -79,7 +79,7 @@ _next = page.start; } -void *MemoryPool::malloc() { +void *MemoryPool::allocChunk() { if (!_next) // No free chunks left? Allocate a new page allocPage(); @@ -89,7 +89,7 @@ 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; Index: hashmap.h =================================================================== --- hashmap.h (Revision 34748) +++ hashmap.h (Arbeitskopie) @@ -37,16 +37,7 @@ #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 but the new operator -#if !defined(__SYMBIAN32__) -#include #endif -#endif namespace Common { @@ -100,28 +91,16 @@ }; -#ifdef USE_HASHMAP_MEMORY_POOL - FixedSizeMemoryPool _nodePool; + ObjectPool _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); + operator delete(node, _nodePool); } -#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 */ uint _size;