Commit Graph

194 Commits

Author SHA1 Message Date
Lars Knoll 10c1e40533 Unify mark handling for MemberData and ArrayData
Introduce a ValueArray class, that defines an array of
Values at the end of a Heap Object.

Change-Id: I00efbf6f5839a6687dd5bc5fc037ec8f06e0936e
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2017-03-09 08:58:15 +00:00
Lars Knoll 6b4b2f5f1b New mark table implementation
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>
2017-03-09 08:58:04 +00:00
Lars Knoll 802bebd566 Merge remote-tracking branch 'origin/5.9' into dev
Change-Id: I372850330c1d92edc5b07596759f0db3a59082a8
2017-02-14 08:21:39 +01:00
Robin Burchell 62268fb2a0 Object: Introduce set and setIndexed
These names are what the ES6 spec uses for this operation. We also
introduce a bool to allow throwing unconditionally if a set fails (which
the spec requires the Set operation to do in a number of places). This
requirement was also present in ES5, but we ignored it, and thus far got
away with it.

Long term, put and putIndexed should go away, but I don't feel
comfortable porting everything over blindly, as some operations do
require throwing, namely:

* Various Array & TypedArray methods that alter 'length'
* Various RegExp methods that alter 'lastIndex'

This change also ports the new Object.assign to use the must-throw
version of set(), which coincidentally fixes the one test failure in
non-strict mode.

Change-Id: Ida641a552d805af0fd9de3333eb62cc6adb3713c
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2017-02-09 14:53:06 +00:00
Robin Burchell 5f83e6dfe6 Object: Allow put and putIndexed to return success or failure
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>
2017-02-09 14:53:01 +00:00
Robin Burchell 60d67b4eb9 QV4Object: Remove helper put() method
This isn't used much, and we can do a bit of a better job by doing it by
hand. In the case of jsonobject, we can reuse the empty string, and in
the other uses, we can avoid allocating multiple values on the JS stack.

Change-Id: I1f02cd86e3969c1471981978d18ce8512412123b
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2017-02-09 14:52:55 +00:00
Robin Burchell 6653fdb6bf FunctionObject: Mark name/length property configurable
In ES5, these were not configurable, but ES6 changed the behavior.

For length, refer to:
    9.2.4 (FunctionInitialize)
    17 (ECMAScript Standard Built-in Objects):
        Unless otherwise specified, the length property of a built-in Function
        object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
        [[Configurable]]: true }.
    19.2.2.1 Function.length
    19.2.3.2 (Function.prototype.bind)
    19.2.4.1 (Function instances, length)

For name, refer to:
    9.2.11 (SetFunctionName)

This does regress test262 for ES5 for me a little, but improves our es6 test
coverage a bit (~682 more tests pass, +1.5%).

Change-Id: Icda7c9068dc3e6e4e4aebbb0d359868a30343013
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2017-02-03 15:10:33 +00:00
Robin Burchell b7090f1334 Fix a crash in setInternalClass
Revealed by the ES6 testsuite, ./test/built-ins/Object/freeze/15.2.3.9-2-1.js
and probably others. We cannot unconditionally dereference memberData,
it may not always exist.

ES6 tests test/built-ins/Object/freeze before:
    === Summary ===
     - Ran 92 tests
     - Passed 66 tests (71.7%)
     - Failed 26 tests (28.3%)

after:
    === Summary ===
     - Ran 92 tests
     - Passed 90 tests (97.8%)
     - Failed 2 tests (2.2%)

Change-Id: I22a6c9ca081394ba15edfde09f73769eb3ce47b3
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
2017-02-03 12:48:40 +00:00
Robin Burchell 040a70ea20 jsruntime: Add a vtable hook on Object for instanceof
This will hopefully allow us to customize the behavior of
QmlTypeWrapper to allow comparison QMetaObject comparison against a
QObjectWrapper lhs (i.e. foo instanceof Item will hopefully be possible)

Task-number: QTBUG-24799
Change-Id: I780c8b424ec14d6ed6f93eeac46390e2fc920000
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
2017-01-26 15:26:28 +00:00
Lars Knoll 7adf9caa6f Ensure that we never create empty MemberData objects
They don't make sense.

Also fixes a crash in test262, where we would pass n == 0 to
MemberData::allocate().

