Saves around 1.5% instructions for the Earley Boyer benchmark
Change-Id: I552d324d5e1713f655ab9909f30c9527bb4ff777
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Avoid creation of the Array in most cases. Fix FunctionObject::method_apply
so that it correctly recognizes this case and does the right thing.
Add a getLength() method to ArgumentsObject to speed up the lookup of that
property.
Improves the RayTrace benchmark by around 15%.
Change-Id: I53eb34a1f9515e59a191ee6f0eb23a3f4c6882d1
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Remove some unused ones and simplify the version taking
a QString
Change-Id: I682b4a06d4da84c2d6be7e4a9a3e831dbd11c9c4
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Now that the code paths are very similar, we can simply to the
check whether to do a fast or slow function call in
ScriptFunction::call/contruct. To make this fast, cache the
result of the required check in QV4::Function
Change-Id: I03085ca2beb83b1721b60b0d7b2ab4c9266d1e48
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
One of the overloads took a QV4::Function * and was so far
apparently unused (as it couldn't have worked since change
3b14e2ffdd). Fix it since
it's getting some use again in the next change.
Change-Id: I3eabb332f9e3f2262a5710d43016346b7138f7e7
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>
Instead, simply create a QmlContext, and setup the bindings with
the QV4::Function itself.
Change-Id: I9db93b15112e43a6d5e275d126fb20f9c8833e8f
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Moves the error checking to where the error occurs.
Change-Id: I2590d3a9d41f41c16d19e4f5883b78a8b28a883c
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
It was just forwarding to the parent implementation anyway.
Change-Id: I179966699978a86efdd6792b31b56eded501efbd
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Factor the common code out into separate methods that can
later on be reused by the QQmlJavaScriptExpression.
Also ensure a CallContext is safe to use with a 0
FunctionObject.
Change-Id: I1181a8e320b8c931d9df5b2c91bc143d8587fb60
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
This allows re-using the check in the QQmlJavascriptExpression code.
Change-Id: I647a6edb4844911f540f08c4a067d055676dd0ed
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
The prepares for being able to call binding code without having
to create a full FunctionObject.
Change-Id: I5f0dcaa4d1ae8876554cac82597351801588bc02
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>
GCC6 with LTO will assume that the then-part is the common path. For
ArrayData-to-CallData "conversion" this is not the case, so reorder
that.
Change-Id: I856ef9b5747e9858a35f15a23159cf7c12fd75ef
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Even with LTO on, GCC6 will not optimize out the fact that a) the d()
pointer won't change here, and that d()->function is constant and not
need to be checked for nullptr all the time.
Also prevents allocating 0 locals, which would still run most of the
jsAlloca code for no good reason.
Change-Id: Iaf5257743cb57d55bef5d334d1e4355590dae7c6
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>
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>
This change also adds a check to the d() calls for Managed, verifies
that the object has been initialized. This is only done for debug
builds.
To prevent other code from tripping the check, a number of other classes
are either marked as trivial, or do initialization in the constructors.
Because of template function changes in them memory manager (those now
call init() instead of in-place new), String has an extra parameter
to force it to temporarily use an old/unmodified template function.
Change-Id: I8c35161ce7680835d830638b6d21498c5129b02b
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
One more step needed to make QV4::Heap::structs trivial.
Change-Id: I6bebfaff970518d65a09f2b9f50a6855c431d4c0
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Do the same thing as in ScriptFunction::construct. If
the return value of the call is not an object, return the
this object passed into the function. If an exception got
thrown return undefined.
Fixes the test failures in section 15.3.5 in the JS test suite.
Change-Id: I7a640f3eb0eb7d207ccfa1ff927a46031a6d2c06
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Fixup for 702c4247d7.
Fixes the test failures in section 15.3.4 of the JS
test suite.
Change-Id: Id44886e0301b560f2975104757467bb0c22aed60
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
When running on a big-endian system, we need to convert the constant values
into big-endian once and then it's possible to access them directly.
Change-Id: I655bad7b7734e3b95e79e5f688f0b4041d0c41c4
Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
On 32-bit architectures we were encoding the absolute address of generated
constants in memory into the load instruction. In order to make the code
reloctable, this patch changes the JIT over to use the constant table in the
compilation unit. This means two additional loads per constant. On
architectures that support instruction pointer relative addressing, we can try
to fix this in the future (arm32 for example).
Change-Id: I8ed7aa7c67711696d6c46c72b3b642d610ff2cbc
Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
This will allow us to #define them away on -no-qml-debug, saving two
pointers per engine.
Change-Id: I400cffd32cd7f55ff0e68565734b6002b9f901d5
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
QML objects can be re-parented on the fly, resulting in different
dependencies for expressions like 'parent.width'. So, because of this,
dependencies are cleared and re-calculated after every binding
evaluation.
However, dependencies on properties of the scope and context objects
cannot change, because these objects do not get changed for the
life-time of a binding. So we can permanently register them. This is
only done for bindings, not for functions, because those might be
conditionally executed.
According to valgrind, this is a reduction of ~186 instructions on x86
for every evaluation of:
Item {
height: width
}
Change-Id: Ib095497323d4f08caf712d480007e2627a176369
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
The implementation of many (or all) runtime functions consist of first
creating a QV4::Scope, which saves and restores the JS stack pointer.
It also prevents tail-calls because of that restoring behavior. In many
cases it suffices to do that at the entry-point of the runtime.
The return value of a JS function call is now also stored in the scope.
Previously, all return values were stored in a ScopedValue, got loaded
on return, and immediately stored in another ScopedValue in the caller.
This resulted in a lot of stores, where now there is only one store
needed, and no extra ScopedValue for every function.
Change-Id: I13d80fc0ce72c5702ef1536d41d12f710c5914fa
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
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>
QV4::Heap::Base::setVtable has a Q_ASSERT on the state of Base::mm_data,
but that member is never initialized anywhere (that is, the Base class
does not properly protect its invariant). There were workarounds in some
places for initializing the member, but only in debug mode.
That was wrong for a number of reasons:
1) Q_ASSERT is still enabled if QT_FORCE_ASSERTS is defined
2) in release mode, the compiler will remove the double initialization
anyway
Another solution would be to give QV4::Heap::Base a constructor that
initializes the member, but I am not sure whether adding a constructor
to this class is permitted.
Task-number: QTBUG-49681
Change-Id: Ic90fe6b1cbe84978a02fffff141beacbe73c0b9c
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
This fix prevents the crash documented in QTBUG-49076.
To quote Erik on the cause of the crash:
Call stack is probably: FunctionPrototype::method_bind ->
BoundFunction::create -> mm::allocObject ->
BoundFunction::BoundFunction -> Heap::FunctionObject ->
(Scoped)FunctionObject::init -> engine::newObject ->
... -> mm::allocObject
The call to Heap::FunctionObject in BoundFunction is the
call to the parent class constructor, which causes an
allocation. But at that point, BoundFunction's target is
still zero-initialised (the real initialization happens
first thing *after* the parent class' constructor is called).
Change-Id: If256f59168867cba9c886642ebaacb1d56801da4
Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
Use character literals where applicable.
Change-Id: I294fc4cb5cbbd23df9735ba2b398118f37cbe08a
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
This allocation doesn't grow so use an exact sizes one.
Change-Id: Ib0117b3a1932bcdc26a4aac6759a08db43a90225
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
There's only one place where we need to resize our member
data, namely when we call setInternalClass() on an object.
In addition, encapsulate the access to the memberdata better
in preparation for inline property data later on.
Change-Id: Ia34d0253d5d1792f1d7c4981556d78375fa7a755
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>
Avoid the implicit push inside the execution context constructor
and rather make this explicit in the code.
Change-Id: I1bb0fb523fddbb273fc666370d619f55f49cd40a
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 creating new QML contexts, these are not used directly,
but rather as scopes for other functions. Change the
behavior, so that newQmlContext doesn't push the new context
onto the context stack.
Change-Id: I8254da3f660c4791941835c925b9892274ea51b0
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
Qml Connection objects where using an awkward way to
make the parameter names of signals available to the
signal handler. This now uses an approach that is
equivalent to what we do with other functions.
The main difference is that we can't know the parameter names
at type compile time, so we have to rewrite the internal class
of the QV4::Function at connect time.
Change-Id: I5e538ac840b5a46ccb14ff71684404d947948324
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
It's now QV4::FunctionObject::createQmlFunction, which I
believe is a better place and name for the method, esp.
as it has no real connnection to the binding wrapper anymore.
Change-Id: I59e20e120db72e53735b3a986e0b91bc7c3347d7
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
This is where the method logically belongs, and removes one more
thing from the context wrapper.
Change-Id: Ibc076c9b31903a484ad4517402eca2a3b7f0d660
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>
Create a specialized QmlContext instead of re-using
a call context with a QQmlContextWrapper as activation
object.
This saves some memory and opens up the route to getting
rid of the context wrapper in a future commit.
Change-Id: I1591c73932a08564fddf5137ac05bbc6f31dd4d5
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>