From d8110b53ed9ee4d69b92e602e812c6311c1b863b Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Wed, 20 Mar 2019 17:15:29 +0100 Subject: Trigger the garbage collector when allocating InternalClass objects As we check the icAllocator's slots on shouldRunGC() we should also check shouldRunGC() when adding slots. Otherwise we might never run the GC when only allocating InternalClasses. In addition, account for the "unmanaged" size of the PropertyAttributes that are part of the InternalClass objects. Those can be large. In cases where an excessive number of large InternalClass objects is created the garbage collector is now invoked frequently, which costs a significant number of CPU cycles, but prevents the memory usage from growing indefinitely. Task-number: QTBUG-58559 Change-Id: Icf102cb6100f6dba212b8bffe1c178897880eda0 Reviewed-by: Lars Knoll --- src/qml/jsruntime/qv4internalclass.cpp | 56 ++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) (limited to 'src/qml/jsruntime/qv4internalclass.cpp') diff --git a/src/qml/jsruntime/qv4internalclass.cpp b/src/qml/jsruntime/qv4internalclass.cpp index 9906e2b1a0..8e2657f4a5 100644 --- a/src/qml/jsruntime/qv4internalclass.cpp +++ b/src/qml/jsruntime/qv4internalclass.cpp @@ -44,6 +44,7 @@ #include "qv4object_p.h" #include "qv4identifiertable_p.h" #include "qv4value_p.h" +#include "qv4mm_p.h" QT_BEGIN_NAMESPACE @@ -204,7 +205,62 @@ void SharedInternalClassDataPrivate::mark(MarkStack *s) data->mark(s); } +SharedInternalClassDataPrivate::SharedInternalClassDataPrivate( + const SharedInternalClassDataPrivate &other, uint pos, + PropertyAttributes value) + : refcount(1), + m_alloc(pos + 8), + m_size(pos + 1), + m_engine(other.m_engine) +{ + m_engine->memoryManager->changeUnmanagedHeapSizeUsage(m_alloc * sizeof(PropertyAttributes)); + data = new PropertyAttributes[m_alloc]; + if (other.data) + memcpy(data, other.data, (m_size - 1) * sizeof(PropertyAttributes)); + data[pos] = value; +} + +SharedInternalClassDataPrivate::SharedInternalClassDataPrivate( + const SharedInternalClassDataPrivate &other) + : refcount(1), + m_alloc(other.m_alloc), + m_size(other.m_size), + m_engine(other.m_engine) +{ + if (m_alloc) { + m_engine->memoryManager->changeUnmanagedHeapSizeUsage(m_alloc * sizeof(PropertyAttributes)); + data = new PropertyAttributes[m_alloc]; + memcpy(data, other.data, m_size*sizeof(PropertyAttributes)); + } else { + data = nullptr; + } +} +SharedInternalClassDataPrivate::~SharedInternalClassDataPrivate() +{ + m_engine->memoryManager->changeUnmanagedHeapSizeUsage( + -qptrdiff(m_alloc * sizeof(PropertyAttributes))); + delete [] data; +} + +void SharedInternalClassDataPrivate::grow() { + if (!m_alloc) { + m_alloc = 4; + m_engine->memoryManager->changeUnmanagedHeapSizeUsage( + 2 * m_alloc * sizeof(PropertyAttributes)); + } else { + m_engine->memoryManager->changeUnmanagedHeapSizeUsage( + m_alloc * sizeof(PropertyAttributes)); + } + + auto *n = new PropertyAttributes[m_alloc * 2]; + if (data) { + memcpy(n, data, m_alloc*sizeof(PropertyAttributes)); + delete [] data; + } + data = n; + m_alloc *= 2; +} namespace Heap { -- cgit v1.2.3