Optimise array access

Optimise accessing indexed properties in Objects and
Arrays

Change-Id: I3330a4151a13e8f34fee1c4641e64d00a52625e2
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
This commit is contained in:
Lars Knoll 2013-01-18 13:48:03 +01:00 committed by Simon Hausmann
parent 5ed9321942
commit 403ddb70fb
3 changed files with 32 additions and 10 deletions

View 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);

View 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;
}

View 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)