summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2010-04-01 05:29:26 (GMT)
committerAaron Kennedy <aaron.kennedy@nokia.com>2010-04-01 05:29:26 (GMT)
commit8e87197c2afa19df1fb15cb9b6b3cc17c3d4c0d6 (patch)
tree691fe48f981f40f2d50790ceeb7d3719799d9b82
parentb1748ec7a9fdcd74fcf05af3903623c7165420ad (diff)
downloadQt-8e87197c2afa19df1fb15cb9b6b3cc17c3d4c0d6.zip
Qt-8e87197c2afa19df1fb15cb9b6b3cc17c3d4c0d6.tar.gz
Qt-8e87197c2afa19df1fb15cb9b6b3cc17c3d4c0d6.tar.bz2
Optimization: Improve allocation strategy for QDeclarativeDeclarativeData
This improves the declarative/creation/itemtree_qml benchmark by 6%
-rw-r--r--src/corelib/kernel/qobject.cpp8
-rw-r--r--src/corelib/kernel/qobject_p.h5
-rw-r--r--src/declarative/qml/qdeclarativecompiler.cpp45
-rw-r--r--src/declarative/qml/qdeclarativedeclarativedata_p.h8
-rw-r--r--src/declarative/qml/qdeclarativeengine.cpp14
-rw-r--r--src/declarative/qml/qdeclarativeinstruction.cpp2
-rw-r--r--src/declarative/qml/qdeclarativeinstruction_p.h7
-rw-r--r--src/declarative/qml/qdeclarativemetatype.cpp10
-rw-r--r--src/declarative/qml/qdeclarativemetatype_p.h4
-rw-r--r--src/declarative/qml/qdeclarativevme.cpp22
10 files changed, 101 insertions, 24 deletions
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index dbc6be2..dfd6a08 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -125,8 +125,10 @@ extern "C" Q_CORE_EXPORT void qt_removeObject(QObject *)
}
}
+void (*QDeclarativeData::destroyed)(QDeclarativeData *, QObject *) = 0;
+void (*QDeclarativeData::parentChanged)(QDeclarativeData *, QObject *, QObject *) = 0;
+
QObjectData::~QObjectData() {}
-QDeclarativeData::~QDeclarativeData() {}
QObjectPrivate::QObjectPrivate(int version)
: threadData(0), connectionLists(0), senders(0), currentSender(0), currentChildBeingDeleted(0)
@@ -876,7 +878,7 @@ QObject::~QObject()
}
if (d->declarativeData)
- d->declarativeData->destroyed(this);
+ QDeclarativeData::destroyed(d->declarativeData, this);
{
QMutex *signalSlotMutex = 0;
@@ -2025,7 +2027,7 @@ void QObjectPrivate::setParent_helper(QObject *o)
}
}
if (!wasDeleted && declarativeData)
- declarativeData->parentChanged(q, o);
+ QDeclarativeData::parentChanged(declarativeData, q, o);
}
/*!
diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h
index 3b59abb..e5d904c 100644
--- a/src/corelib/kernel/qobject_p.h
+++ b/src/corelib/kernel/qobject_p.h
@@ -87,9 +87,8 @@ enum { QObjectPrivateVersion = QT_VERSION };
class Q_CORE_EXPORT QDeclarativeData
{
public:
- virtual ~QDeclarativeData();
- virtual void destroyed(QObject *) = 0;
- virtual void parentChanged(QObject *, QObject *) = 0;
+ static void (*destroyed)(QDeclarativeData *, QObject *);
+ static void (*parentChanged)(QDeclarativeData *, QObject *, QObject *);
};
class Q_CORE_EXPORT QObjectPrivate : public QObjectData
diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp
index 56af5f5..27fecfb 100644
--- a/src/declarative/qml/qdeclarativecompiler.cpp
+++ b/src/declarative/qml/qdeclarativecompiler.cpp
@@ -881,23 +881,38 @@ void QDeclarativeCompiler::genObject(QDeclarativeParser::Object *obj)
}
// Create the object
- QDeclarativeInstruction create;
- create.type = QDeclarativeInstruction::CreateObject;
- create.line = obj->location.start.line;
- create.create.column = obj->location.start.column;
- create.create.data = -1;
- if (!obj->custom.isEmpty())
- create.create.data = output->indexForByteArray(obj->custom);
- create.create.type = obj->type;
- if (!output->types.at(create.create.type).type &&
- !obj->bindingBitmask.isEmpty()) {
- Q_ASSERT(obj->bindingBitmask.size() % 4 == 0);
- create.create.bindingBits =
- output->indexForByteArray(obj->bindingBitmask);
+ if (obj->custom.isEmpty() && output->types.at(obj->type).type &&
+ obj != compileState.root) {
+
+ QDeclarativeInstruction create;
+ create.type = QDeclarativeInstruction::CreateSimpleObject;
+ create.line = obj->location.start.line;
+ create.createSimple.create = output->types.at(obj->type).type->createFunction();
+ create.createSimple.typeSize = output->types.at(obj->type).type->createSize();
+ create.createSimple.column = obj->location.start.column;
+ output->bytecode << create;
+
} else {
- create.create.bindingBits = -1;
+
+ QDeclarativeInstruction create;
+ create.type = QDeclarativeInstruction::CreateObject;
+ create.line = obj->location.start.line;
+ create.create.column = obj->location.start.column;
+ create.create.data = -1;
+ if (!obj->custom.isEmpty())
+ create.create.data = output->indexForByteArray(obj->custom);
+ create.create.type = obj->type;
+ if (!output->types.at(create.create.type).type &&
+ !obj->bindingBitmask.isEmpty()) {
+ Q_ASSERT(obj->bindingBitmask.size() % 4 == 0);
+ create.create.bindingBits =
+ output->indexForByteArray(obj->bindingBitmask);
+ } else {
+ create.create.bindingBits = -1;
+ }
+ output->bytecode << create;
+
}
- output->bytecode << create;
// Setup the synthesized meta object if necessary
if (!obj->metadata.isEmpty()) {
diff --git a/src/declarative/qml/qdeclarativedeclarativedata_p.h b/src/declarative/qml/qdeclarativedeclarativedata_p.h
index d1d063a..dfc3113 100644
--- a/src/declarative/qml/qdeclarativedeclarativedata_p.h
+++ b/src/declarative/qml/qdeclarativedeclarativedata_p.h
@@ -64,6 +64,10 @@ class QDeclarativeAbstractBinding;
class QDeclarativeContext;
class QDeclarativePropertyCache;
class QDeclarativeContextData;
+// This class is structured in such a way, that simply zero'ing it is the
+// default state for elemental object allocations. This is crucial in the
+// workings of the QDeclarativeInstruction::CreateSimpleObject instruction.
+// Don't change anything here without first considering that case!
class Q_AUTOTEST_EXPORT QDeclarativeDeclarativeData : public QDeclarativeData
{
public:
@@ -73,8 +77,8 @@ public:
bindingBits(0), lineNumber(0), columnNumber(0), deferredComponent(0), deferredIdx(0),
attachedProperties(0), propertyCache(0), guards(0) {}
- virtual void destroyed(QObject *);
- virtual void parentChanged(QObject *, QObject *);
+ void destroyed(QObject *);
+ void parentChanged(QObject *, QObject *);
void setImplicitDestructible() {
if (!explicitIndestructibleSet) indestructible = false;
diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp
index 3e570e5..65dd72b 100644
--- a/src/declarative/qml/qdeclarativeengine.cpp
+++ b/src/declarative/qml/qdeclarativeengine.cpp
@@ -346,6 +346,17 @@ Q_GLOBAL_STATIC(QDeclarativeEngineDebugServer, qmlEngineDebugServer);
typedef QMap<QString, QString> StringStringMap;
Q_GLOBAL_STATIC(StringStringMap, qmlEnginePluginsWithRegisteredTypes); // stores the uri
+
+static void QDeclarativeDeclarativeData_destroyed(QDeclarativeData *d, QObject *o)
+{
+ static_cast<QDeclarativeDeclarativeData *>(d)->destroyed(o);
+}
+
+static void QDeclarativeDeclarativeData_parentChanged(QDeclarativeData *d, QObject *o, QObject *p)
+{
+ static_cast<QDeclarativeDeclarativeData *>(d)->parentChanged(o, p);
+}
+
void QDeclarativeEnginePrivate::init()
{
Q_Q(QDeclarativeEngine);
@@ -353,6 +364,9 @@ void QDeclarativeEnginePrivate::init()
qRegisterMetaType<QDeclarativeScriptString>("QDeclarativeScriptString");
qRegisterMetaType<QScriptValue>("QScriptValue");
+ QDeclarativeData::destroyed = QDeclarativeDeclarativeData_destroyed;
+ QDeclarativeData::parentChanged = QDeclarativeDeclarativeData_parentChanged;
+
contextClass = new QDeclarativeContextScriptClass(q);
objectClass = new QDeclarativeObjectScriptClass(q);
valueTypeClass = new QDeclarativeValueTypeScriptClass(q);
diff --git a/src/declarative/qml/qdeclarativeinstruction.cpp b/src/declarative/qml/qdeclarativeinstruction.cpp
index 9083ab3..36e5a2d 100644
--- a/src/declarative/qml/qdeclarativeinstruction.cpp
+++ b/src/declarative/qml/qdeclarativeinstruction.cpp
@@ -60,6 +60,8 @@ void QDeclarativeCompiledData::dump(QDeclarativeInstruction *instr, int idx)
break;
case QDeclarativeInstruction::CreateObject:
qWarning().nospace() << idx << "\t\t" << line << "\t" << "CREATE\t\t\t" << instr->create.type << "\t\t\t" << types.at(instr->create.type).className;
+ case QDeclarativeInstruction::CreateSimpleObject:
+ qWarning().nospace() << idx << "\t\t" << line << "\t" << "CREATE_SIMPLE\t\t" << instr->createSimple.typeSize;
break;
case QDeclarativeInstruction::SetId:
qWarning().nospace() << idx << "\t\t" << line << "\t" << "SETID\t\t\t" << instr->setId.value << "\t\t\t" << primitives.at(instr->setId.value);
diff --git a/src/declarative/qml/qdeclarativeinstruction_p.h b/src/declarative/qml/qdeclarativeinstruction_p.h
index 877179d..1f3c964 100644
--- a/src/declarative/qml/qdeclarativeinstruction_p.h
+++ b/src/declarative/qml/qdeclarativeinstruction_p.h
@@ -74,6 +74,7 @@ public:
// top of the stack.
Init, /* init */
CreateObject, /* create */
+ CreateSimpleObject, /* createSimple */
SetId, /* setId */
SetDefault,
CreateComponent, /* createComponent */
@@ -175,6 +176,11 @@ public:
int bindingBits;
ushort column;
};
+ struct CreateSimpleInstruction {
+ void (*create)(void *);
+ int typeSize;
+ ushort column;
+ };
struct StoreMetaInstruction {
int data;
int aliasData;
@@ -305,6 +311,7 @@ public:
union {
InitInstruction init;
CreateInstruction create;
+ CreateSimpleInstruction createSimple;
StoreMetaInstruction storeMeta;
SetIdInstruction setId;
AssignValueSourceInstruction assignValueSource;
diff --git a/src/declarative/qml/qdeclarativemetatype.cpp b/src/declarative/qml/qdeclarativemetatype.cpp
index c512d97..6f99f95 100644
--- a/src/declarative/qml/qdeclarativemetatype.cpp
+++ b/src/declarative/qml/qdeclarativemetatype.cpp
@@ -313,6 +313,16 @@ QDeclarativeCustomParser *QDeclarativeType::customParser() const
return d->m_customParser;
}
+QDeclarativeType::CreateFunc QDeclarativeType::createFunction() const
+{
+ return d->m_newFunc;
+}
+
+int QDeclarativeType::createSize() const
+{
+ return d->m_allocationSize;
+}
+
bool QDeclarativeType::isCreatable() const
{
return d->m_newFunc != 0;
diff --git a/src/declarative/qml/qdeclarativemetatype_p.h b/src/declarative/qml/qdeclarativemetatype_p.h
index b3ec5e3..96e3c74 100644
--- a/src/declarative/qml/qdeclarativemetatype_p.h
+++ b/src/declarative/qml/qdeclarativemetatype_p.h
@@ -115,6 +115,10 @@ public:
QObject *create() const;
void create(QObject **, void **, size_t) const;
+ typedef void (*CreateFunc)(void *);
+ CreateFunc createFunction() const;
+ int createSize() const;
+
QDeclarativeCustomParser *customParser() const;
bool isCreatable() const;
diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp
index 2338bc3..6498e6c 100644
--- a/src/declarative/qml/qdeclarativevme.cpp
+++ b/src/declarative/qml/qdeclarativevme.cpp
@@ -236,13 +236,33 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack,
}
} else {
QDeclarative_setParent_noEvent(o, parent);
- // o->setParent(parent);
}
}
stack.push(o);
}
break;
+ case QDeclarativeInstruction::CreateSimpleObject:
+ {
+ QObject *o = (QObject *)operator new(instr.createSimple.typeSize +
+ sizeof(QDeclarativeDeclarativeData));
+ ::bzero(o, instr.createSimple.typeSize + sizeof(QDeclarativeDeclarativeData));
+ instr.createSimple.create(o);
+
+ QDeclarativeDeclarativeData *ddata =
+ (QDeclarativeDeclarativeData *)(((const char *)o) + instr.createSimple.typeSize);
+ ddata->lineNumber = instr.line;
+ ddata->columnNumber = instr.createSimple.column;
+
+ QObjectPrivate::get(o)->declarativeData = ddata;
+ ctxt->addObject(o);
+ QObject *parent = stack.top();
+ QDeclarative_setParent_noEvent(o, parent);
+
+ stack.push(o);
+ }
+ break;
+
case QDeclarativeInstruction::SetId:
{
QObject *target = stack.top();