aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/parser/qqmljsmemorypool_p.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/parser/qqmljsmemorypool_p.h')
-rw-r--r--src/qml/parser/qqmljsmemorypool_p.h128
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