diff options
Diffstat (limited to 'src/declarative/qml/parser/qdeclarativejsmemorypool_p.h')
-rw-r--r-- | src/declarative/qml/parser/qdeclarativejsmemorypool_p.h | 124 |
1 files changed, 82 insertions, 42 deletions
diff --git a/src/declarative/qml/parser/qdeclarativejsmemorypool_p.h b/src/declarative/qml/parser/qdeclarativejsmemorypool_p.h index 8d61dbe714..043331d9e8 100644 --- a/src/declarative/qml/parser/qdeclarativejsmemorypool_p.h +++ b/src/declarative/qml/parser/qdeclarativejsmemorypool_p.h @@ -57,8 +57,9 @@ #include <QtCore/qglobal.h> #include <QtCore/qshareddata.h> +#include <QtCore/qdebug.h> -#include <string.h> +#include <cstring> QT_QML_BEGIN_NAMESPACE @@ -66,64 +67,103 @@ namespace QDeclarativeJS { class QML_PARSER_EXPORT MemoryPool : public QSharedData { + MemoryPool(const MemoryPool &other); + void operator =(const MemoryPool &other); + public: - enum { maxBlockCount = -1 }; - enum { defaultBlockSize = 1 << 12 }; - - MemoryPool() { - m_blockIndex = maxBlockCount; - m_currentIndex = 0; - m_storage = 0; - m_currentBlock = 0; - m_currentBlockSize = 0; + MemoryPool() + : _blocks(0), + _allocatedBlocks(0), + _blockCount(-1), + _ptr(0), + _end(0) + { } + + ~MemoryPool() + { + if (_blocks) { + for (int i = 0; i < _allocatedBlocks; ++i) { + if (char *b = _blocks[i]) + qFree(b); + } + + qFree(_blocks); + } } - virtual ~MemoryPool() { - for (int index = 0; index < m_blockIndex + 1; ++index) - qFree(m_storage[index]); + inline void *allocate(size_t size) + { + size = (size + 7) & ~7; + if (_ptr && (_ptr + size < _end)) { + void *addr = _ptr; + _ptr += size; + return addr; + } + return allocate_helper(size); + } - qFree(m_storage); + void reset() + { + _blockCount = -1; + _ptr = _end = 0; } - char *allocate(int bytes) { - bytes += (8 - bytes) & 7; // ensure multiple of 8 bytes (maintain alignment) - if (m_currentBlock == 0 || m_currentBlockSize < m_currentIndex + bytes) { - ++m_blockIndex; - m_currentBlockSize = defaultBlockSize << m_blockIndex; +private: + void *allocate_helper(size_t size) + { + Q_ASSERT(size < BLOCK_SIZE); + + if (++_blockCount == _allocatedBlocks) { + if (! _allocatedBlocks) + _allocatedBlocks = DEFAULT_BLOCK_COUNT; + else + _allocatedBlocks *= 2; - m_storage = reinterpret_cast<char**>(qRealloc(m_storage, sizeof(char*) * (1 + m_blockIndex))); - m_currentBlock = m_storage[m_blockIndex] = reinterpret_cast<char*>(qMalloc(m_currentBlockSize)); - ::memset(m_currentBlock, 0, m_currentBlockSize); + _blocks = (char **) qRealloc(_blocks, sizeof(char *) * _allocatedBlocks); - m_currentIndex = (8 - quintptr(m_currentBlock)) & 7; // ensure first chunk is 64-bit aligned - Q_ASSERT(m_currentIndex + bytes <= m_currentBlockSize); + for (int index = _blockCount; index < _allocatedBlocks; ++index) + _blocks[index] = 0; } - char *p = reinterpret_cast<char *> - (m_currentBlock + m_currentIndex); + char *&block = _blocks[_blockCount]; - m_currentIndex += bytes; + if (! block) + block = (char *) qMalloc(BLOCK_SIZE); - return p; - } + _ptr = block; + _end = _ptr + BLOCK_SIZE; - int bytesAllocated() const { - int bytes = 0; - for (int index = 0; index < m_blockIndex; ++index) - bytes += (defaultBlockSize << index); - bytes += m_currentIndex; - return bytes; + void *addr = _ptr; + _ptr += size; + return addr; } private: - int m_blockIndex; - int m_currentIndex; - char *m_currentBlock; - int m_currentBlockSize; - char **m_storage; + char **_blocks; + int _allocatedBlocks; + int _blockCount; + char *_ptr; + char *_end; + + enum + { + BLOCK_SIZE = 8 * 1024, + DEFAULT_BLOCK_COUNT = 8 + }; +}; -private: - Q_DISABLE_COPY(MemoryPool) +class QML_PARSER_EXPORT Managed +{ + Managed(const Managed &other); + void operator = (const Managed &other); + +public: + Managed() {} + ~Managed() {} + + void *operator new(size_t size, MemoryPool *pool) { return pool->allocate(size); } + void operator delete(void *) {} + void operator delete(void *, MemoryPool *) {} }; } // namespace QDeclarativeJS |