aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmlobjectcreator.cpp
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@digia.com>2014-04-02 12:02:14 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-04-03 13:59:37 +0200
commitef2e5a39fa188c0fb229e7847b5ac3f177ba778e (patch)
tree0ceb8415472c281b5a6c88cd4b3ddf84945606ee /src/qml/qml/qqmlobjectcreator.cpp
parentcf06b028f71fb80616be7fbb3ef3aaf7d5474eca (diff)
Use RAII for VME profiler
Now that object creation is done in nested function calls we can use an RAII-type profiler to trace it. This makes the profiling much simpler and more robust. Also, the stack of profiling data in the VME profiler has to match the stack of completion callbacks in the VME, so the push and pop operations are synchronized now. Task-number: QTBUG-37978 Change-Id: I1bc5e0665b88e5b3772e48c8676cdda3fae59e1b Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src/qml/qml/qqmlobjectcreator.cpp')
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp35
1 files changed, 17 insertions, 18 deletions
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index d0c635b007..2ebf90c9be 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -98,7 +98,10 @@ QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, QQmlCompile
sharedState->allCreatedObjects.allocate(compiledData->totalObjectCount);
sharedState->creationContext = creationContext;
sharedState->rootContext = 0;
- sharedState->profiler.profiler = QQmlEnginePrivate::get(engine)->profiler;
+
+ QQmlProfiler *profiler = QQmlEnginePrivate::get(engine)->profiler;
+ Q_QML_PROFILE_IF_ENABLED(profiler,
+ sharedState->profiler.init(profiler, compiledData->totalParserStatusCount));
}
QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, QQmlCompiledData *compiledData, QQmlObjectCreatorSharedState *inheritedSharedState)
@@ -223,8 +226,6 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI
ddata->compiledData->addref();
}
- Q_QML_VME_PROFILE(sharedState->profiler, stop());
-
phase = CreatingObjectsPhase2;
if (interrupt && interrupt->shouldInterrupt())
@@ -1014,6 +1015,7 @@ void QQmlObjectCreator::recordError(const QV4::CompiledData::Location &location,
QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isContextObject)
{
+ QQmlObjectCreationProfiler profiler(sharedState->profiler.profiler);
ActiveOCRestorer ocRestorer(this, QQmlEnginePrivate::get(engine));
bool isComponent = false;
@@ -1023,21 +1025,23 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
QQmlParserStatus *parserStatus = 0;
bool installPropertyCache = true;
+ const QV4::CompiledData::Object *obj = qmlUnit->objectAt(index);
if (compiledData->isComponent(index)) {
isComponent = true;
QQmlComponent *component = new QQmlComponent(engine, compiledData, index, parent);
+ Q_QML_OC_PROFILE(sharedState->profiler, profiler.update(QStringLiteral("<component>"),
+ context->url, obj->location.line, obj->location.column));
QQmlComponentPrivate::get(component)->creationContext = context;
instance = component;
ddata = QQmlData::get(instance, /*create*/true);
} else {
- const QV4::CompiledData::Object *obj = qmlUnit->objectAt(index);
-
QQmlCompiledData::TypeReference *typeRef = resolvedTypes.value(obj->inheritedTypeNameIndex);
Q_ASSERT(typeRef);
installPropertyCache = !typeRef->isFullyDynamicType;
QQmlType *type = typeRef->type;
if (type) {
- Q_QML_VME_PROFILE(sharedState->profiler, start(type->qmlTypeName(), context->url, obj->location.line, obj->location.column));
+ Q_QML_OC_PROFILE(sharedState->profiler, profiler.update(type->qmlTypeName(),
+ context->url, obj->location.line, obj->location.column));
instance = type->create();
if (!instance) {
recordError(obj->location, tr("Unable to create object of type %1").arg(stringAt(obj->inheritedTypeNameIndex)));
@@ -1059,15 +1063,16 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
sharedState->allCreatedObjects.push(instance);
} else {
Q_ASSERT(typeRef->component);
+ Q_QML_OC_PROFILE(sharedState->profiler, profiler.update(typeRef->component->name,
+ context->url, obj->location.line, obj->location.column));
if (typeRef->component->qmlUnit->isSingleton())
{
recordError(obj->location, tr("Composite Singleton Type %1 is not creatable").arg(stringAt(obj->inheritedTypeNameIndex)));
return 0;
}
- Q_QML_VME_PROFILE(sharedState->profiler, startBackground(typeRef->component->name));
+
QQmlObjectCreator subCreator(context, typeRef->component, sharedState.data());
instance = subCreator.create();
- Q_QML_VME_PROFILE(sharedState->profiler, foreground(context->url, obj->location.line, obj->location.column));
if (!instance) {
errors += subCreator.errors;
return 0;
@@ -1100,6 +1105,9 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
if (parserStatus) {
parserStatus->classBegin();
+ // push() the profiler state here, together with the parserStatus, as we'll pop() them
+ // together, too.
+ Q_QML_OC_PROFILE(sharedState->profiler, sharedState->profiler.push(profiler));
sharedState->allParserStatusCallbacks.push(parserStatus);
parserStatus->d = &sharedState->allParserStatusCallbacks.top();
}
@@ -1186,7 +1194,7 @@ QQmlContextData *QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interru
if (QQmlVME::componentCompleteEnabled()) { // the qml designer does the component complete later
QQmlTrace trace("VME Component Complete");
while (!sharedState->allParserStatusCallbacks.isEmpty()) {
- Q_QML_VME_PROFILE(sharedState->profiler, pop());
+ QQmlObjectCompletionProfiler profiler(&sharedState->profiler);
QQmlParserStatus *status = sharedState->allParserStatusCallbacks.pop();
if (status && status->d) {
@@ -1197,7 +1205,6 @@ QQmlContextData *QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interru
if (watcher.hasRecursed() || interrupt.shouldInterrupt())
return 0;
}
- Q_QML_VME_PROFILE(sharedState->profiler, clear());
}
{
@@ -1246,20 +1253,12 @@ void QQmlObjectCreator::clear()
while (!sharedState->allCreatedObjects.isEmpty())
delete sharedState->allCreatedObjects.pop();
- // If profiling is switched off during a VME run and then switched back on
- // before or during the next run background ranges from the first run will
- // be reported in the second run because we don't clear() here. We accept
- // that as the collected data will be incomplete anyway and because not
- // calling clear() here is benefitial for the non-profiling case.
- Q_QML_VME_PROFILE(sharedState->profiler, clear(true));
-
phase = Done;
}
bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject *bindingTarget, QQmlPropertyData *valueTypeProperty, const QBitArray &bindingsToSkip)
{
const QV4::CompiledData::Object *obj = qmlUnit->objectAt(index);
- Q_QML_VME_PROFILE(sharedState->profiler, push());
QQmlData *declarativeData = QQmlData::get(instance, /*create*/true);