aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/parser/qqmljsmemorypool_p.h
diff options
context:
space:
mode:
authorVitaly Fanaskov <vitaly.fanaskov@qt.io>2018-11-27 15:09:11 +0100
committerVitaly Fanaskov <vitaly.fanaskov@qt.io>2018-11-28 14:54:36 +0000
commit0e87966c8f815269b770a0a31974e0cd5b8ab26e (patch)
tree0a9a5eee7d4b7a0086000295e60d0c3ca9db42cd /src/qml/parser/qqmljsmemorypool_p.h
parente1a0e894aa09dd1323a7792192f1d68ee6677f8a (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.h14
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
};
};