aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/compiler/qqmltypecompiler.cpp1
-rw-r--r--src/qml/debugger/qqmlprofiler.cpp55
-rw-r--r--src/qml/debugger/qqmlprofiler_p.h140
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp35
4 files changed, 80 insertions, 151 deletions
diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp
index b44d4e285a..087f8df8a5 100644
--- a/src/qml/compiler/qqmltypecompiler.cpp
+++ b/src/qml/compiler/qqmltypecompiler.cpp
@@ -1408,6 +1408,7 @@ void QQmlComponentAndAliasResolver::findAndRegisterImplicitComponents(const QmlI
QmlIR::Object *syntheticComponent = pool->New<QmlIR::Object>();
syntheticComponent->init(pool, compiler->registerString(QString::fromUtf8(componentType->typeName())), compiler->registerString(QString()));
+ syntheticComponent->location = binding->valueLocation;
if (!resolvedTypes->contains(syntheticComponent->inheritedTypeNameIndex)) {
QQmlCompiledData::TypeReference *typeRef = new QQmlCompiledData::TypeReference;
diff --git a/src/qml/debugger/qqmlprofiler.cpp b/src/qml/debugger/qqmlprofiler.cpp
index a0b39744a0..99446e945e 100644
--- a/src/qml/debugger/qqmlprofiler.cpp
+++ b/src/qml/debugger/qqmlprofiler.cpp
@@ -147,59 +147,4 @@ void QQmlProfiler::reportData()
emit dataReady(result);
}
-/*!
- * \fn void QQmlVmeProfiler::Data::clear()
- * Resets the profiling data to defaults.
- */
-
-/*!
- * \fn bool QQmlVmeProfiler::startBackground(const QString &typeName)
- * If profiling is enabled clears the current range data, then stops the
- * profiler previously running in the foreground if any, then starts a new one
- * in the background, setting the given typeName. \a typeName is the type of
- * object being created.
- */
-
-/*!
- * \fn bool QQmlVmeProfiler::start(const QString &typeName, const QUrl &url, int line, int column)
- * If profiling is enabled clears the current range data, then stops the
- * profiler previously running in the foreground if any, then starts a new one
- * in the foreground, setting the given location. \a url is the URL of
- * file being executed, \a line is the current line in in that file, and
- * \a column is the current column in that file.
- */
-
-/*!
- * \fn bool QQmlVmeProfiler::pop()
- * Stops the currently running profiler, if any, then retrieves an old one from the stack
- * of paused profilers and starts that if possible.
- */
-
-/*!
- * \fn void QQmlVmeProfiler::push()
- * Pushes the currently running profiler on the stack of paused profilers. Note: The profiler
- * isn't paused here. That's a separate step. If it's never paused, but pop()'ed later that
- * won't do any harm, though.
- */
-
-/*!
- * \fn void QQmlVmeProfiler::clear(bool stopProfiling = false)
- * Stops the currently running (foreground and background) profilers and removes all saved
- * data about paused profilers.
- */
-
-/*!
- * \fn void QQmlVmeProfiler::stop()
- * Stop profiler running in the foreground, if any.
- */
-
-/*!
- * \fn bool QQmlVmeProfiler::foreground(const QUrl &url, int line, int column)
- * Stops the profiler currently running in the foreground, if any and puts the
- * next profiler from the background in its place if there are any profilers in
- * the background. Additionally the rangeLocation is set. \a url is the URL of
- * file being executed, \a line is the current line in in that file, and
- * \a column is the current column in that file.
- */
-
QT_END_NAMESPACE
diff --git a/src/qml/debugger/qqmlprofiler_p.h b/src/qml/debugger/qqmlprofiler_p.h
index 6afdc1e73b..84001905ab 100644
--- a/src/qml/debugger/qqmlprofiler_p.h
+++ b/src/qml/debugger/qqmlprofiler_p.h
@@ -55,6 +55,7 @@
#include <private/qv4function_p.h>
#include <private/qqmlboundsignal_p.h>
+#include <private/qfinitestack_p.h>
#include "qqmlprofilerdefinitions_p.h"
#include "qqmlabstractprofileradapter_p.h"
@@ -142,6 +143,11 @@ public:
location.sourceFile, location.line, location.column));
}
+ void startCreating()
+ {
+ m_data.append(QQmlProfilerData(m_timer.nsecsElapsed(), 1 << RangeStart, 1 << Creating));
+ }
+
void startCreating(const QString &typeName, const QUrl &fileName, int line, int column)
{
m_data.append(QQmlProfilerData(m_timer.nsecsElapsed(),
@@ -149,16 +155,11 @@ public:
1 << Creating, typeName, fileName, line, column));
}
- void startCreating(const QString &typeName)
- {
- m_data.append(QQmlProfilerData(m_timer.nsecsElapsed(), (1 << RangeStart | 1 << RangeData),
- 1 << Creating, typeName));
- }
-
- void creatingLocation(const QUrl &fileName, int line, int column)
+ void updateCreating(const QString &typeName, const QUrl &fileName, int line, int column)
{
- m_data.append(QQmlProfilerData(m_timer.nsecsElapsed(), 1 << RangeLocation, 1 << Creating,
- fileName, line, column));
+ m_data.append(QQmlProfilerData(m_timer.nsecsElapsed(),
+ (1 << RangeLocation | 1 << RangeData),
+ 1 << Creating, typeName, fileName, line, column));
}
template<RangeType Range>
@@ -246,108 +247,91 @@ struct QQmlCompilingProfiler : public QQmlProfilerHelper {
}
};
-#define Q_QML_VME_PROFILE(profilerMember, Method) Q_QML_PROFILE_IF_ENABLED(profilerMember.profiler, profilerMember.Method)
-
struct QQmlVmeProfiler : public QQmlProfilerDefinitions {
public:
struct Data {
- Data() : line(0), column(0) {}
- QUrl url;
- int line;
- int column;
- QString typeName;
+ Data() : m_line(0), m_column(0) {}
+ QUrl m_url;
+ int m_line;
+ int m_column;
+ QString m_typeName;
};
- QQmlVmeProfiler() : profiler(0), running(false) {}
+ QQmlVmeProfiler() : profiler(0) {}
- void clear(bool stopProfiling = false)
+ void init(QQmlProfiler *p, int maxDepth)
{
- ranges.clear();
- if (running)
- profiler->endRange<Creating>();
- for (int i = 0; i < backgroundRanges.count(); ++i) {
- profiler->endRange<Creating>();
- }
- backgroundRanges.clear();
- running = false;
- if (stopProfiling) profiler = 0;
+ profiler = p;
+ ranges.allocate(maxDepth);
}
- void startBackground(const QString &typeName)
+ Data pop()
{
- if (running) {
- profiler->endRange<Creating>();
- running = false;
- }
- profiler->startCreating(typeName);
- backgroundRanges.push(typeName);
+ if (ranges.count() > 0)
+ return ranges.pop();
+ else
+ return Data();
}
- void start(const QString &typeName, const QUrl &url, int line, int column)
+ void push(const Data &data)
{
- switchRange();
- setCurrentRange(typeName, url, line, column);
- profiler->startCreating(typeName, url, line, column);
+ if (ranges.capacity() > ranges.count())
+ ranges.push(data);
}
- void stop()
- {
- if (running) {
- profiler->endRange<Creating>();
- running = false;
- }
- }
+ QQmlProfiler *profiler;
- void pop()
+private:
+ QFiniteStack<Data> ranges;
+};
+
+#define Q_QML_OC_PROFILE(profilerMember, Code)\
+ Q_QML_PROFILE_IF_ENABLED(profilerMember.profiler, Code)
+
+class QQmlObjectCreationProfiler : public QQmlVmeProfiler::Data {
+public:
+
+ QQmlObjectCreationProfiler(QQmlProfiler *profiler) : profiler(profiler)
{
- if (ranges.count() > 0) {
- switchRange();
- currentRange = ranges.pop();
- profiler->startCreating(currentRange.typeName, currentRange.url,
- currentRange.line, currentRange.column);
- }
+ Q_QML_PROFILE(profiler, startCreating());
}
- void push()
+ ~QQmlObjectCreationProfiler()
{
- if (running)
- ranges.push(currentRange);
+ Q_QML_PROFILE(profiler, endRange<QQmlProfilerDefinitions::Creating>());
}
- void foreground(const QUrl &url, int line, int column)
+ void update(const QString &typeName, const QUrl &url, int line, int column)
{
- if (backgroundRanges.count() > 0) {
- switchRange();
- setCurrentRange(backgroundRanges.pop(), url, line, column);
- profiler->creatingLocation(url, line, column);
- }
+ profiler->updateCreating(typeName, url, line, column);
+ m_typeName = typeName;
+ m_url = url;
+ m_line = line;
+ m_column = column;
}
- QQmlProfiler *profiler;
-
private:
+ QQmlProfiler *profiler;
+};
- void switchRange()
+class QQmlObjectCompletionProfiler {
+public:
+ QQmlObjectCompletionProfiler(QQmlVmeProfiler *parent) :
+ profiler(parent->profiler)
{
- if (running)
- profiler->endRange<Creating>();
- else
- running = true;
+ Q_QML_PROFILE_IF_ENABLED(profiler, {
+ QQmlVmeProfiler::Data data = parent->pop();
+ profiler->startCreating(data.m_typeName, data.m_url, data.m_line, data.m_column);
+ });
}
- void setCurrentRange(const QString &typeName, const QUrl &url, int line, int column)
+ ~QQmlObjectCompletionProfiler()
{
- currentRange.typeName = typeName;
- currentRange.url = url;
- currentRange.line = line;
- currentRange.column = column;
+ Q_QML_PROFILE(profiler, endRange<QQmlProfilerDefinitions::Creating>());
}
-
- Data currentRange;
- QStack<Data> ranges;
- QStack<QString> backgroundRanges;
- bool running;
+private:
+ QQmlProfiler *profiler;
};
QT_END_NAMESPACE
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);