diff options
Diffstat (limited to 'src/qml/parser/qqmljsmemorypool_p.h')
-rw-r--r-- | src/qml/parser/qqmljsmemorypool_p.h | 128 |
1 files changed, 103 insertions, 25 deletions
diff --git a/src/qml/parser/qqmljsmemorypool_p.h b/src/qml/parser/qqmljsmemorypool_p.h index 536f5d4239..bcd6d8672b 100644 --- a/src/qml/parser/qqmljsmemorypool_p.h +++ b/src/qml/parser/qqmljsmemorypool_p.h @@ -71,13 +71,7 @@ class QML_PARSER_EXPORT MemoryPool : public QSharedData void operator =(const MemoryPool &other); public: - MemoryPool() - : _blocks(0), - _allocatedBlocks(0), - _blockCount(-1), - _ptr(0), - _end(0) - { } + MemoryPool() {} ~MemoryPool() { @@ -89,11 +83,12 @@ public: free(_blocks); } + qDeleteAll(strings); } inline void *allocate(size_t size) { - size = (size + 7) & ~7; + size = (size + 7) & ~size_t(7); if (Q_LIKELY(_ptr && (_ptr + size < _end))) { void *addr = _ptr; _ptr += size; @@ -105,15 +100,24 @@ public: void reset() { _blockCount = -1; - _ptr = _end = 0; + _ptr = _end = nullptr; } template <typename Tp> Tp *New() { return new (this->allocate(sizeof(Tp))) Tp(); } + template <typename Tp, typename... Ta> Tp *New(Ta... args) + { return new (this->allocate(sizeof(Tp))) Tp(args...); } + + QStringRef newString(const QString &string) { + strings.append(new QString(string)); + return QStringRef(strings.last()); + } private: Q_NEVER_INLINE void *allocate_helper(size_t size) { - Q_ASSERT(size < BLOCK_SIZE); + size_t currentBlockSize = DEFAULT_BLOCK_SIZE; + while (Q_UNLIKELY(size >= currentBlockSize)) + currentBlockSize *= 2; if (++_blockCount == _allocatedBlocks) { if (! _allocatedBlocks) @@ -121,22 +125,22 @@ private: else _allocatedBlocks *= 2; - _blocks = (char **) realloc(_blocks, sizeof(char *) * _allocatedBlocks); + _blocks = reinterpret_cast<char **>(realloc(_blocks, sizeof(char *) * size_t(_allocatedBlocks))); Q_CHECK_PTR(_blocks); for (int index = _blockCount; index < _allocatedBlocks; ++index) - _blocks[index] = 0; + _blocks[index] = nullptr; } char *&block = _blocks[_blockCount]; if (! block) { - block = (char *) malloc(BLOCK_SIZE); + block = reinterpret_cast<char *>(malloc(currentBlockSize)); Q_CHECK_PTR(block); } _ptr = block; - _end = _ptr + BLOCK_SIZE; + _end = _ptr + currentBlockSize; void *addr = _ptr; _ptr += size; @@ -144,33 +148,107 @@ private: } private: - char **_blocks; - int _allocatedBlocks; - int _blockCount; - char *_ptr; - char *_end; + char **_blocks = nullptr; + int _allocatedBlocks = 0; + int _blockCount = -1; + char *_ptr = nullptr; + char *_end = nullptr; + QVector<QString*> strings; enum { - BLOCK_SIZE = 8 * 1024, + DEFAULT_BLOCK_SIZE = 8 * 1024, DEFAULT_BLOCK_COUNT = 8 }; }; class QML_PARSER_EXPORT Managed { - Managed(const Managed &other); - void operator = (const Managed &other); - + Q_DISABLE_COPY(Managed) public: - Managed() {} - ~Managed() {} + Managed() = default; + ~Managed() = default; void *operator new(size_t size, MemoryPool *pool) { return pool->allocate(size); } void operator delete(void *) {} void operator delete(void *, MemoryPool *) {} }; +template <typename T> +class FixedPoolArray +{ + T *data; + int count = 0; + +public: + FixedPoolArray() + : data(nullptr) + {} + + FixedPoolArray(MemoryPool *pool, int size) + { allocate(pool, size); } + + void allocate(MemoryPool *pool, int size) + { + count = size; + data = reinterpret_cast<T*>(pool->allocate(count * sizeof(T))); + } + + void allocate(MemoryPool *pool, const QVector<T> &vector) + { + count = vector.count(); + data = reinterpret_cast<T*>(pool->allocate(count * sizeof(T))); + + if (QTypeInfo<T>::isComplex) { + for (int i = 0; i < count; ++i) + new (data + i) T(vector.at(i)); + } else { + memcpy(data, static_cast<const void*>(vector.constData()), count * sizeof(T)); + } + } + + template <typename Container> + void allocate(MemoryPool *pool, const Container &container) + { + count = container.count(); + data = reinterpret_cast<T*>(pool->allocate(count * sizeof(T))); + typename Container::ConstIterator it = container.constBegin(); + for (int i = 0; i < count; ++i) + new (data + i) T(*it++); + } + + int size() const + { return count; } + + const T &at(int index) const { + Q_ASSERT(index >= 0 && index < count); + return data[index]; + } + + T &at(int index) { + Q_ASSERT(index >= 0 && index < count); + return data[index]; + } + + T &operator[](int index) { + return at(index); + } + + + int indexOf(const T &value) const { + for (int i = 0; i < count; ++i) + if (data[i] == value) + return i; + return -1; + } + + const T *begin() const { return data; } + const T *end() const { return data + count; } + + T *begin() { return data; } + T *end() { return data + count; } +}; + } // namespace QQmlJS QT_QML_END_NAMESPACE |