Change-Id: Ia95ab6632bd1998afe84a38c38c3c6603230362d
Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
2017-01-25 14:16:35 +00:00
Lars Knoll cea4a039d7 Convert builtins in TypedArray, ArrayBuffer and DataView
Change-Id: I091020406f438f2dedf9ccae950fb328f2cf5522
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2017-01-25 08:31:14 +00:00
Lars Knoll c2a4277ae5 Speed up invocation of builtin functions
Completely avoid creation of a CallContext for those methods,
as we don't need it.

Change-Id: Iff1a38fd3c7e846df6ec0374cb7b3fb8f1b4de3a
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2017-01-25 08:31:10 +00:00
Lars Knoll a56809dcfd Get rid of the inline member data in Object
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>
2017-01-25 08:30:59 +00:00
Lars Knoll cf960d2ce2 Streamline code allocating MemberData
Saves around 1% in the Splay benchmark.

Change-Id: I32c8807d6688351beea2a34d945e8ef87b31355f
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
2016-12-13 08:27:50 +00:00
Erik Verbruggen 3b14e2ffdd QML: Make Heap::Object and all subclasses trivial
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>
2016-10-06 11:44:08 +00:00
Anton Kudryavtsev c03d9c49d3 Qml: replace QStringLiteral with QL1S
... or with QL1C in such cases:

- if there is overloaded function
- in QStringBuilder expressions

Saves ~1.5 KB in text size.
Build config: ubuntu 16.04 x64, gcc 5.3

Change-Id: Icc0789f1c244ce20a3182494b0c7f35c9d77e41d
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2016-07-05 15:22:08 +00:00
Erik Verbruggen 702c4247d7 V4: Pass scope around as parameters inside the runtime.
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>
2016-06-22 11:07:05 +00:00
Frank Meerkoetter 4be62189a1 Scrape off some more allocations by using the QStringBuilder
Change-Id: I25cbbcad086afb15694f69bdc52bd4ddce4b3a18
Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
2016-05-09 13:21:31 +00:00
Jani Heikkinen 45bd04ba73 Updated license headers
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>
2016-01-19 14:53:18 +00:00
Lars Knoll af390399c8 Fix a crash when copying array data
Regression from 5.5. d()->arrayData->alloc can be larger, but
never smaller than the allocation of the other's array data.

Change-Id: I7d2265768f9d6e6298bfbba0d674a4d0e642422f
Task-number: QTBUG-48727
Reviewed-by: Liang Qi <liang.qi@theqtcompany.com>
Reviewed-by: Nikita Krupenko <krnekit@gmail.com>
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
2015-10-20 06:47:42 +00:00
Lars Knoll 3f12ee31a4 Add method to convert identifiers back into QV4::String objects
Allocating a new String for the Identifier is wasting both memory
and CPU. Let's rather extract it from the IdentifierTable.

Change-Id: Ibb9b2ac9775fefce74602d6954586195cdd5814e
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
2015-09-25 08:38:40 +00:00
Lars Knoll 13edffa303 Move remaining objects to new constructor syntax
Also disable the old way of constructing objects.

Change-Id: Ib4e69087cd563ae1481da116d6caf97876239798
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
2015-09-22 08:20:13 +00:00
Lars Knoll 9420eb5c4e Use the new construction scheme for RegExpObjects
Gives around 10% speed improvement on the v8 regexp
benchmark.

Change-Id: Iad37bcbc79ccbfb92f65852b660364c919862a75
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
2015-09-22 08:19:59 +00:00
Lars Knoll 833c99db20 Inline property data into the object
Append the part of the objects property data that is
known ad instantiation time to the object itself and
by that avoid creating a separate MemberData. Saves
some memory and should speed up object creation.

Currently implemented only for Object and ArrayObject.

Change-Id: I7693bf2f3a28fb718522398ebb94ac115e021fa4
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
2015-09-22 08:19:53 +00:00
Lars Knoll b58c33da59 Get rid of propertyAt in Object
Change-Id: I3022b3c5c1ae90530ef5ca88e0b88a2fd1102e73
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
2015-09-15 19:13:20 +00:00
Lars Knoll 15cd948bda Replace __getPropertyDescriptor__ with a getValueOrSetter call
This one returns a pointer to a Value instead of a property.

