aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4internalclass.cpp
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2019-03-20 17:15:29 +0100
committerUlf Hermann <ulf.hermann@qt.io>2019-03-26 08:57:59 +0000
commitd8110b53ed9ee4d69b92e602e812c6311c1b863b (patch)
tree5f8dd40ac25a1f2dbb8a9da794e0252919cdfb58 /src/qml/jsruntime/qv4internalclass.cpp
parent156066d4753243143970aeb0b740f8f429e7916b (diff)
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 <lars.knoll@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4internalclass.cpp')
-rw-r--r--src/qml/jsruntime/qv4internalclass.cpp56
1 files changed, 56 insertions, 0 deletions
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<PropertyKey>::mark(MarkStack *s)
data->mark(s);
}
+SharedInternalClassDataPrivate<PropertyAttributes>::SharedInternalClassDataPrivate(
+ const SharedInternalClassDataPrivate<PropertyAttributes> &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<PropertyAttributes>::SharedInternalClassDataPrivate(
+ const SharedInternalClassDataPrivate<PropertyAttributes> &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<PropertyAttributes>::~SharedInternalClassDataPrivate()
+{
+ m_engine->memoryManager->changeUnmanagedHeapSizeUsage(
+ -qptrdiff(m_alloc * sizeof(PropertyAttributes)));
+ delete [] data;
+}
+
+void SharedInternalClassDataPrivate<PropertyAttributes>::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 {