Optimise array access
authorLars Knoll <lars.knoll@digia.com>
Fri, 18 Jan 2013 12:48:03 +0000 (13:48 +0100)
committerSimon Hausmann <simon.hausmann@digia.com>
Fri, 18 Jan 2013 19:09:47 +0000 (20:09 +0100)
Optimise accessing indexed properties in Objects and
Arrays

Change-Id: I3330a4151a13e8f34fee1c4641e64d00a52625e2
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
qmljs_objects.cpp
qmljs_runtime.cpp
qv4array.h

index 0236d3c..c57355d 100644 (file)
@@ -280,7 +280,8 @@ Value Object::__get__(ExecutionContext *ctx, String *name, bool *hasProperty)
 
 Value Object::__get__(ExecutionContext *ctx, uint index, bool *hasProperty)
 {
-    if (const PropertyDescriptor *p = __getPropertyDescriptor__(ctx, index)) {
+    const PropertyDescriptor *p = __getPropertyDescriptor__(ctx, index);
+    if (p && p->type != PropertyDescriptor::Generic) {
         if (hasProperty)
             *hasProperty = true;
         return getValue(ctx, p);
index d7829e3..58e6cdb 100644 (file)
@@ -575,23 +575,30 @@ void __qmljs_set_property(ExecutionContext *ctx, Value object, String *name, Val
 
 Value __qmljs_get_element(ExecutionContext *ctx, Value object, Value index)
 {
+    uint type = object.type();
     uint idx = index.asArrayIndex();
 
-    if (object.isString() && idx < UINT_MAX) {
-        String *str = object.stringValue();
-        if (idx >= (uint)str->toQString().length())
-            return Value::undefinedValue();
-        const QString s = str->toQString().mid(idx, 1);
-        return Value::fromString(ctx, s);
-    }
+    if (type != Value::Object_Type) {
+        if (type == Value::String_Type) {
+            String *str = object.stringValue();
+            if (idx >= (uint)str->toQString().length())
+                return Value::undefinedValue();
+            const QString s = str->toQString().mid(idx, 1);
+            return Value::fromString(ctx, s);
+        }
 
-    if (!object.isObject())
         object = __qmljs_to_object(object, ctx);
+    }
 
     Object *o = object.objectValue();
 
-    if (idx < UINT_MAX)
+    if (idx < UINT_MAX) {
+        const PropertyDescriptor *p = o->array.nonSparseAt(idx);
+        if (p && p->type == PropertyDescriptor::Data)
+            return p->value;
+
         return o->__get__(ctx, idx);
+    }
 
     String *name = index.toString(ctx);
     return o->__get__(ctx, name);
@@ -606,6 +613,11 @@ void __qmljs_set_element(ExecutionContext *ctx, Value object, Value index, Value
 
     uint idx = index.asArrayIndex();
     if (idx < UINT_MAX) {
+        PropertyDescriptor *p = o->array.nonSparseAtRef(idx);
+        if (p && p->type == PropertyDescriptor::Data && p->isWritable()) {
+            p->value = value;
+            return;
+        }
         o->__put__(ctx, idx, value);
         return;
     }
index b33163c..d055923 100644 (file)
@@ -521,6 +521,15 @@ public:
         return values.constData() + index;
     }
 
+    PropertyDescriptor *nonSparseAtRef(uint index) {
+        if (sparse)
+            return 0;
+        index += offset;
+        if (index >= (uint)values.size())
+            return 0;
+        return values.data() + index;
+    }
+
     const PropertyDescriptor *at(uint index) const {
         if (!sparse) {
             if (index >= values.size() - offset)