From cd148a1fd4959daac669581df35f91104fab7b8b Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Wed, 12 Sep 2018 20:08:54 +0200 Subject: Optimize Object::virtualGet() Optimize virtualGet() for the common case where the proto chain are all regular objects. Change-Id: I51eea9a4b96033be4effc2072fedc5b9b08e8440 Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4object.cpp | 51 ++++++++++++++++++++++++----------------- src/qml/jsruntime/qv4object_p.h | 7 +++++- 2 files changed, 36 insertions(+), 22 deletions(-) (limited to 'src/qml/jsruntime') diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp index ec6675adc0..e58b9d8168 100644 --- a/src/qml/jsruntime/qv4object.cpp +++ b/src/qml/jsruntime/qv4object.cpp @@ -94,7 +94,7 @@ void Heap::Object::setUsedAsProto() internalClass.set(internalClass->engine, internalClass->asProtoClass()); } -ReturnedValue Object::getValue(const Value &thisObject, const Value &v, PropertyAttributes attrs) +ReturnedValue Object::getValueAccessor(const Value &thisObject, const Value &v, PropertyAttributes attrs) { if (!attrs.isAccessor()) return v.asReturnedValue(); @@ -413,41 +413,50 @@ OwnPropertyKeyIterator *Object::virtualOwnPropertyKeys(const Object *o, Value *t // Section 8.12.3 ReturnedValue Object::internalGet(PropertyKey id, const Value *receiver, bool *hasProperty) const { + Heap::Object *o = d(); + uint index = id.asArrayIndex(); if (index != UINT_MAX) { Scope scope(this); PropertyAttributes attrs; - ScopedObject o(scope, this); ScopedProperty pd(scope); - if (o->arrayData() && o->arrayData()->getProperty(index, pd, &attrs)) { - if (hasProperty) - *hasProperty = true; - return Object::getValue(*receiver, pd->value, attrs); - } - if (o->isStringObject()) { - ScopedString str(scope, static_cast(o.getPointer())->getIndex(index)); - if (str) { - attrs = (Attr_NotWritable|Attr_NotConfigurable); + while (1) { + if (o->arrayData && o->arrayData->getProperty(index, pd, &attrs)) { if (hasProperty) *hasProperty = true; - return str.asReturnedValue(); + return Object::getValue(*receiver, pd->value, attrs); + } + if (o->internalClass->vtable->type == Type_StringObject) { + ScopedString str(scope, static_cast(o)->getIndex(index)); + if (str) { + attrs = (Attr_NotWritable|Attr_NotConfigurable); + if (hasProperty) + *hasProperty = true; + return str.asReturnedValue(); + } } + o = o->prototype(); + if (!o || o->internalClass->vtable->get != Object::virtualGet) + break; } } else { - Heap::Object *o = d(); Q_ASSERT(!id.isArrayIndex()); - uint idx = o->internalClass->find(id); - if (idx < UINT_MAX) { - if (hasProperty) - *hasProperty = true; - return Object::getValue(*receiver, *o->propertyData(idx), o->internalClass->propertyData.at(idx)); + while (1) { + uint idx = o->internalClass->find(id); + if (idx < UINT_MAX) { + if (hasProperty) + *hasProperty = true; + return Object::getValue(*receiver, *o->propertyData(idx), o->internalClass->propertyData.at(idx)); + } + o = o->prototype(); + if (!o || o->internalClass->vtable->get != Object::virtualGet) + break; } } - Heap::Object *p = d()->prototype(); - if (p) { - const Value v = Primitive::fromHeapObject(p); + if (o) { + const Value v = Primitive::fromHeapObject(o); const Object &obj = static_cast(v); return obj.get(id, receiver, hasProperty); } diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h index 41484660ab..991c0591a5 100644 --- a/src/qml/jsruntime/qv4object_p.h +++ b/src/qml/jsruntime/qv4object_p.h @@ -185,12 +185,17 @@ struct Q_QML_EXPORT Object: Managed { // // helpers // - static ReturnedValue getValue(const Value &thisObject, const Value &v, PropertyAttributes attrs); + static ReturnedValue getValue(const Value &thisObject, const Value &v, PropertyAttributes attrs) { + if (attrs.isData()) + return v.asReturnedValue(); + return getValueAccessor(thisObject, v, attrs); + } ReturnedValue getValue(const Value &v, PropertyAttributes attrs) const { Scope scope(this->engine()); ScopedValue t(scope, const_cast(this)); return getValue(t, v, attrs); } + static ReturnedValue getValueAccessor(const Value &thisObject, const Value &v, PropertyAttributes attrs); bool putValue(uint memberIndex, const Value &value); -- cgit v1.2.3