| Commit message (Collapse) | Author | Age | Files | Lines |
... | |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
There are a couple of reasons to split the temporaries off from the
arguments and locals:
Temporaries are invisible, and changes to them cannot be observed.
On the other hand, arguments and locals are visible, and writes to them
can be seen from other places (nested functions), or by using the
arguments array. So, in practice these correspond to memory locations.
(One could argue that if neither nested functions, nor eval(), nor
arguments[] is used, the loads/stores are invisible too. But that's an
optimization, and changing locals/arguments to temporaries can be done
in a separate pass.)
Because of the "volatile" nature of arguments and locals, their usage
cannot be optimized. All optimizations (SSA construction, register
allocation, copy elimination, etc.) work on temporaries. Being able to
easily ignore all non-temporaries has the benefit that optimizations can
be faster.
Previously, Temps were not uniquely numbered: argument 1, local 1, and
temporary 1 all had the same number and were distinguishable by their
type. So, for any mapping from Temp to something else, a QHash was used.
Now that Temps only hold proper temporaries, the indexes do uniquely
identify them. Add to that the fact that after transforming to SSA form
all temporaries are renumbered starting from 0 and without any holes in
the numbering, many of those datastructures can be changed to simple
vectors. That change gives a noticeable performance improvement.
One implication of this change is that a number of functions that took
a Temp as their argument, now need to take Temp-or-ArgLocal, so Expr.
However, it turns out that there are very few places where that applies,
as many of those places also need to take constants or names. However,
explicitly separating memory loads/stores for arguments/locals from
temporaries adds the benefit that it's now easier to do a peep-hole
optimizer for those load/store operations in the future: when a load is
directly preceded by a store, it can be eliminated if the value is
still available in a temporary.
Change-Id: I4114006b076795d9ea9fe3649cdb3b9d7b7508f0
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
|
|
|
|
|
|
|
|
|
|
| |
- Replace 2 QHash<BasicBlock *, ...> with QVector<...>, where the
basic-block index is the index of the vector.
- Nearly all QHashes and QSets will have a minimal fill rate. So,
initialize/reserve all of them with a reasonable minimal size to
prevent re-allocations and re-hashing.
Change-Id: Iade857991d73fddd0b92cecb8d458064b253a08d
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
BasicBlocks have an index property which points to the index of that
basic block in the container array in Function. This property can be
used to store calculated information about basic blocks in a vector,
where the vector index corresponds to the basic block index. This is
a lot cheaper than storing any information in a
QHash<BasicBlock *, ....>.
However, this numbering requires that no re-ordering or deletion of
blocks happens. This change cleans up all that handling which was
scattered over a number of places.
Change-Id: I337abd39c030b9d30c82b7bbcf2ba89e50a08e63
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
|
|
|
|
| |
Change-Id: I6185b59a7dfd6977ce82581ab4385e07d78f13f6
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
|
|
|
|
|
|
|
|
|
|
| |
Properly convert the argument to an object if
it's not null or undefined as mandated by the
standard.
Add a similar test case for the with statement.
Change-Id: Idd8e245e8dae4803eb0e2010e3d43bb912670444
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
|
|
|
|
|
|
|
|
|
|
| |
unsigned.
compiler\qv4isel_moth.cpp(1041) : warning C4146: unary minus operator applied to unsigned type, result still unsigned
compiler\qv4isel_moth.cpp(1056) : warning C4146: unary minus operator applied to unsigned type, result still unsigned
compiler\qv4isel_moth.cpp(1096) : warning C4146: unary minus operator applied to unsigned type, result still unsigned
Change-Id: Idb4714a277486ff736f49c50c7e840fd62e2150f
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
|
|
|
|
|
|
|
|
|
| |
Move all our runtime methods into the QV4::Runtime
struct and give them nicer names without underscores.
Sort them logically and remove a few unused methods.
Change-Id: Ib69b71764ff194d0ba211aac581f9a99734d8180
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The debugger should only have one breakpoint that can
be set per line. Nevertheless, we should have proper
line number information available in case we stop at
other places.
We also need a debug instruction before the return
statement, so that step out will always find a last
stopping point in the parent frame.
Change-Id: I86145fc244148f106a4a97ce69ab60b568c8dac6
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
|
|
|
|
|
|
|
| |
Make sure stepping works correctly, and we always
break at a valid breakpoint.
Change-Id: I6a3032b3ae204484b8a92b2031904a7f681c7f80
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
|
|
|
|
|
|
|
|
|
| |
This unifies the way we handle line numbers in the
JIT and Interpreter.
Remove the now unused lineNumberMapping code and data.
Change-Id: I1d60b1fbb77e70b531fa73d93410683e84dd1e3c
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Only store a Hash of break points in the debugger,
instead of the involved logic that currently adds and
removes break points. Add the current line number to
the Debug statements in the interpreter, and pass them
on to the debugger for checking whether we should really
break.
This adds a slight additional overhead to running inside the
debugger, but greatly simplifies the logic and doesn't require
modifying the bytecode anymore. This in turn opens up the
possibility to run the debugger on JIT generated code later on.
Change-Id: If2a3ae8f8d08b69a3a704cbbe0a84000f917a32e
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
|
|
|
|
| |
Change-Id: I69a736ac7920a10667949475600460ee43d61480
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
|
|
|
|
| |
Change-Id: I13c7d9dda7cd1e771079f6fdaa175008b3a3e0e5
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
|
|
|
|
|
|
| |
compile time
Change-Id: Ieb7f6ee97a4f251f1e2369850ebb9e2931f84ac1
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Object literals with array indices are now created with one
run-time call, instead of an initial one for non-integral keys
followed by sub-sequent define_builtin_property calls.
* Cleaned up propert name retrieval. Instead of using a visitor,
it's easier to define a virtual method on the PropertyName type. The visitor
doesn't buy us much as it's not possible to recurse within property names, and
this way we can use it also from the function scanner to correctly determine
the number of arguments needed for object literal initalizations.
* Similarly the duplicated/common name member for all property assignments
has been moved into PropertyName, for convenient access without AST casts.
* Removed now unused builtin_define_property/settergetter functions from IR,
run-time and moth.
Change-Id: I90d54c81ea5f3f500f4f4a9c14f7caf5135e7f9f
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
|
|
|
|
|
|
|
|
| |
QQmlJS::MASM -> QV4::JIT
QQmlJS::V4IR -> QV4::IR
Change-Id: I707e8990459114a699c200fe3c22cec3c8df1afc
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Use the life-time intervals to track which temps go out of scope, in
order to re-use the stack-slots they occupied. This reduces the memory
consumption on the JavaScript stack and allows for deeper call stacks.
For the ECMA tests, this reduces the number of slots needed for the
main/entry function from more than 650 to about 10 (depending on the
test).
Change-Id: Iff4044f5ff7f25e1f88ff1a04f4e80dd99a67590
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
|
|
|
|
|
|
|
|
|
|
| |
These instructions did hurt more than help, as they converted
ints to doubles. Since the regular add/sub/mul runtime methods
have fast paths for both ints and doubles, we're better off
using those instead.
Change-Id: I0b7a6f95818943bfc8a0669c1c56f7db4e7246e0
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
|
|
|
|
|
|
|
| |
This avoids the bool invert in the instruction
stream, and some additional code in the VME.
Change-Id: I0ea675a2e3d07c1b8c5234b888d8d9683bcee330
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
|
|
|
|
| |
Change-Id: Ie01ef2be8beb890b1ca56bbdc990ccea87c1d91e
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
|
|
|
|
|
|
|
| |
These give a measurable speedup as the critical code
paths are now inline.
Change-Id: I3cee8a432fbe96d66ba1e6bd277a38e624a50c14
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
|
|
|
|
|
|
| |
This simplifies and speeds up loading of constants
Change-Id: I05b4f7a34abd4ed6416fa800a31debbb28b37104
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This avoid having to check for the debugger at every instruction
we execute. Instead we only add debug instructions at the beginning
of every line and every basic block when we have a debugger.
This still allows interrupting the JS execution at any time (as we
can't loop inside a basic block), and single stepping through lines.
But it has no overhead when the debugger is not running and a lot
less when it is running.
Change-Id: Ib17170b42944b608fc6caa1891082205dd2b2763
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Reviewed-by: Erik Verbruggen <erik.verbruggen@digia.com>
|
|
|
|
|
|
|
| |
Significantly speeds up crypto.js
Change-Id: Icd3d59bea3fe4427e93e9e10e3526178e8de859c
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
|
|
|
|
|
|
|
|
|
|
| |
* Resolve lookups in namespaces at compile time and instruct the SSA optimizer
to eliminate reads from the namespace (QQmlTypeWrapper) if possible. For example
access to attached properties of types (i.e. MyNameSpace.ListView.isCurrentItem)
requires neither reading the namespace nor the type.
* Add support for accelerated lookup of attached properties
Change-Id: Ib0b66404ed7e70e1d4a46a1ac8218743a4cc8608
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
|
|
|
|
|
|
|
|
|
| |
With this patch we determine the meta-object of singletons, propagate it into
the IR and load them separately using a dedicated run-time function. In
addition enums in singletons and QML types are resolved at compile time.
Change-Id: I01ce1288391b476d1c9af669cb2987a44c885703
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
|
|
|
|
|
|
|
|
|
|
|
|
| |
...instead of a special MEMBER type. This allows removing the
type member from V4IR::Member altogether (and thus unshadow from
V4IR::Expr::type). By not requiring the base of a id lookup
member expression to be a NAME, we can also speed up repeated
id lookups by fetching the id object array wrapper only once
per function.
Change-Id: I3e9b8f498d32ace4a0cc2254f49e02ecc124f79c
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Propagate QObject properties in member expressions across temporaries
as part of the type interference SSA pass. This replaces the earlier
attempt to resolving QObject properties in fieldMemberExpression()
in the codegen, but it was incomplete and now things like the following
are fully resolved:
var tmp = blah.somePropertyThatReturnsAQQuickItem; <-- QQuickItem property return type propagated into tmp
var width = tmp.width; <-- and picked up here again to resolve the index of width instead of by name
With this patch Temp gets a helper structure with a function pointer,
initialized to aid the resolution of properties in Qt meta objects. This
structure is propagated into the temps until it reaches the next member
expression that uses the temp. Similarly QObjectType is added as IR type, next
to VarType.
The resolution inside the SSA type interference pass also requires passing
through the QQmlEngine from the upper caller levels, in order to resolve the
property type to a potential QMetaObject property.
Change-Id: I14c98fa455db57603da46613ce49c174d0944291
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
|
|
|
|
|
|
|
|
| |
This is not used that often, but it removes one more place
where we do lookups by name.
Change-Id: I9f798b8b4a64be3fdf3e53090e4288724c9d2b22
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The previous approach of collecting the dependencies through an IR visitor
doesn't work, because it relies on a fixed structure - for example MEMBER(NAME,
prop) - which we can't guarantee (it's usually MEMBER(TEMP, prop)). But it
turns out that we can only pre-calculate dependencies for context, scope or id
properties, so we can do that right away in the QML specific JS codegen, store
that information in the IR function and use it from there in the data structure
generator as well as in the isel as a parameter to getQObjectProperty to tell
the run-time whether capture is required or not.
Change-Id: I33711c3420d6534c653c2a6a4284f0fc12e941cf
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
|
|
|
|
|
|
|
|
|
|
| |
The life-ranges are only valid when the IR is in SSA form. So the use
of them in the interpreter after converting out of SSA form introduced
bugs. Instead, allocate a stack-slot for each unique temporary, and
re-use the code for this from the JIT.
Change-Id: I294f1116064f0b85996cf96a0b408b41a3c785e2
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
|
|
|
|
|
|
|
|
|
|
|
|
| |
When a non strict mode function uses the this object, we
need to make sure it's being correctly converted into a
object before being accessed. So far this was being done
by ScriptFunction::call. Move this into the generated code to
avoid overhead for methods not using 'this', and simplify our
ScriptFunction::call() implementation.
Change-Id: I739f4a89d29ed8082ce59e48d1523776224fc29d
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
|
|
|
|
| |
Change-Id: Ic0492fbe31a1e134674bc6c20381f735dd6d5b7a
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
|
|
|
|
|
|
|
|
|
| |
The QQmlContextData stores the JS objects of imported scripts in a
QList<PersistentValue>. Instead of indexing into that list, this patch changes
ctxt->importedScripts to be a JavaScript array, that in the IR we can index via
subscript.
Change-Id: Ie2c35fb5294a20a0b7084bb51d19671a27195fec
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
|
|
|
|
|
|
|
|
| |
We can resolve the use of names that refer to imported scripts at compile
time and load them at run-time by index through context->importedScripts.
Change-Id: I681b19e7d68dbf3b9a68af00b4cea2a9254c2d78
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
|
|
|
|
|
|
|
|
| |
After the resolution of a property, we can set it by index at run-time instead
of via name resolution.
Change-Id: I479599dabe343cf9e6582dcda12291aebfcce418
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
objects at QML compile time
This avoids having to do a string lookup for ids and in the import cache at
run-time, before we can do a string hash lookup in the property cache. Instead
we resolve final properties in the context and scope object at compile time and
look them up at run-time using their index instead. The dependencies to these
properties are also tracked separately and recorded in the compiled data.
This is merely the initial patch. There's a lot left to do, such as having
specialized getter and setters for specific property types. Setters are missing
altogether right now and will fall back to name lookup.
Change-Id: If3cb4e7c9454ef4850a615f0935b311c9395b165
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Implement lookup calls for the interpreter. This
significantly reduces overhead by avoiding repeated
name lookups on the same object type.
This doubles the speed of quite a few of the v8
benchmarks, and brings the interpreter up to close
to 40% of the speed of the JIT.
Change-Id: Ie8c2f5b1ca71a7329bc643c3d2158a6301a392ed
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
|
|
|
|
|
|
|
| |
Optimize unops for ints/bools and add some
special binops where one side is constant.
Change-Id: I4f5639e36458560e5614371733abaafd94909ab1
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
|
|
|
|
|
|
| |
This gives another 10-15% for v8-bench
Change-Id: Iaea90402179813af23008c35d344fa7f5353cf5f
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We can resolve lookups for objects referenced by id at QML compile time
and use a run-time helper to extract the id object out of the QML context
data by index instead of name.
Dependencies to id objects are also tracked at compile time and registered
separately before entering the generated function code.
The lookup of id objects is encoded in the IR as special member lookups.
Members will also then in the future be used to for property lookups in context
and scope properties, as well as any other property lookups in QObjects where
we can determine the meta-object.
Change-Id: I36cf3ceb11b51a983da6cad5b61c3bf574acc20a
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
|
|
|
|
|
| |
Change-Id: I6e141a425c2b4cc0cd64c7f0011e7028b9147f69
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
|
|
|
|
|
|
|
|
|
| |
Get rid of the parameter type, and only store a
scope, that is an index into a SafeValue ** array.
This significantly speeds up loading and saving of
parameters.
Change-Id: I185145f1afd0b8cea461c7ca732ada3ebe39c34c
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
|
|
|
|
|
|
|
|
| |
With the constant table this is exactly the same as a move.
Also renamed MoveTemp to Move, as it not only moves Temps
but also other variables.
Change-Id: I1fccc04314661954179d903519adbc39777395e5
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
|
|
|
|
|
|
|
|
| |
This makes it possible to remove the Value stored as
part of the instruction stream. Reduces the size of the
instruction stream and will allow to optimize Param lookup.
Change-Id: I23dab5dbed76bf8d62df7042934064d4676bc43d
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
|
|
|
|
|
|
|
|
| |
Add the required instructions and check for
exceptions in the engine before storing any
results.
Change-Id: Ibfaf904d659859e8012920270825211ba202c63d
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Simplify the generated code. Add a special block to catch
exceptions thrown inside a catch() statement.
store the exception on the stack when entering finally and
rethrow it at the end. This ensure correct behavior for
break/continue/return statements inside finally.
Don't check for exceptions after calling push_catch_scope
and pop_scope in the JIT'ed code. This can lead to infinite
loops when throwing inside an exception handler.
Change-Id: I67e9325794e2fd25b0773b21e02fbaadb43faab0
Change-Id: Ic1ea9c0c43eec1d49177dc1ab4552a1da04e96fe
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Start the work to remove c++ exceptions from our JS
exception handling. Rather rely on engine->hasException.
Check the flag after we return from any runtime call in the
JIT.
Implement new try/catch handling code in qv4codegen and
for the JIT that doesn't rely on exceptions. As an added
bonus, we can remove the Try statement in the IR.
Change-Id: Ic95addd6ae03371c43c47e04cac26afdce23a061
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
|
|
|
|
|
|
|
|
|
|
| |
The allocator doesn't work correctly and sometimes assigns
temps with overlapping ranges to the same stack slot.
This fixes crypto.js and qt quick controls autotests running
with the interpreter.
Change-Id: If3d0f90edfac669f89da5174cd58eb345d48f2b8
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
|
|
|
|
|
|
|
|
| |
With a growing number of functions per module, these calls become
expensive and are unnecessary. defineFunction in the code generator
can simply return the correct index right away.
Change-Id: I8ab56a3083bf215674a1b46c502b415be694e465
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
|