Some slots still have free memory available. If we only
need to allocate a small object, check if we can split up
one of these slots before giving up and starting a GC
cycle.
Change-Id: I11fb9d53c607274dbb5fd0bc02088ed94bfe7c4e
Reviewed-by: Robin Burchell <robin.burchell@crimson.no>
The bug lead to us not sorting all freed memory into
the bins for the allocator to find. The lead to memory
being 'lost' in the garbage collector.
Add an assertion that checks for lost memory when
we're running with aggressive GC.
Also make sure we don't run GC twice in a row when
aggressive GC is enabled.
Change-Id: I4fb6732acce8a2e66258fa70fb7d8f1f939cfd9f
Reviewed-by: Robin Burchell <robin.burchell@crimson.no>
Instead allocate a MemberData at the same time as the
object if required. Turns out this is faster now,
and significantly simplifies some of our internal logic
to access member properties.
In addition, we can properly setup the inline member size
to use the full extent of the memory reserved by the
memory manager. This avoid some needless reallocations of
MemberData objects.
Change-Id: I36daeeaf6df16f2268103662fc78d600b4058ef8
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
There's no point in having the memset inline. In theory, the
compiler could optimize by combining this with later on inline
initialization code, in practice this doesn't happen anyway,
and we have some options of avoiding or combing the memsets
in the allocator.
Change-Id: I4502ef947ae235223726269821f9482ad62e1070
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Inline the few remaining members into the MemoryManager
class itself.
Change-Id: If5fef74581daa89df3e8cc237329c27395ce2289
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
This is a block based allocator. We allocate HeapItems
from 64k Chunks (except for huge items that get their
own chunk). The allocator is block based, and aims to
defragment when sweep'ing the blocks.
The mark bit is now stored in the Chunk header, not
inline in the object anymore.
Change-Id: I2845f8b73dd496911ba50b868d54d144501d41e4
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Use a new Chunk based allocator for very large items.
Change-Id: Ie61a72efb6340cd9ef54e4fdd957d7ca36c8729f
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
We used to allocate those on the C stack, but this doesn't work
anymore with the new GC, as the mark bit is not stored inside the
object anymore.
Instead use a special allocator for these contexts that operates like a
stack.
Change-Id: I381ac3914ca866945312a1e79883aefe72662d2c
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Cleans up the code a bit in preparation of the new GC. Has minimal
effect on performance these days.
Change-Id: Ifa6afea9acf8b6f086412e7eab7fa37c5387c624
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Let the destroy() method in QV4::String clean up the
unmanaged heap size instead of having a special hook in
the code that sweeps the GC heap.
Change-Id: I989ee99604f0cc67b896d3acc94e200dd5e56a60
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
It's a hack we needed when we still had a conservative GC, but
it is not required anymore. The only thing we still need is the
protection against running the GC recursively.
Change-Id: I55cd51d4929c828db5b61b38e781467c5bf77314
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
These two were mixed, but have completely different values.
Task-number: QTBUG-56471
Change-Id: Ifbf6da3032335ea89bfbc3acde17f64a571b9dc0
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
This allows for a compiler to do dead-store elimination for zero-
initialized memory that gets overwritten directly after the allocated
chunk is returned.
Change-Id: I6493aae8fdabc2306e7cfa1233f917b1775c4451
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Check that the destroy() method of Heap::Base was called when a Managed
object needs destruction. This checks if a call to the parent's
destroy() method was accidentally omitted.
Change-Id: Id025ecd6d4744bf3eab23503fbe317ed2a461138
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Getting the current time from QTime is expensive as it adheres
to the locale timezone. To measure elapsed time in a code block,
using the monotonic QElapsedTimer is much faster.
Change-Id: Ibea390d7bc5270a20cf35111dfc919e37be7001e
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
A call to a handler of Component.onDestruction may end up causing WeakValues
such as QQmlData::jsWrapper to be set again, even though they've been set to
undefined in an earlier iteration of the loop that walks through the weak
references. That in turn may result in invalid object references to objects
that are scheduled for destruction by the collector.
So after calling all destroy handlers for QObjects, reset all of the weak
values again.
Task-number: QTBUG-54939
Change-Id: I00ebabb76274e296fb1bd90d8d3e21dbbb920b57
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
With aggressive GC enabled we may end up calling the GC recursively, which does
not work at all, so disable that.
Change-Id: I9ce0abbdb7b2bfa8499b33fd0be0d6e4a5212a15
Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
By not relying on the return value of the macros we can #define them
away later, when compiling with -no-qml-debug
Change-Id: I24d50fa3f5d8e8765a42b050c81ddfae20f20a23
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
When you build qtdeclarative with CONFIG+=heaptrack then the allocations
from the custom pool allocator can be traced with heaptrack. This works
similar to the existing valgrind support.
Change-Id: Ia988380415083aa1346c84c8c64b49ea3e17b7e2
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
This commit adds a small test that exercises a number of code paths
inside qv4mm.cpp which are normally gated via environment variables.
Change-Id: Ibe959387a9b86ce68df258513446d2165fe06ee2
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
All those type conversions assumed that the content of a Value was
either the requested type, or 0 (zero, a null pointer). Now, attempting
to convert e.g. undefined to a string will fail, instead of returning a
weird address.
Change-Id: I0f567cdcc9cc9728d019f17693f4a6007394a9c6
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Change-Id: I7cf6c5d3458b0c43283e63a7300ee9965ba803fb
Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
Reviewed-by: Frank Meerkoetter <frank.meerkoetter@basyskom.com>
Delay freeing QObjectWrapper Value to MemoryManager::sweep() to make sure
we can destroy all QObjectWrapper objects.
We also keep track of QObjectWrapper in QV4::Heap::ModelObject to make
sure we destory them in QV4::MemoryManager::sweep()
Change-Id: I3a8a3b07faab1f88c2eb746f68aa8d9584b40026
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
From Qt 5.7 -> LGPL v2.1 isn't an option anymore, see
http://blog.qt.io/blog/2016/01/13/new-agreement-with-the-kde-free-qt-foundation/
Updated license headers to use new LGPL header instead of LGPL21 one
(in those files which will be under LGPL v3)
Change-Id: Ic36f1a0a1436fe6ac6eeca8c2375a79857e9cb12
Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
This reverts commit 839d2d3e23, which has
been causing crashes in qtquickcontrols2 auto tests and making it nearly
impossible to integrate anything over the past few days.
Change-Id: I570b286a067aae5e3c2d8c56ad601e1a6cb58c20
Task-number: QTBUG-50134
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
Call destroyObject() for every QV4::Heap::QObectWrapper object in heap in
QV4::MemoryManager::sweep() to make sure the QPointer object contained in
QV4::Heap::QObjectWrapper is properly destructed.
We also keep track of QObjectWrapper in QV4::Heap::ModelObject to make
sure we destory them in QV4::MemoryManager::sweep()
Change-Id: I3b3e96cfc300c2e21ab691762879ac2970afa90c
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
Where possible, use qEnvironmentVariableIsSet()/
qEnvironmentVariableIsEmpty() instead of checking on the
return value of qgetenv().
Where the value is required, add a check using one of
qEnvironmentVariableIsSet()/Empty().
Change-Id: Ia8b7534e6f5165bd8a6b4e63ccc139c42dd03056
Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
The old algorithm could lead to excessive garbage collection
in cases where lots of strings are being created.
The new algorithm is a bit more agressive in doubling the GC limit
for string data. This doubles the performance of both the v8 regexp
and splay benchmarks.
Change-Id: I2b5cd27c14410b033038a409d5ae03c9636d4f71
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
The output of QV4_MM_STATS was only reporting the items allocated on the
JS HEAP. It was missing out on the LargeItems which are allocated on
the C++ heap.
Change-Id: Ife3d7afd769beb31afd1ed681d503f9811b03b96
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
Now that the other method is gone, let's use
the shorter currentContext
Change-Id: I2a6fb3b77f83a1ffdf314ad29081e303d17030ed
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
This saves one pointer per allocated execution context.
Now every execution context that is pushed, allocates two
Values on the js stack. One contains the context itself, the
other one the offset to the parent context.
Things are a bit tricky for with and catch scopes, as those
are called from the generated code, and can't open a Scope
anymore. In addition, all methods iterating over the js
stack frames need to work with ExecutionContext pointers,
not ScopedContext's.
Change-Id: I6f3013749d4e73d2fac37973b976ba6029686b82
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
Always operate on the current context (as that's what we do
in practice anyway).
Change-Id: I4171207a7a86e69aa685754956c0764ac6e152a7
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
When called, the function would return a full-fledged QObject that maps the
list element addressed. It would contain a _copy_ of all values in the list
item and it would create a new meta-object for each list element.
This function exists for the JavaScript API, and therefore we now return a much
more lightweight object. For compatbility reasons it still has to be a QObject,
but the meta-object of it is created on-demand, i.e. only when accessing
properties from the C++ side or when connecting to the changed signal of a
property. Otherwise the JavaScript wrapper will return the live values from the
model without copying them.
Change-Id: Iabf3ca22192d2aee06ae9d4b4cfb2fcde2a021b1
Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
Reviewed-by: Michael Brasser <michael.brasser@live.com>
Reviewed-by: Spencer Schumann <spencer.schumann@echostar.com>
Conflicts:
src/qml/debugger/qv4debugservice.cpp
src/qml/jsruntime/qv4value_inl_p.h
src/qml/jsruntime/qv4value_p.h
src/qml/memory/qv4mm.cpp
src/qml/memory/qv4mm_p.h
src/qml/qml/qqmlnotifier_p.h
src/qml/qml/qqmlproperty.cpp
src/quick/items/qquickflickable.cpp
src/quick/items/qquicktextedit.cpp
tests/auto/quick/qquickwindow/BLACKLIST
The extra changes in qqmlbinding.cpp are ported from changes to
qqmlproperty.cpp that occurred in parallel with writeBinding() being
moved to qqmlbinding.cpp.
Change-Id: I16d1920abf448c29a01822256f52153651a56356
I don't see why the vector needs to be sorted by the base()
addresses of the contained PageAllocations.
Change-Id: I31946a50075c64d01c6de98964ea42ebfc936c68
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
The wrappers emit a destroyed signal, and it's important
that the GC heap is in a well defined state when these signals
are emitted.
Change-Id: I423c4241b1e2fd3de727277d26bbe64f08862193
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
This is required, so we can safely access the vtable even while
we're marking objects during GC.
Change-Id: I34f56b61b4bca0d0742faf607eb5ab8b2c30685e
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>