diff options
author | Vitaly Fanaskov <vitaly.fanaskov@qt.io> | 2018-11-27 15:09:11 +0100 |
---|---|---|
committer | Vitaly Fanaskov <vitaly.fanaskov@qt.io> | 2018-11-28 14:54:36 +0000 |
commit | 0e87966c8f815269b770a0a31974e0cd5b8ab26e (patch) | |
tree | 0a9a5eee7d4b7a0086000295e60d0c3ca9db42cd /src/qml/parser/qqmljsmemorypool_p.h | |
parent | e1a0e894aa09dd1323a7792192f1d68ee6677f8a (diff) |
Fix failing assertion in memory pool allocator in large QML scenes
In the previous implementation MemoryPool wasn't able to allocate more
memory than predefined block size (8 kB). Now, if a user tries to
allocate more memory than default block size, the block size will be
increased for current block only. All remain space in a new block will
be used according to the current allocation strategy.
Increasing block size of some certain blocks doesn't lead to
reallocation of the entire memory pool. Also this situation happens very
rarely, e.g., when compiling something contains more than approx. 2500
objects.
Also fixed some warnings and used more casts in C++ style.
Fixes: QTBUG-71195
Change-Id: I65d57959849f282178cffc92285a6a32f6bb9b25
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'src/qml/parser/qqmljsmemorypool_p.h')
-rw-r--r-- | src/qml/parser/qqmljsmemorypool_p.h | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/src/qml/parser/qqmljsmemorypool_p.h b/src/qml/parser/qqmljsmemorypool_p.h index 9a480f1224..afd0f809da 100644 --- a/src/qml/parser/qqmljsmemorypool_p.h +++ b/src/qml/parser/qqmljsmemorypool_p.h @@ -88,7 +88,7 @@ public: 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; @@ -113,7 +113,9 @@ public: 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,7 +123,7 @@ 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) @@ -131,12 +133,12 @@ private: 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; @@ -153,7 +155,7 @@ private: enum { - BLOCK_SIZE = 8 * 1024, + DEFAULT_BLOCK_SIZE = 8 * 1024, DEFAULT_BLOCK_COUNT = 8 }; }; |