aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2011-11-30 17:54:03 +0000
committerQt by Nokia <qt-info@nokia.com>2011-12-01 18:55:39 +0100
commit8fd12405b9976ca4c9dec6cf53ccde24bfa76dd7 (patch)
tree12dd5dfbad6e20a515fc557e2a83a1ef111ca828
parent32115087589939225a4516ed15196a4f6632c13b (diff)
Improve value type read performance
On x86, this gives ~3x improvement in property read time. Change-Id: I8f75e9bb7450bc56ca42f8258c3a5641bc9c18d3 Reviewed-by: Chris Adams <christopher.adams@nokia.com>
-rw-r--r--src/declarative/qml/v8/qv8valuetypewrapper.cpp58
-rw-r--r--src/declarative/qml/v8/qv8valuetypewrapper_p.h3
2 files changed, 48 insertions, 13 deletions
diff --git a/src/declarative/qml/v8/qv8valuetypewrapper.cpp b/src/declarative/qml/v8/qv8valuetypewrapper.cpp
index 2c46b77823..aca0c85ace 100644
--- a/src/declarative/qml/v8/qv8valuetypewrapper.cpp
+++ b/src/declarative/qml/v8/qv8valuetypewrapper.cpp
@@ -105,8 +105,11 @@ void QV8ValueTypeWrapper::destroy()
{
qPersistentDispose(m_toString);
qPersistentDispose(m_constructor);
+ qPersistentDispose(m_toStringSymbol);
}
+static quint32 toStringHash = -1;
+
void QV8ValueTypeWrapper::init(QV8Engine *engine)
{
m_engine = engine;
@@ -119,6 +122,10 @@ void QV8ValueTypeWrapper::init(QV8Engine *engine)
m_toString, v8::DEFAULT,
v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete));
m_constructor = qPersistentNew<v8::Function>(ft->GetFunction());
+
+ m_toStringSymbol = qPersistentNew<v8::String>(v8::String::NewSymbol("toString"));
+ m_toStringString = QHashedV8String(m_toStringSymbol);
+ toStringHash = m_toStringString.hash();
}
v8::Local<v8::Object> QV8ValueTypeWrapper::newValueType(QObject *object, int property, QDeclarativeValueType *type)
@@ -231,19 +238,30 @@ v8::Handle<v8::Value> QV8ValueTypeWrapper::Getter(v8::Local<v8::String> property
QV8ValueTypeResource *r = v8_resource_cast<QV8ValueTypeResource>(info.This());
if (!r) return v8::Handle<v8::Value>();
- // XXX This is horribly inefficient. Sadly people seem to have taken a liking to
- // value type properties, so we should probably try and optimize it a little.
- // We should probably just replace all value properties with dedicated accessors.
+ QHashedV8String propertystring(property);
- QByteArray propName = r->engine->toString(property).toUtf8();
- if (propName == QByteArray("toString")) {
- return r->engine->valueTypeWrapper()->m_toString;
+ {
+ // Comparing the hash first actually makes a measurable difference here, at least on x86
+ quint32 hash = propertystring.hash();
+ if (hash == toStringHash &&
+ r->engine->valueTypeWrapper()->m_toStringString == propertystring) {
+ return r->engine->valueTypeWrapper()->m_toString;
+ }
}
- int index = r->type->metaObject()->indexOfProperty(propName.constData());
- if (index == -1)
- return v8::Handle<v8::Value>();
+ QDeclarativePropertyData local;
+ QDeclarativePropertyData *result = 0;
+ {
+ QDeclarativeData *ddata = QDeclarativeData::get(r->type, false);
+ if (ddata && ddata->propertyCache)
+ result = ddata->propertyCache->property(propertystring);
+ else
+ result = QDeclarativePropertyCache::property(r->engine->engine(), r->type,
+ propertystring, local);
+ }
+ if (!result)
+ return v8::Handle<v8::Value>();
if (r->objectType == QV8ValueTypeResource::Reference) {
QV8ValueTypeReferenceResource *reference = static_cast<QV8ValueTypeReferenceResource *>(r);
@@ -251,7 +269,6 @@ v8::Handle<v8::Value> QV8ValueTypeWrapper::Getter(v8::Local<v8::String> property
if (!reference->object)
return v8::Handle<v8::Value>();
-
r->type->read(reference->object, reference->property);
} else {
Q_ASSERT(r->objectType == QV8ValueTypeResource::Copy);
@@ -261,10 +278,25 @@ v8::Handle<v8::Value> QV8ValueTypeWrapper::Getter(v8::Local<v8::String> property
r->type->setValue(copy->value);
}
- QMetaProperty prop = r->type->metaObject()->property(index);
- QVariant result = prop.read(r->type);
+#define VALUE_TYPE_LOAD(metatype, cpptype, constructor) \
+ if (result->propType == metatype) { \
+ cpptype v; \
+ void *args[] = { &v, 0 }; \
+ r->type->qt_metacall(QMetaObject::ReadProperty, result->coreIndex, args); \
+ return constructor(v); \
+ }
- return r->engine->fromVariant(result);
+ // These four types are the most common used by the value type wrappers
+ VALUE_TYPE_LOAD(QMetaType::QReal, qreal, v8::Number::New);
+ VALUE_TYPE_LOAD(QMetaType::Int, int, v8::Integer::New);
+ VALUE_TYPE_LOAD(QMetaType::QString, QString, r->engine->toString);
+ VALUE_TYPE_LOAD(QMetaType::Bool, bool, v8::Boolean::New);
+
+ QVariant v(result->propType, (void *)0);
+ void *args[] = { v.data(), 0 };
+ r->type->qt_metacall(QMetaObject::ReadProperty, result->coreIndex, args);
+ return r->engine->fromVariant(v);
+#undef VALUE_TYPE_ACCESSOR
}
v8::Handle<v8::Value> QV8ValueTypeWrapper::Setter(v8::Local<v8::String> property,
diff --git a/src/declarative/qml/v8/qv8valuetypewrapper_p.h b/src/declarative/qml/v8/qv8valuetypewrapper_p.h
index 2582560c0f..ce8944efb5 100644
--- a/src/declarative/qml/v8/qv8valuetypewrapper_p.h
+++ b/src/declarative/qml/v8/qv8valuetypewrapper_p.h
@@ -56,6 +56,7 @@
#include <QtCore/qglobal.h>
#include <QtDeclarative/qdeclarativelist.h>
#include <private/qv8_p.h>
+#include <private/qhashedstring_p.h>
QT_BEGIN_NAMESPACE
@@ -92,6 +93,8 @@ private:
QV8Engine *m_engine;
v8::Persistent<v8::Function> m_constructor;
v8::Persistent<v8::Function> m_toString;
+ v8::Persistent<v8::String> m_toStringSymbol;
+ QHashedV8String m_toStringString;
};
QT_END_NAMESPACE