From c749f37c83cbb458e25a7d5200facf8634ac959e Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Fri, 3 Jul 2015 13:20:18 +0200 Subject: V4: track C++ heap usage for Strings in the MemoryManager ... and do a GC run when it exceeds a threshold. The issue with Strings is that they hold on to QString instances that store the real content. However, the GC only sees the light-weight JS handle, and doesn't take the size of the backing content into account. So it could happen that big QStrings accumulate in the heap as long as the GC didn't reach its threshold. The newly introduced unmanaged heap threshold is upped by a factor of two when exceeded, and lowered by a factor of 2 when the used heap space falls below a quarter of the threshold. Also grow the threshold if there is enough space after running the GC, but another GC run would be triggered for the next allocation. There is a special case for Heap::String::append, because this method will copy the data from the left and right substrings into a new QString. To track this, append notifies the memory manager directly of the new length. The pointer to the memory manager is stored in Heap::String, growing it from 40 bytes to 48 bytes (which makes it still fit in the same bucket, so no extra memory is allocated). Task-number: QTBUG-42002 Change-Id: I71313915e593a9908a2b227b0bc4d768e375ee17 Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4runtime.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/qml/jsruntime/qv4runtime.cpp') diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index c31de6a9f0..b66e917b87 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -521,7 +521,8 @@ QV4::ReturnedValue RuntimeHelpers::addHelper(ExecutionEngine *engine, const Valu return pright->asReturnedValue(); if (!pright->stringValue()->d()->length()) return pleft->asReturnedValue(); - return (engine->memoryManager->alloc(pleft->stringValue()->d(), pright->stringValue()->d()))->asReturnedValue(); + MemoryManager *mm = engine->memoryManager; + return (mm->alloc(mm, pleft->stringValue()->d(), pright->stringValue()->d()))->asReturnedValue(); } double x = RuntimeHelpers::toNumber(pleft); double y = RuntimeHelpers::toNumber(pright); @@ -537,7 +538,8 @@ QV4::ReturnedValue Runtime::addString(ExecutionEngine *engine, const Value &left return right.asReturnedValue(); if (!right.stringValue()->d()->length()) return left.asReturnedValue(); - return (engine->memoryManager->alloc(left.stringValue()->d(), right.stringValue()->d()))->asReturnedValue(); + MemoryManager *mm = engine->memoryManager; + return (mm->alloc(mm, left.stringValue()->d(), right.stringValue()->d()))->asReturnedValue(); } Scope scope(engine); @@ -554,7 +556,8 @@ QV4::ReturnedValue Runtime::addString(ExecutionEngine *engine, const Value &left return pright->asReturnedValue(); if (!pright->stringValue()->d()->length()) return pleft->asReturnedValue(); - return (engine->memoryManager->alloc(pleft->stringValue()->d(), pright->stringValue()->d()))->asReturnedValue(); + MemoryManager *mm = engine->memoryManager; + return (mm->alloc(mm, pleft->stringValue()->d(), pright->stringValue()->d()))->asReturnedValue(); } void Runtime::setProperty(ExecutionEngine *engine, const Value &object, int nameIndex, const Value &value) -- cgit v1.2.3