Change-Id: I66e16526cc61d1ff3564cae983881c30b9106b54
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
2015-09-15 19:13:16 +00:00
Lars Knoll e13b9624b0 Further reduce usage of Property
Using Property * as return value is something I wanted to get rid of for
a long time. As this interferes with storing properties inline in the
Object, now is a good time to finally do the work :)

Change-Id: I30594bad9a4cea5d9d606ebe02d7f3e707b4263a
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
2015-09-15 19:13:07 +00:00
Lars Knoll 665f17782a Simplify Object::getValue
Object::getValue only needs the value/property getter. Because of this
it's enough to pass it the Value stored in the member/arrayData and the
property attributes. Like this we avoid the reinterpret_cast to a
Property pointer.

Change-Id: Ib6873526f9db22ed0e607e3617be5729b15271ab
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
2015-09-15 19:13:03 +00:00
Lars Knoll 9ea6c69ab5 Simplify Object::putValue()
Change-Id: I1cc43f0081f63aed27c82875192e0f415ec995d5
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
2015-09-15 19:12:59 +00:00
Lars Knoll 64c3e1cbb1 Cleanups
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>
2015-09-15 19:12:47 +00:00
Lars Knoll fb52dab6b4 Further cleanups
Reduce usage of ScopedContext.

Change-Id: I84a6a7478065de3398fd0b21596ca1308e78ceb3
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
2015-09-15 19:12:40 +00:00
Lars Knoll 0e6195a85c Cleanup usage of ExecutionEngine::currentContext
Change-Id: Ic79d6da162375928ec25871cd0341daeab6483d2
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
2015-09-15 07:37:22 +00:00
Lars Knoll 415f55d140 Encapsulate and protect all accesses to the vtable of Heap objects
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>
2015-08-10 07:24:32 +00:00
Erik Verbruggen 92836d052e Remove type punning from QV4::Value.
The union in QV4::Value is used to do type punning. In C++, this is
compiler-defined behavior. For example, Clang and GCC will try to detect
it and try to do the proper thing. However, it can play havoc with Alias
Analysis, and it is not guaranteed that some Undefined Behavior (or
Compiler depenedent behavior) might occur.

The really problematic part is the struct inside the union: depending on
the calling convention and the register size, it results in some
exciting code. For example, the AMD64 ABI specifies that a struct of two
values of INTEGER class can be passed in separate registers when doing a
function call. Now, if the AA in the compiler looses track of the fact
that the tag overlaps with the double, you might get:

    ecx := someTag
    ... conditional jumps
double_case:
    rdx := xorredDoubleValue
    callq someWhere

If the someWhere function checks for the tag first, mayhem ensues: the
double value in rdx does not overwrite the tag that is passed in ecx.

Changing the code to do reinterpret_cast<>s might also give problems
on 32bit architectures, because there is a double, whose size is not the
same as the size of the tag, which could confuse AA.

So, to fix this, the following is changed:
- only have a quint64 field in the QV4::Value, which has the added
  benefit that it's very clear for the compiler that it's a POD
- as memcpy is the only approved way to ensure bit-by-bit "conversion"
  between types (esp. FP<->non-FP types), change all conversions to use
  memcpy. Use bitops (shift/and/or) for anything else.
- only use accessor functions for non-quint64 values

As any modern compiler has memcpy as an intrinsic, the call will be
replaced with one or a few move instructions. The accessor functions
also get inlined, the bitops get optimized, so in all cases the compiler
can generate the most compact code possible.

This patch obsoletes f558bc4858 (which had
the exact aliassing problem of the double and the tag as described
above).

Change-Id: I60a39d8564be5ce6106403a56a8de90943217006
Reviewed-by: Ulf Hermann <ulf.hermann@theqtcompany.com>
2015-07-24 11:44:05 +00:00
Lars Knoll 64199b0a58 Store a Heap::String pointer in StringObject
Change-Id: I926c5bb2dd4f1613af6737d4200e568f0ec13d58
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
2015-06-17 09:03:48 +00:00
Lars Knoll 81d8e36c17 Get rid of the tmpProperty in StringObject
This was a bad hack. The new code is cleaner, and should
also perform faster in a couple of cases (avoiding the creation
of a temporary String that is then only thrown away).

