| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
With the QV4::Moth::BytecodeGenerator::Jump type we are relying on the
compiler doing a return value optimization. That however is not required
by the C++11 standard and the GHS compiler does indeed not do that here,
resulting in a ~Jump destructor call in the following sequence _before_
link() is called:
Jump generateJump() { ...; return Jump(...); }
...
generateJump().link();
The destructor however verifies that link() was called, which fails.
Fix this by making Jump a move-only type, which the compiler will issue
if it doesn't perform a return value optimization.
Task-number: QTBUG-66917
Change-Id: I97cc9a5d7f97d61e573ad8bc309cf48ab18eb25d
Reviewed-by: Kimmo Ollila <kimmo.ollila@qt.io>
Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When an alias points to a child object which has not yet been
initialized, it's id won't have been registered yet, so setting up a
binding to it will result in a crash.
The fix is: when setting a binding target fails, and its target property
is an alias, queue them until all bindings have been set up, and try
again.
Task-number: QTBUG-57041
Change-Id: I4dc5a6d25c0a32fed9fd952c955e2006c76be45a
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Given two simple bindings in this order
property int firstVar: secondVar
property int secondVar: ...
then the binding expression for "secondVar" ends up being evaluated
twice at run-time. The first time happens when enabling the binding
expression for "firstVar", which results in the engine detecting that
there is a dependency onto another binding that has not been enabled
yet. This is when QQmlData::flushPendingBinding(Impl) enables the
expression for secondVar and does an initial evaluation. Afterwards the
QQmlObjectCreator continues enabling the next binding in ::finalize(),
which will end up evaluating secondVar a second time, unnecessarily.
We can detect this case inside setEnabled and only call update() if we
transition from disabled to enabled state. This should also cover the
case of bindings created and assigned dynamically through QtQuick
PropertyChanges / States, as those call setEnabled(false) before
removing the binding (to replace it with something else) and
setEnabled(true) when reverting the state (in
QQmlPropertyPrivate::setBinding).
Change-Id: I447432891eabff2c4393f5abfee1092992746fa0
Task-number: QTBUG-66945
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
|
|
|
|
|
|
|
| |
This lead to quite a few valgrind warnings in test cases.
Change-Id: Icef0fc5f93a68e4fe67e1ecd4755b456ad4778a9
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We shouldn't allocate objects that are larger than the size of
a standard memory segment through the chunk allocator, as this
can lead to problems when freeing the segment and then re-using
it again.
Instead allocate a private MemorySegment for these objects, and
free it when the object gets garbage collected.
Task-number: QTBUG-66732
Change-Id: Ic24ff65d204977f313ab0adaf7a8132883e525f0
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
QQmlData is shared between engines, but the relevant QObjectWrapper is
not.
Since 749a7212e903d8e8c6f256edb1836b9449cc7fe1 when a QObjectWrapper is
deleted it resets the shared QQmlData propertyCache.
ab5d4c78224c9ec79165e8890e5f8b8e838e0709 fixed this situation for
bindings, however we would still hit effectively the same crash in the
same situation if a function is evaluated before a binding.
Change-Id: I20cd91cd8e31fd0176d542822c67e81a790599ba
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When declaring bindings within a group property and that group property
itself is a locally declared alias, then by the time we try to determine
property caches for the group property we will fail as the aliases
haven't been resolved yet.
To fix this we can keep track of such group property declarations
(encapsulated in the QQmlInstantiatingBindingContext that has all we
need) and after we've resolved the aliases (added them to the property
caches), we can go back and fill in the entries in the propertyCaches
array for the group properties.
Task-number: QTBUG-51043
Change-Id: I5613513db3977934bcc51a3df530de47d57326f9
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
Reviewed-by: Michael Brasser <michael.brasser@live.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
If we're run from a top-level evaluate() call from the JS engine, then
let's assume that any created components are top-level components that
belong to the root QML engine context. This is not quite a typical
use-case, but our API allows for this and this seems like an easy and
sensible solution.
Task-number: QTBUG-66792
Change-Id: Ic1c9171c257e8e60c0b2c43f9194bd038744ed2d
Reviewed-by: Oleg Yadrov <oleg.yadrov@qt.io>
Reviewed-by: Michael Brasser <michael.brasser@live.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When initializing a QQmlProperty with the following syntax:
QQmlProperty property(root, "testType.objectName", QQmlEngine::contextForObject(root));
only try to look up types (for each token after splitting on the '.')
if the token starts with an uppercase letter, as 1e350a8c now enforces
that type names begin with an uppercase letter.
Task-number: QTBUG-66715
Change-Id: Iab64be1deb971dca256fc65d358c773837222a57
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|
|
|
|
| |
Change-Id: I55adc9c261529ee4b88fbb5591b3955e396437a8
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|
|
|
|
|
|
|
| |
qtdeclarative/src/qml/qml/ftw/qpodvector_p.h:119:22: error: ‘void* memmove(void*, const void*, size_t)’ writing to an object of non-trivially copyable type ‘class QQuickBasePositioner::PositionedItem’; use copy-assignment or copy-initialization instead [-Werror=class-memaccess]
::memmove(m_data + idx, m_data + idx + count,
Change-Id: I049703a0a6bb4432dfd3d3ce3c8cef13e9c2e31a
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|
|
|
|
|
|
|
|
|
|
| |
qpodvector_p.h:90:34: error: ‘void* realloc(void*, size_t)’ moving an object of non-trivially copyable type ‘class QQuickBasePositioner::PositionedItem’; use ‘new’ and ‘delete’ instead [-Werror=class-memaccess]
m_data = (T *)realloc(m_data, m_capacity * sizeof(T));
qpodvector_p.h:94:22: error: ‘void* memmove(void*, const void*, size_t)’ writing to an object of non-trivially copyable type ‘class QQuickBasePositioner::PositionedItem’; use copy-assignment or copy-initialization instead [-Werror=class-memaccess]
::memmove(m_data + idx + 1, m_data + idx, moveCount * sizeof(T));
Change-Id: I37088986a0f8613152a355ed6f3f9572316fa607
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|
|
|
|
|
|
|
| |
qtdeclarative/src/qml/jsruntime/qv4string.cpp:224:76: error: ‘void* memcpy(void*, const void*, size_t)’ copying an object of non-trivial type ‘class QChar’ from an array of ‘short unsigned int’ [-Werror=class-memaccess]
memcpy(ch, item->text->data(), item->text->size * sizeof(QChar));
Change-Id: Ibbb91fb017fe3cc382e4a4641f899c8ea4ef989a
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|
|
|
|
|
|
|
| |
qtdeclarative/src/qml/jsruntime/qv4engine.cpp:913:78: error: ‘void* memcpy(void*, const void*, size_t)’ writing to an object of type ‘struct QV4::Property’ with no trivial copy-assignment [-Werror=class-memaccess]
memcpy(argumentsAccessors, oldAccessors, oldSize*sizeof(Property));
Change-Id: I6e3d6a1a26fda33aa47c315a183edba9dcd0c0b9
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|
|
|
|
|
|
|
| |
qtdeclarative/src/qml/parser/qqmljsparser.cpp:82:129: error: ‘void* realloc(void*, size_t)’ moving an object of non-trivially copyable type ‘class QStringRef’; use ‘new’ and ‘delete’ instead [-Werror=class-memaccess]
string_stack = reinterpret_cast<QStringRef*> (realloc(string_stack, stack_size * sizeof(QStringRef)));
Change-Id: I670b8a860bf3dc9c20126306f7848f38acd75ca9
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|
|
|
|
|
|
|
|
| |
These will include Debug interpreter instructions, which wreck havoc
when no debugger is attached.
Task-number: QTBUG-66593
Change-Id: I0692207e51df6d52d0616f37a06ade76b6b2d54a
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|
|
|
|
| |
Change-Id: If9e28d143f8cba3df3c757476b4f2265e2eb8b2a
Reviewed-by: Johan Helsing <johan.helsing@qt.io>
|
|
|
|
|
|
|
|
|
| |
The helper function added in commit
2659c308792967322564b5088e0e21bb371e0283 is not needed - it was added by
accident.
Change-Id: I29c3cd31f726a46a24a056b27173e96a112eb8a6
Reviewed-by: Michael Brasser <michael.brasser@live.com>
|
|
|
|
|
|
|
|
| |
clang-tidy -p compile_commands.json $file -checks='-*,modernize-use-default-member-init,readability-redundant-member-init'
-config='{CheckOptions: [{key: modernize-use-default-member-init.UseAssignment, value: "1"}]}' -header-filter='qtdeclarative' -fix
Change-Id: I705f3235ff129ba68b0d8dad54a083e29fcead5f
Reviewed-by: Johan Helsing <johan.helsing@qt.io>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
From now on we prefer nullptr instead of 0 to clarify cases where
we are assigning or testing a pointer rather than a numeric zero.
Also, replaced cases where 0 was passed as Qt::KeyboardModifiers
with Qt::NoModifier (clang-tidy replaced them with nullptr, which
waas wrong, so it was just as well to make the tests more readable
rather than to revert those lines).
Change-Id: I4735d35e4d9f42db5216862ce091429eadc6e65d
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|
|
|
|
|
|
|
|
| |
This update corrects many qdoc warnings, mostly of the "Can't link to..."
variety, but there were also a few qdoc comments added. As of this update,
the qdoc warning count is 46 in QtDeclarative.
Change-Id: Icf2d34c7ce7010ebfd9b474feacfe8af42f3fd5f
Reviewed-by: Martin Smith <martin.smith@qt.io>
|
|
|
|
|
|
|
|
|
|
|
| |
While it is valid to assign an id to group properties that are QObjects,
it is not possible to support this with group properties that are value
types, as we do not have QObject instances and id references are limited
to those.
Change-Id: I7601d0fe00d1261dd711e34f45550db797773f9a
Task-number: QTBUG-51525
Reviewed-by: Michael Brasser <michael.brasser@live.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This is a regression introduced with commit
4876ea6a18ccdfd72014582aa5d50ab9f6b6ec9e. Where we previously always
returned the same JS object, we would afterwards return a new JS object
for every invocation, which breaks reference comparison. As we store the
JS wrapper for the list element in the QQmlData->jsWrapper we can avoid
repeated allocations. In order for that wrapper to keep working after
modifications (insertion, etc.) to the list model, we have to replace
the static element index with a reference to the node model meta-object,
which also has an element index that however is kept up-to-date by the
list model itself.
Change-Id: I4368de6b6d86687fe96fbf73bd60b80b69d7b058
Task-number: QTBUG-52017
Reviewed-by: Michael Brasser <michael.brasser@live.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Assigning to a group property inside a property value source or
interceptor as part of an "on assignment" is perfectly valid. That is
because while "color" is a value type property, the on assignment means
we're actually setting easing.type (in the example and test) on the
property value source, not the color, and that one is a QObject. The
same goes for interceptors.
Change-Id: I505a658977a578894d6dfb00bf5c65b41e42b12f
Task-number: QTBUG-56600
Reviewed-by: Michael Brasser <michael.brasser@live.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When the code generation capability is not set, the first call of
canAllocateExecutableMemory will cause a warning about suboptimal
performance. The qWarning code checks, which thread caused the message
and QThread::current sets QCoreApplicationPrivate;s theMainThread when
it is called for the first time on Windows.
If we call that function inside a static initializer, it will be called
before QCoreApplication is created and thus set the main thread to the
one that called the function. This will cause a warning about QApplication
not being created inside the main() thread, but more importantly,
delivering of events will not work in WinRT applications afterwards.
Task-number: QTBUG-66418
Change-Id: I3b6bf804983644b5ae5fe2288a587dc95fab2c8b
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
|
|
|
|
|
|
|
|
|
|
|
|
| |
If it's in the command-line, it is added to the precompiled header,
which won't be regenerated if the macro changed. Instead, let's create a
header that can be #included only in the file it needs to.
Since qmldevtools compiles the file that has this new #include, we need
to ensure it was created before the module is compiled.
Change-Id: I940917d6763842499b18fffd1513b9c64cd98387
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|
|
|
|
|
|
| |
qv4bytecodegenerator.cpp:99:19: error: ‘instructionsAsInts[3]’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
Change-Id: I940917d6763842499b18fffd1513ff143fc502bb
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When a function is called that is in a QML scope or a QML context, set
the 'this' object to the QML scope. This is done by introducing two new
interpreter instructions, which get the context passed in.
Note: this patch is 5.11 specific. 5.9 had a similair issue, but the
implementation is quite different, so that was fixed separately.
Task-number: QTBUG-66432
Change-Id: Ie43150cdd26360025895df28d31264985abf1c15
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|
|
|
|
|
|
|
|
|
| |
We don't want the JIT to ignore the debug instructions, and in
qsgatlastexture.cpp qqmlglobal_p.h which defines
DEFINE_BOOL_CONFIG_OPTION was implicitly included via qml_debug.
Change-Id: I82329b9422f4938f097263517afadebab33a0d0c
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Reviewed-by: Nodir Temirkhodjaev <nodir.temir@gmail.com>
|
|\
| |
| |
| |
| |
| |
| |
| | |
Conflicts:
.qmake.conf
tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp
Change-Id: I7feb9772fc35066f56b7c073482b53ca8c86c70b
|
| |
| |
| |
| |
| |
| |
| |
| |
| | |
This reverts commit 823428d994b0ec0f6b85288d74554660a51b2406. No more
needed after qt3d commit 78f77f80057b1e77c3f47d52de3e0b3f0c5d8d6e that
took the new API into use.
Change-Id: I4acb707cf363a625ae8e90c4560a0d5140cc4011
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Strictly speaking this is a regression introduced with commit
e22b624d9ab1f36021adb9cdbfa9b37054282bb8, making the QQmlContextData
objects reference counted, especially from the V4 QML context wrapper
objects.
That change (correct as it is) introduced an accidental circular
dependency in the simple scenario of importing a .js file in a .qml
file:
Each time the type in the .qml file is instantiated, we create a
dedicated QQmlContextData for the .js file. If the .js file has no
imports itself, that new context will get the same ctx->importedScripts
JS array as the QML context of the .qml file. That is a strong reference
via QV4::PersistentValue. That array in turn contains the
QV4::QmlContextWrapper that belongs to the imported script, which in
turn holds a strong reference (via refcount) to the script's context.
This patch breaks the circular reference when we perform context
invalidation, as the least intrusive measure.
For the auto-test to work, we must also clear the qmlContext persistent
of the QV4::Script that's used to evaluate the .js file. In subsequent
imports that persistent will be initialized to new values, so it will
only hold a strong reference to the last import, but strictly speaking
that is still a leak - hence also part of this fix.
Change-Id: I3e543c946e5e683425072dc3df7e49ca0e0c0215
Task-number: QTBUG-66189
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
- Mention (in the detailed description) that Array is indeed supported.
- Provide examples for getting and setting individual array elements,
and how to read the length of the array.
- Properly document the property() and setProperty() overloads that
take an index.
- Link to the overloads where it makes sense.
These changes make the intended workflow for using arrays much more
obvious.
Change-Id: I4657a7b1e2b4c2977120ee8e345ee9ae7d2bbc2d
Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
CONSTANT properties are by nature non-NOTIFYable.
The issue behind the regression is caused by the fact that we were
capturing a property regardless of whether or not it was const.
There were two states that captureRequired was expressing:
true: We're reading the property of a QObject, and we're not quite sure
where the QObject comes from or what it is. So, when reading that
property at run-time, make sure that we capture where we read that
property so that if it changes we can re-evaluate the entire
expression.
false: We're reading the property of a QObject, and we know that it's
the scope object or context object, which we know very well. Instead of
registering a property capture every time, we can do that ahead of time
and then register all those captures in one shot in
registerQmlDependencies().
There is a third state that is only relevant when captureRequired is
false: We're reading a property from the scope or context object, but
it's a CONSTANT property, so we don't need to register a dependency
at all.
This patch adds replaces captureRequired with the PropertyCapturePolicy
enum, which accounts for the third state and, as a bonus, makes the
code easier to understand.
Task-number: QTBUG-66361
Change-Id: I6cef1deb76538fbdacf1324b4467403dd40dd7de
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
| |
| |
| |
| |
| | |
Change-Id: I940917d6763842499b18fffd1513b8c1308ce873
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
|\ \
| | |
| | |
| | | |
refs/staging/5.11
|
| |\ \
| | | |
| | | |
| | | | |
refs/staging/5.11
|
| | |\ \
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
Conflicts:
src/imports/shapes/qquickshape.cpp
src/imports/shapes/qquickshape_p_p.h
src/qml/compiler/qqmlpropertycachecreator_p.h
src/qml/jsruntime/qv4value_p.h
src/quick/items/qquickloader_p.h
tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
tools/qmlprofiler/qmlprofilerapplication.cpp
Change-Id: Iafc66ae84bf78630ed72a986acb678e9d19e3a69
|
| | | |\|
| | | | |
| | | | |
| | | | | |
Change-Id: I3b250545e334f50dcef1a75acdef51820d34079a
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
This is a regression introduced with commit
3b6eeee177b64eebe240d51be0c7bb5f031471d8 in the 5.9 branch. When
constructing an object with deferred properties and not running
qmlExecuteDeferred, then the deferred data would never get deleted
because the bindings list remains non-empty and we would leak the
deferred data as well as the entire compilation unit behind it.
This happens for example when declaring when instantiating a QML file
with states:
states: [ State { ... }, State { ... }, ... }
Unless every state is entered, its deferred changes property is never
applied (via qmlExecuteDeferred) and thus the defer data is leaked.
Task-number: QTBUG-66189
Change-Id: I1b2119c601d1e0ab4e37f53d4cf2f569586ee883
Reviewed-by: J-P Nurmi <jpnurmi@qt.io>
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
Replace manual use in QQmlData and QQmlData::DeferredData with
QQmlRefPointer.
Due to forward declaration trouble this required declaring a non-inline
constructor/destructor for QQmlData and DeferedData and disabling
copying, so that not every C++ compilation unit including qqmldata_p.h
needs to instantiate the QQmlRefPointer destructor and thus know whether
QV4::CompiledData::CompilationUnit has release(), etc. The out-of-line
declarations however should not have any negative impact as the only
call sites are within qqmlengine.cpp, too.
Change-Id: I2e8295cb0d7f876a5d7d18765dbac285184e6c99
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
This approach tracks object allocations only,
when slots from already allocated memory segment are used.
Change-Id: I514b974d7580c1236264bec96dc1abe594585e86
Reviewed-by: Milian Wolff <milian.wolff@kdab.com>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
Task-number: QTBUG-62007
Change-Id: I63d5a57163b36bc8629930e1cda8d5afa1e77d15
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
The idea of NaN boxing is to use one single NaN as a "true" NaN, and all
others as a boxed value. So when encoding some NaN, be sure to use that
one "true" NaN. Otherwise, it will be interpreted as an encoded value.
Task-number: QTBUG-65998
Change-Id: Ia6e4641be180f3d626c40a57b473f181358e04db
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
|
| | | |\|
| | | | |
| | | | |
| | | | | |
Change-Id: I41ca9120a470a905c2f5c168c1de4cf970fa0fff
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
Change-Id: I444137fd10041781df232447b8e2bf712582f079
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
When for the QQC code path we do QML type re-compilation, we allocate a
new QV4::CompiledData::Unit. We must make sure that this dynamically
allocated memory is released in QV4::CompiledData::CompilationUnit's
destructor, by ensuring that the StaticData flag is not set.
This isn't directly applicable to the ahead-of-time generated cache file
unit data as they will always be re-generated (and thus the unsetting of
StaticData at the end of createCompilationUnit::createUnitData()), but
I've added a test-case nevertheless to ensure the correct engine
behavior.
Change-Id: I16973d7989567892bf8bf9dd6214bf293055d260
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
Commit 3b14e2ffdd8eb4b7f7f4508768b75f2acc399370 replaced the
QQmlRefPointer<QQmlPropertyCache> with a raw QQmlPropertyCache pointer
and added a V4_NEEDS_DESTROY tag. However unfortunately the destroy()
method in the heap class does not decrease the reference count.
Change-Id: I90a8c56cd638592b67aae7041fbb57c879c4146c
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
When importing modules - in the QML loader thread - with plugins we keep
globally track of the Qt plugins that we have loaded that contain QML
modules, to ensure that we don't call the engine-independent
registerTypes() function on the plugin multiple times. After
registerTypes() we may also call initializeEngine() on the plugin for
the engine-specific initialization, which - as a QQmlEngine is provided
as parameter - must happen in the gui thread. For that we issue a
thread-blocking call that waits until the gui thread has woken up and
processed the event/call.
During that time the global plugin lock is held by that QML loader
thread.
If meanwhile the gui thread instantiates a second QQmlEngine and
attempts to issue a synchronous type compilation (using
QQmlComponent::CompilationMode::PreferSynchronous), then gui thread is
blocking and waiting for its own QML loader thread to complete the type
compilation, which may involve processing an import that requires
loading a plugin. Now this second QML loader thread is blocked by trying
to acquire the global plugin registry lock
(qmlEnginePluginsWithRegisteredTypes()->mutex) in qqmlimports.cpp.
Now the first QML loader thread is blocked because the gui thread is not
processing the call events for the first engine. The gui thread is
blocked waiting for the second QML loader thread, which in turn is stuck
trying to acquire the lock held by the first QML loader thread.
The provided test case triggers this scenario, although through a
slightly different way. It's not possible to wait in the gui thread for
the plugin lock to be held in a loader thread via the registerTypes
callback, as that also acquires the QQmlMetaType lock that will
interfere with the test-case. However the same plugin lock issue appears
when the first QML engine is located in a different thread altogether.
In that case the dispatch to the engine thread /works/, but it won't be
the gui thread but instead the secondary helper thread of the test case
that will sit in our initializeEngine() callback.
This bug was spotted in production customer code with backtraces
pointing into the three locations described above: One QML loader thread
blocking on a call to the gui thread, the gui thread blocking on a
second QML loader thread and that one blocking on acquisition of the
plugin lock held by the first.
Fortunately it is not necessary to hold on to the global plugin lock
when doing the engine specific initialization. That allows the second
QML loader thread to complete its work and finally resume the GUI
thread's event loop.
Change-Id: If757b3fc9b473f42b266427e55d7a1572b937515
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
When the persistent storage becomes fragmented, we would find the page
with a hole in it, but we wouldn't put it to the front of the page
list. So upon the next allocation we would begin iterating through
firstPage again.
This wasn't quite visible in callgrind as overall not many instructions
were executed, but in perf this function showed up as hotspot because
the search for free pages ends up with a lot of cache misses.
In delegates_item_states.qml this was about ~7% of measured cycles with
perf.
Change-Id: I2bfa337ea9be14d1321756963c72d31336790a0a
Done-with: Erik
Task-number: QTBUG-65708
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
|