diff options
author | Ulf Hermann <ulf.hermann@digia.com> | 2014-04-02 12:02:14 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-04-03 13:59:37 +0200 |
commit | ef2e5a39fa188c0fb229e7847b5ac3f177ba778e (patch) | |
tree | 0ceb8415472c281b5a6c88cd4b3ddf84945606ee /src/qml/qml/qqmlobjectcreator.cpp | |
parent | cf06b028f71fb80616be7fbb3ef3aaf7d5474eca (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.cpp | 35 |
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); |