Renamed ScopedCallData to JSCall, enforced passing a JS
FunctionObject to it, and added call() and callAsConstructor()
methods to it.
Change-Id: I30db65c9765c2896b5909fe2105c0934c6dad861
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Don't emit any Line instructions anymore, and instead store
the info in a side table in the compiled data, where it can
be looked up on demand.
Change-Id: Idcaf3bf4ee4129fd62f9e717bf1277dc6a34fe19
Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
Fix the push/pop context instructions to not modify the JS
stack anymore, as that can cause conflicts with the VME
(and was an ugly hack in any case). Instead, these instructions
not return the old context, that is then stored in a temporary.
Get rid of Engine::current and Engine::currentContext. The
StackFrame structures do now contain the only and authoritive
data. This finally gives us a nice setup where we create and
destroy frames on the stack when entering/leaving functions.
Change-Id: If161e3e941f59865c47ecfe1e094faf62b52bfa0
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Allow for faster calling of builtins, and completely avoid
scope creation in many cases.
Change-Id: I0f1681e19e9908db10def85a74e134a87fc2e44c
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Change those back again to return a value. This will be required
to avoid creation of Scope objects between JS function calls.
Change-Id: I05cb5cf8fd0c13dcefa60d213ccd5983fab57ea3
Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
Instead modify our StackFrame struct to hold the
QV4::Function and have a linked list of those for
the frames.
Change-Id: I8676e16bc51a5ba6cf25a5b3423576d44e8a926a
Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
QQmlType is now refcounted, and we need to use it by
value, to control it's lifetime properly. This is
required, so we can clean up the QQmlMetaTypeData
cache on engine destruction and with trimComponentCache()
Task-number: QTBUG-61536
Change-Id: If86391c86ea20a646ded7c9925d8f743f628fb91
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
We can easily do this now that Managed has a pointer to an
internal class (which always has a back pointer to the
ExecutionEngine).
Remove the extra engine pointer from ExecutionContext, and clean
up tow methods in String.
Change-Id: I98d750b1afbdeadf42e66ae0c92c48db1a7adc31
Reviewed-by: Robin Burchell <robin.burchell@crimson.no>
And do not store the vtable in Heap::Base anymore. This change
makes the internal class the main distinguishing feature
of all garbage collected objects.
It also saves one pointer on all Objects. No measurable
impact on runtime performance.
Change-Id: I040a28b7581b993f1886b5219e279173dfa567e8
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Add a new logging category that can be used to debug issues with
unexpected binding breakages caused by assignment to previously bound
properties. If enabled, outputs a message when a binding is broken with
detailed location and property/value information.
[ChangeLog][QtQml] The QML engine can now emit informational messages
(in the "qt.qml.binding.removal" logging category) whenever a binding is
lost due to an imperative assignment. This can be used to debug issues
due to broken bindings.
Change-Id: Ie31e5a198450b6f998c1266acfc97e8f33a92e3d
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
When searching a QObject for properties, try to find QObject properties first,
and then bail if we don't find a match and the object is not already wrapped.
It makes no sense to wrap the object just to check the (empty) JS side
props, which is often the case with QmlContextWrapper's scopeObject and
contextObject. This can especially be seen when looking at QML's model
activity, as they set a context object in order to hijack lookup of
model data & index.
This can be seen in a test like the following:
Repeater {
model: 10
delegate: Text {
text: index
}
}
Before this patch, the 'index' access would previously trigger wrapping
of the QQmlDelegateModelItem. The same applies to the 'model' prop etc.
Noteworthy improvements of a full qmlbench run that aren't part of the "usual"
statistical noise are generally around the 5% mark.
Outside performance, the advantages are also clear on memory. Examining
for instance delegates_flipable.qml with QV4_MM_STATS=1 on my MBP:
Before:
Freed JS type: QmlContext (5000 instances)
Freed JS type: QObjectWrapper (5000 instances)
Freed JS type: QmlContextWrapper (5000 instances)
Freed JS type: QQuickItemWrapper (5000 instances)
After:
Freed JS type: QmlContext (5000 instances)
Freed JS type: QmlContextWrapper (5000 instances)
Freed JS type: QQuickItemWrapper (5000 instances)
... which is what we expect, no more QObjectWrappers here, a lot less garbage
to clear up.
Timewise, while the measured mark/sweep times are not stable, there is a
proportional decrease of about 40% in time for both mark and sweep phases in
the GC (slightly more on TX1 than desktop, curiously).
Finally, GC's memory use is quite stable for each round of the test, and in this
case, we see a decrease of 378kb used at the time of each GC.
Before:
Allocated 2515968 bytes in 39 chunks
Used memory before GC: 2489824
Used memory after GC : 889856
Freed up bytes : 1599968
After:
Allocated 2128896 bytes in 33 chunks
Used memory before GC: 2098304
Used memory after GC : 818304
Freed up bytes : 1280000
As a final note, while this provides an improvement to many of qmlbench's
benchmarks, as they make heavy use of Repeater, these benefits should map quite
well to real world applications as well: anything that uses item views will
likely see a significant reduction to the amount of GC'd objects.
In the future, it would be nice to have tests for the amount of garbage
created by various activities, but that is an item for another day.
Change-Id: Idd14180e689235eea8883d68487570b0e14d47e6
Reviewed-by: Michael Brasser <michael.brasser@live.com>
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
If an external QObject is exposed to an engine through a QObjectWrapper,
make sure to deref and clear the propertyCache reference in the object's
declarative data when the QObjectWrapper is destroyed. This makes sure
that there is no dangling propertyCache pointer when the object is
subsequently exposed to another engine.
Task-number: QTBUG-57633
Change-Id: I37f6793d8be65b23b4e81bb4ed91db18271261b0
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
This is required to be able to implement concurrent or
incremental garbage collection.
Change-Id: Ib3c5eee3779ca2ee08a57cd3961dbcb0537bbb54
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
The new set() method also taked an ExecutionEngine pointer. This makes
it trivial to now add a write barrier for those operations.
Change-Id: I321eccfe6fb279cc240b5c84910e6854f71759f6
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Automatically generate a table containing the data where JS Values
and pointers are in objects in the JS heap.
This will allow making the GC mark phase a lot more efficient.
A bit of a special hack is currently required for MemberData and
ArrayData, as they have a variable length, and we need to read the
size from the object.
We keep backwards compatibility with the old markObjects() functions
for now (calling them if they are defined). Some further work on
QV4::String and in a few other places is required before we can get
remove the compatibility.
Change-Id: I78528ace67e886bdbe4a4330c9677c7fc9f08a33
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
A method and a property can have the same name in a QObject. This is
not directly expressible in a JS object, but when iterating the
properties of a wrapped QObject we should not look them up by name as
we might find the wrong one this way. However, as we already know what
we are looking for, there is no need for any further searching anyway.
Task-number: QTBUG-58887
Change-Id: I68574008c7a078baab9b343d550cc27956b0d5a9
Reviewed-by: hjk <hjk@qt.io>
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Some parts of the ES6 (and even ES5!) spec specifically require handling
of a property write failure. This will be introduced in followup changes,
as it's going to be rather more involved than this.
Change-Id: Ie482493fcf4780df0e23619650a856421d20bd55
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Like this we can remove the QQmlBinding::create() overload
that takes a FunctionObject.
Change-Id: Ib6c37395ded325e68cf0fbf3afd08fb6dd6efa3b
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
It's not needed anymore as we now store this in the binding
directly.
Change-Id: I518c83207f219b690f31200e4d17251075bbd322
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
This is what's in the Value in all cases anyway.
Change-Id: I212c4c4076050e8d0ea4cf6f72a1683e132cd51b
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
The class should get merged with the QV4::QmlContext class.
Simplify the cleanup by moving both classes into a common
file.
Change-Id: I0074da79701d5f41eb51681b70fcde85bfd45fc1
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
And also hint that wrap_slowPath should not be inlined with LTO,
otherwise the fast-path wrap method will lose any advantage it has.
Change-Id: I30d52fa2f64b813aaeb5c0d62f6d48ec1ba03fa1
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
GCC6 might dead-store-eliminate out our secret write to Base::mmdata,
because it expects all memory content to be "undefined" before
constructor calls. Clang might take the same approach if the constructor
of Heap::Object is removed.
By making these structs trivial, it also makes them memcpy-able.
Change-Id: I055b2ad28311b997fbe059849ebda4d5894eaa9b
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
This removes the destructors of subclasses of Base, making them nearly
trivial.
Change-Id: Ia6f7d467e87899b5ad37b8709a8f633a51689d59
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Otherwise a re-use of the C++-owned QObject will have a back reference
to a possibly GCed QV4::QObjectWrapper, which results in exciting
behavior.
Task-number: QTBUG-46263
Change-Id: Iff0e36f9e67c01abd02cfb5a89605d0f26ddb0de
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Mark QQuickItem visual children directly in QQuickItem instead of
relying on the item being a (grand) child of a window.
[ChangeLog][QtQuick] Fix crash with QQuickItems created via JavaScript being
garbage collected sometimes when they're not assigned to a window.
This may happen even in qmlscene when between the creation of the root item and
the assignment to the QQuickWindow the garbage collector runs.
The previous approach of a persistent in QQuickView marking the visual item
hierarchy relies on the existence of a view. The only thing left to do in the
view and qml window implementation is enforcing the CppOwnership policy set on
the content item in QQuickWindow by ensuring the presence of the JS wrapper,
replacing the persistent with a weak value.
This also introduces a new internal mechanism for QObject sub-classes to
provide their own V4 JS wrapper types.
Task-number: QTBUG-39888
Change-Id: Icd45a636a6d4e4528fc19165b13f4e1ca7967087
Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
One of the steps needed to make QV4::Heap::structs trivial.
Change-Id: Ic4d73f15035af21c8a682aaad1ee68cdd91f8e7d
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
One of the steps needed to make QV4::Heap::structs trivial. It also
makes QMetaObjectWrapper memcpy-able.
Change-Id: I1a1b2e5a3fdb87ac4d2b5ace5af3aac54a63d9ed
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
.. to reduce allocations.
Replace fromLatin1 with QLatin1String or
with QStringBuilder where it is possible.
Change-Id: I09c7242fa7b118447b51239e2a6743a34fb3de14
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>