Change-Id: Ia6f978e037506484adbc01a61606307d4645b343
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
2015-06-17 09:03:46 +00:00
Lars Knoll a4aa358acf Fix Object::getOwnProperty API
Don't return a Proprety pointer, this has issues with
StringObject. Instead pass in a pointer that will get filled
with the correct data.

Change-Id: I28536ca129f5be3a4a1bc9583223521458411195
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
2015-06-17 09:03:43 +00:00
Lars Knoll 864988474a Move the StringValue members of ExecutionEngine onto the JS stack
Change-Id: Ib55c05f1730b7659e2f6fee7e1fa79c10c759167
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
2015-06-10 15:01:17 +00:00
Lars Knoll f9440c704e Move more objects from the v4 engine to the js stack
Convert most of the prototype objects in the v4 engine.

Change-Id: I365f290493c20973bc991b6a383649836e42a16a
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
2015-04-24 15:21:28 +00:00
Lars Knoll 0a499043fb Get rid of qv4value_inl_p.h and replace it by qv4typedvalue_p.h
This is a cleaner separation and further reduces include dependencies
in the definitions of our basic data structured.

Change-Id: I18aa86cdea0c0dfbc16075d4d617af97e638811e
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
2015-04-24 15:20:43 +00:00
Lars Knoll 1401a2ef0a Rename Heap::Base::as() to cast()
The as() methods in other places to dynamic type checking, whereas
cast() methods are basically the same as a static_cast.

Change-Id: Iacd0174824b41b8fad05d6b55b1e62e3b44a31db
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
2015-04-21 14:21:45 +00:00
Lars Knoll b4cb71e9d7 More cleanups
Get rid of Value::asObject(), and pass const Managed pointers
into some more vtable methods.

Change-Id: Ia4f427d5fd8868f77b4015d1ce5424d32bfc2115
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
2015-04-21 13:01:47 +00:00
Lars Knoll fc5a11aadc Get rid of asManaged()
Change-Id: I853417fdf1cc339f7d43a006c20e1626b6bfb288
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
2015-04-21 13:01:41 +00:00
Lars Knoll 4930941197 Further cleanups
The get and getIndexed vtable methods should take a const Managed
pointer. Start cleaning up the asFoo() methods in Value and Managed
by removing asArrayObject() and asErrorObject().

Change-Id: Ibd49bf20773ef84c15785b7ac37a7bc9fd4745d5
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
2015-04-16 17:44:24 +00:00
Lars Knoll 6e3b0d3ace Reduce dependencies
Change-Id: I4190c1a6d8a06a130e50cb727feafa7cf11f21cd
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
2015-03-20 11:16:56 +00:00
Lars Knoll 2a4e835a7d Wrap members in Object in a Heap::Pointer
Change-Id: I0d132592487255027c215da21fbec15b23b00624
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
2015-03-20 11:16:50 +00:00
Lars Knoll feebac8e70 Move memory management related functionality into it's own folder
Start moving the memory related functionality into it's own folder.
This will simplify refactoring of the GC related functionality later
on.

Change-Id: I70ec6f512af7a7897625afb84d914c17572b0ccd
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
2015-03-02 16:34:16 +00:00
Jani Heikkinen c5796292ad Update copyright headers
Qt copyrights are now in The Qt Company, so we could update the source
code headers accordingly. In the same go we should also fix the links to
point to qt.io.

Change-Id: I61120571787870c0ed17066afb31779b1e6e30e9
Reviewed-by: Iikka Eklund <iikka.eklund@theqtcompany.com>
2015-02-12 10:28:11 +00:00
Lars Knoll 002a5d4303 Get rid of most uses of ValueRef
Instead pass a const Value & into the functions

With our new inheritance structure, we can get rid of ValueRef
and instead simply pass a pointer to a Value again. Pointers to
Values are safe to use again now, as they are now guaranteed to
be in a place where the GC knows about them.

Change-Id: I44c606fde764db3993b8128fd6fb781d3a298e53
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
2015-01-23 08:07:32 +01:00
Lars Knoll 630f118f04 Move the internalClass pointer into Heap::Object
The other classes that derive from Heap::Base don't need it
at all. So get rid of it there and save a pointer.

Change-Id: I9c5df2e43cd6eeac2e6e41f3d3b8077d3afbc8f2
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
2015-01-21 13:19:02 +01:00