diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2019-04-23 09:33:25 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2019-04-23 09:34:29 +0200 |
commit | 580fa7dc88aae23053e44ffa335a15f6af112a20 (patch) | |
tree | 5bc915d7c2e252739122d9441bd0d7fa7175d0c2 /src/qml/memory/qv4mm_p.h | |
parent | 6767114285db9d0e16dc278d08f231e8561546b4 (diff) | |
parent | c00283bb3bb966bf60c307ec8283bd98c12318bf (diff) |
Merge remote-tracking branch 'origin/dev' into wip/scenegraphng
Change-Id: Ifec879473540b609403ac951967f6d9ecb0bb6f0
Diffstat (limited to 'src/qml/memory/qv4mm_p.h')
-rw-r--r-- | src/qml/memory/qv4mm_p.h | 44 |
1 files changed, 42 insertions, 2 deletions
diff --git a/src/qml/memory/qv4mm_p.h b/src/qml/memory/qv4mm_p.h index bbbbb1aef6..6dfdd81cb2 100644 --- a/src/qml/memory/qv4mm_p.h +++ b/src/qml/memory/qv4mm_p.h @@ -264,13 +264,13 @@ public: size_t getLargeItemsMem() const; // called when a JS object grows itself. Specifically: Heap::String::append + // and InternalClassDataPrivate<PropertyAttributes>. void changeUnmanagedHeapSizeUsage(qptrdiff delta) { unmanagedHeapSize += delta; } template<typename ManagedType> typename ManagedType::Data *allocIC() { - size_t size = align(sizeof(typename ManagedType::Data)); - Heap::Base *b = *icAllocator.allocate(size, true); + Heap::Base *b = *allocate(&icAllocator, align(sizeof(typename ManagedType::Data))); return static_cast<typename ManagedType::Data *>(b); } @@ -284,12 +284,52 @@ protected: Heap::Object *allocObjectWithMemberData(const QV4::VTable *vtable, uint nMembers); private: + enum { + MinUnmanagedHeapSizeGCLimit = 128 * 1024 + }; + void collectFromJSStack(MarkStack *markStack) const; void mark(); void sweep(bool lastSweep = false, ClassDestroyStatsCallback classCountPtr = nullptr); bool shouldRunGC() const; void collectRoots(MarkStack *markStack); + HeapItem *allocate(BlockAllocator *allocator, std::size_t size) + { + bool didGCRun = false; + if (aggressiveGC) { + runGC(); + didGCRun = true; + } + + if (unmanagedHeapSize > unmanagedHeapSizeGCLimit) { + if (!didGCRun) + runGC(); + + if (3*unmanagedHeapSizeGCLimit <= 4 * unmanagedHeapSize) { + // more than 75% full, raise limit + unmanagedHeapSizeGCLimit = std::max(unmanagedHeapSizeGCLimit, + unmanagedHeapSize) * 2; + } else if (unmanagedHeapSize * 4 <= unmanagedHeapSizeGCLimit) { + // less than 25% full, lower limit + unmanagedHeapSizeGCLimit = qMax(std::size_t(MinUnmanagedHeapSizeGCLimit), + unmanagedHeapSizeGCLimit/2); + } + didGCRun = true; + } + + if (size > Chunk::DataSize) + return hugeItemAllocator.allocate(size); + + if (HeapItem *m = allocator->allocate(size)) + return m; + + if (!didGCRun && shouldRunGC()) + runGC(); + + return allocator->allocate(size, true); + } + public: QV4::ExecutionEngine *engine; ChunkAllocator *chunkAllocator; |