aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2016-12-09 14:46:49 +0100
committerLars Knoll <lars.knoll@qt.io>2016-12-10 11:07:02 +0000
commit8c322d89ee13f15141f3115dcb5ee9567270ba32 (patch)
treebdadf23e2b0c7b9e7b23d579ea8858de8b954d4d /src
parentd3bff5843b14a4e0640fb7429b0d8685d5d25b46 (diff)
Some smaller optimizations for indexed property access
Saves around 1% of instructions on crypto.js Change-Id: Iccef08b204e6e752d827242baf156efd9a4d58a7 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/qml/jsruntime/qv4lookup.cpp55
-rw-r--r--src/qml/jsruntime/qv4value_p.h15
2 files changed, 47 insertions, 23 deletions
diff --git a/src/qml/jsruntime/qv4lookup.cpp b/src/qml/jsruntime/qv4lookup.cpp
index 0b0b2685b3..8d322e69d1 100644
--- a/src/qml/jsruntime/qv4lookup.cpp
+++ b/src/qml/jsruntime/qv4lookup.cpp
@@ -118,7 +118,8 @@ ReturnedValue Lookup::lookup(const Object *thisObject, PropertyAttributes *attrs
ReturnedValue Lookup::indexedGetterGeneric(Lookup *l, const Value &object, const Value &index)
{
- if (object.isObject() && index.asArrayIndex() < UINT_MAX) {
+ uint idx;
+ if (object.isObject() && index.asArrayIndex(idx)) {
l->indexedGetter = indexedGetterObjectInt;
return indexedGetterObjectInt(l, object, index);
}
@@ -129,11 +130,12 @@ ReturnedValue Lookup::indexedGetterFallback(Lookup *l, const Value &object, cons
{
Q_UNUSED(l);
Scope scope(l->engine);
- uint idx = index.asArrayIndex();
+ uint idx;
+ bool isInt = index.asArrayIndex(idx);
ScopedObject o(scope, object);
if (!o) {
- if (idx < UINT_MAX) {
+ if (isInt) {
if (const String *str = object.as<String>()) {
if (idx >= (uint)str->toQString().length()) {
return Encode::undefined();
@@ -153,7 +155,7 @@ ReturnedValue Lookup::indexedGetterFallback(Lookup *l, const Value &object, cons
return Encode::undefined();
}
- if (idx < UINT_MAX) {
+ if (isInt) {
if (o->d()->arrayData && !o->d()->arrayData->attrs) {
ScopedValue v(scope, Scoped<ArrayData>(scope, o->arrayData())->get(idx));
if (!v->isEmpty())
@@ -173,14 +175,17 @@ ReturnedValue Lookup::indexedGetterFallback(Lookup *l, const Value &object, cons
ReturnedValue Lookup::indexedGetterObjectInt(Lookup *l, const Value &object, const Value &index)
{
- uint idx = index.asArrayIndex();
- if (idx != UINT_MAX) {
- if (Object *o = object.objectValue()) {
- if (o->d()->arrayData && o->d()->arrayData->type == Heap::ArrayData::Simple) {
- Heap::SimpleArrayData *s = o->d()->arrayData.cast<Heap::SimpleArrayData>();
- if (idx < s->len)
- if (!s->data(idx).isEmpty())
- return s->data(idx).asReturnedValue();
+ uint idx;
+ if (index.asArrayIndex(idx)) {
+ if (Heap::Base *b = object.heapObject()) {
+ if (b->vtable()->isObject) {
+ Heap::Object *o = static_cast<Heap::Object *>(b);
+ if (o->arrayData && o->arrayData->type == Heap::ArrayData::Simple) {
+ Heap::SimpleArrayData *s = o->arrayData.cast<Heap::SimpleArrayData>();
+ if (idx < s->len)
+ if (!s->data(idx).isEmpty())
+ return s->data(idx).asReturnedValue();
+ }
}
}
}
@@ -191,7 +196,8 @@ ReturnedValue Lookup::indexedGetterObjectInt(Lookup *l, const Value &object, con
void Lookup::indexedSetterGeneric(Lookup *l, const Value &object, const Value &index, const Value &v)
{
if (Object *o = object.objectValue()) {
- if (o->d()->arrayData && o->d()->arrayData->type == Heap::ArrayData::Simple && index.asArrayIndex() < UINT_MAX) {
+ uint idx;
+ if (o->d()->arrayData && o->d()->arrayData->type == Heap::ArrayData::Simple && index.asArrayIndex(idx)) {
l->indexedSetter = indexedSetterObjectInt;
indexedSetterObjectInt(l, object, index, v);
return;
@@ -207,8 +213,8 @@ void Lookup::indexedSetterFallback(Lookup *l, const Value &object, const Value &
if (scope.engine->hasException)
return;
- uint idx = index.asArrayIndex();
- if (idx < UINT_MAX) {
+ uint idx;
+ if (index.asArrayIndex(idx)) {
if (o->d()->arrayData && o->d()->arrayData->type == Heap::ArrayData::Simple) {
Heap::SimpleArrayData *s = o->d()->arrayData.cast<Heap::SimpleArrayData>();
if (idx < s->len) {
@@ -226,14 +232,17 @@ void Lookup::indexedSetterFallback(Lookup *l, const Value &object, const Value &
void Lookup::indexedSetterObjectInt(Lookup *l, const Value &object, const Value &index, const Value &v)
{
- uint idx = index.asArrayIndex();
- if (idx != UINT_MAX) {
- if (Object *o = object.objectValue()) {
- if (o->d()->arrayData && o->d()->arrayData->type == Heap::ArrayData::Simple) {
- Heap::SimpleArrayData *s = o->d()->arrayData.cast<Heap::SimpleArrayData>();
- if (idx < s->len) {
- s->data(idx) = v;
- return;
+ uint idx;
+ if (index.asArrayIndex(idx)) {
+ if (Heap::Base *b = object.heapObject()) {
+ if (b->vtable()->isObject) {
+ Heap::Object *o = static_cast<Heap::Object *>(b);
+ if (o->arrayData && o->arrayData->type == Heap::ArrayData::Simple) {
+ Heap::SimpleArrayData *s = o->arrayData.cast<Heap::SimpleArrayData>();
+ if (idx < s->len) {
+ s->data(idx) = v;
+ return;
+ }
}
}
}
diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h
index e59ab9af0b..816b8fb11b 100644
--- a/src/qml/jsruntime/qv4value_p.h
+++ b/src/qml/jsruntime/qv4value_p.h
@@ -453,6 +453,7 @@ public:
}
inline uint asArrayIndex() const;
+ inline bool asArrayIndex(uint &idx) const;
#ifndef V4_BOOTSTRAP
uint asArrayLength(bool *ok) const;
#endif
@@ -531,6 +532,20 @@ inline uint Value::asArrayIndex() const
return UINT_MAX;
return idx;
}
+
+inline bool Value::asArrayIndex(uint &idx) const
+{
+ if (!isDouble()) {
+ if (isInteger() && int_32() >= 0) {
+ idx = (uint)int_32();
+ return true;
+ }
+ return false;
+ }
+ double d = doubleValue();
+ idx = (uint)d;
+ return (idx == d);
+}
#endif
inline