aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2011-12-09 12:39:23 +0000
committerQt by Nokia <qt-info@nokia.com>2011-12-14 04:52:08 +0100
commite8d0ab4b01cabf31d9bff31a821928d846c2f0af (patch)
treee58f5d7a4a93b66a487ad9ea09b4f10d803b10c4
parent0f2188361b996c4d8b8901412cdcebf35bad1e53 (diff)
Add a tracing API for the QML engine
Change-Id: Ic03583444d586f275897d765be8e1b5e69fdd5d4 Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
-rw-r--r--src/declarative/qml/ftw/ftw.pri2
-rw-r--r--src/declarative/qml/ftw/qdeclarativepool_p.h11
-rw-r--r--src/declarative/qml/ftw/qdeclarativetrace.cpp154
-rw-r--r--src/declarative/qml/ftw/qdeclarativetrace_p.h294
-rw-r--r--src/declarative/qml/qdeclarativebinding.cpp18
-rw-r--r--src/declarative/qml/qdeclarativebinding_p.h2
-rw-r--r--src/declarative/qml/qdeclarativebinding_p_p.h1
-rw-r--r--src/declarative/qml/qdeclarativecompiler.cpp3
-rw-r--r--src/declarative/qml/qdeclarativecomponent.cpp1
-rw-r--r--src/declarative/qml/qdeclarativeinstruction_p.h2
-rw-r--r--src/declarative/qml/qdeclarativevme.cpp60
-rw-r--r--src/declarative/qml/qdeclarativevme_p.h10
-rw-r--r--src/declarative/qml/v4/qv4bindings.cpp14
-rw-r--r--src/declarative/qml/v4/qv4bindings_p.h4
-rw-r--r--src/declarative/qml/v8/qv8bindings.cpp12
-rw-r--r--src/declarative/qml/v8/qv8bindings_p.h3
16 files changed, 577 insertions, 14 deletions
diff --git a/src/declarative/qml/ftw/ftw.pri b/src/declarative/qml/ftw/ftw.pri
index 9df0af8146..44141223bf 100644
--- a/src/declarative/qml/ftw/ftw.pri
+++ b/src/declarative/qml/ftw/ftw.pri
@@ -14,6 +14,7 @@ HEADERS += \
$$PWD/qdeletewatcher_p.h \
$$PWD/qrecyclepool_p.h \
$$PWD/qflagpointer_p.h \
+ $$PWD/qdeclarativetrace_p.h \
SOURCES += \
$$PWD/qintrusivelist.cpp \
@@ -21,4 +22,5 @@ SOURCES += \
$$PWD/qdeclarativepool.cpp \
$$PWD/qfastmetabuilder.cpp \
$$PWD/qdeclarativethread.cpp \
+ $$PWD/qdeclarativetrace.cpp \
diff --git a/src/declarative/qml/ftw/qdeclarativepool_p.h b/src/declarative/qml/ftw/qdeclarativepool_p.h
index 60ff4fa359..3a7133c7fb 100644
--- a/src/declarative/qml/ftw/qdeclarativepool_p.h
+++ b/src/declarative/qml/ftw/qdeclarativepool_p.h
@@ -55,6 +55,7 @@
#include <QtCore/qglobal.h>
#include <QtCore/qstring.h>
+#include <QtCore/qurl.h>
QT_BEGIN_NAMESPACE
@@ -105,6 +106,7 @@ public:
inline QString *NewString(const QString &);
inline QByteArray *NewByteArray(const QByteArray &);
+ inline QUrl *NewUrl(const QUrl &);
template<typename T>
struct List {
@@ -145,6 +147,8 @@ private:
};
struct ByteArrayClass : public QByteArray, public Class {
};
+ struct UrlClass : public QUrl, public Class {
+ };
inline void *allocate(int size);
void newpage();
@@ -222,6 +226,13 @@ QByteArray *QDeclarativePool::NewByteArray(const QByteArray &s)
return rv;
}
+QUrl *QDeclarativePool::NewUrl(const QUrl &s)
+{
+ QUrl *rv = New<UrlClass>();
+ *rv = s;
+ return rv;
+}
+
void *QDeclarativePool::allocate(int size)
{
if (!_page || (_page->header.free + size) > (_page->memory + Page::pageSize))
diff --git a/src/declarative/qml/ftw/qdeclarativetrace.cpp b/src/declarative/qml/ftw/qdeclarativetrace.cpp
new file mode 100644
index 0000000000..61e84075aa
--- /dev/null
+++ b/src/declarative/qml/ftw/qdeclarativetrace.cpp
@@ -0,0 +1,154 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdeclarativetrace_p.h"
+
+#ifdef QML_ENABLE_TRACE
+#include <stdio.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+#ifdef QML_ENABLE_TRACE
+
+QDeclarativeTrace::Pool QDeclarativeTrace::logPool;
+QDeclarativeTrace::Entry *QDeclarativeTrace::first = 0;
+QDeclarativeTrace::Entry *QDeclarativeTrace::last = 0;
+
+static qint64 toNsecs(QDeclarativeTrace::TimeType time)
+{
+#ifdef Q_OS_MAC
+ static mach_timebase_info_data_t info = {0,0};
+ if (info.denom == 0)
+ mach_timebase_info(&info);
+ return time * info.numer / info.denom;
+#else
+ qint64 rv = time.tv_sec * 1000000000 + time.tv_nsec;
+ return rv;
+#endif
+}
+
+QDeclarativeTrace::Pool::Pool()
+{
+ first = New<Entry>();
+ last = first;
+}
+
+QDeclarativeTrace::Pool::~Pool()
+{
+ char buffer[128];
+ sprintf(buffer, "qml.%d.log", ::getpid());
+ FILE *out = fopen(buffer, "w");
+ if (!out) {
+ fprintf (stderr, "QML Log: Could not open %s\n", buffer);
+ return;
+ } else {
+ fprintf (stderr, "QML Log: Writing log to %s\n", buffer);
+ }
+
+ QDeclarativeTrace::Entry *cur = QDeclarativeTrace::first;
+ QByteArray indent;
+ int depth = -1;
+
+ qint64 firstTime = -1;
+
+ while (cur) {
+
+ switch (cur->type) {
+ case QDeclarativeTrace::Entry::RangeStart: {
+ RangeStart *rs = static_cast<QDeclarativeTrace::RangeStart *>(cur);
+
+ qint64 nsecs = toNsecs(rs->time);
+
+ if (firstTime == -1)
+ firstTime = nsecs;
+
+ nsecs -= firstTime;
+
+ depth++;
+ indent = QByteArray(depth * 4, ' ');
+ fprintf(out, "%s%s @%lld (%lld ns)\n", indent.constData(),
+ rs->description, nsecs, toNsecs(rs->end->time) - nsecs - firstTime);
+ } break;
+ case QDeclarativeTrace::Entry::RangeEnd:
+ depth--;
+ indent = QByteArray(depth * 4, ' ');
+ break;
+ case QDeclarativeTrace::Entry::Detail:
+ fprintf(out, "%s %s\n", indent.constData(),
+ static_cast<QDeclarativeTrace::Detail *>(cur)->description);
+ break;
+ case QDeclarativeTrace::Entry::IntDetail:
+ fprintf(out, "%s %s: %d\n", indent.constData(),
+ static_cast<QDeclarativeTrace::Detail *>(cur)->description,
+ static_cast<QDeclarativeTrace::IntDetail *>(cur)->value);
+ break;
+ case QDeclarativeTrace::Entry::StringDetail: {
+ QByteArray vLatin1 = static_cast<QDeclarativeTrace::StringDetail *>(cur)->value->toLatin1();
+ fprintf(out, "%s %s: %s\n", indent.constData(),
+ static_cast<QDeclarativeTrace::Detail *>(cur)->description,
+ vLatin1.constData());
+ } break;
+ case QDeclarativeTrace::Entry::UrlDetail: {
+ QByteArray vLatin1 = static_cast<QDeclarativeTrace::UrlDetail *>(cur)->value->toString().toLatin1();
+ fprintf(out, "%s %s: %s\n", indent.constData(),
+ static_cast<QDeclarativeTrace::Detail *>(cur)->description,
+ vLatin1.constData());
+ } break;
+ case QDeclarativeTrace::Entry::Event: {
+ Event *ev = static_cast<QDeclarativeTrace::Event *>(cur);
+ qint64 nsecs = toNsecs(ev->time) - firstTime;
+ fprintf(out, "%s + %s @%lld +%lld ns\n", indent.constData(),
+ ev->description, nsecs, nsecs - (toNsecs(ev->start->time) - firstTime));
+ } break;
+ case QDeclarativeTrace::Entry::Null:
+ default:
+ break;
+ }
+ cur = cur->next;
+ }
+ fclose(out);
+}
+
+#endif
+
+QT_END_NAMESPACE
+
diff --git a/src/declarative/qml/ftw/qdeclarativetrace_p.h b/src/declarative/qml/ftw/qdeclarativetrace_p.h
new file mode 100644
index 0000000000..6fac53967a
--- /dev/null
+++ b/src/declarative/qml/ftw/qdeclarativetrace_p.h
@@ -0,0 +1,294 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVETRACE_P_H
+#define QDECLARATIVETRACE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+#include <private/qdeclarativepool_p.h>
+
+// #define QML_ENABLE_TRACE
+
+#if defined(QML_ENABLE_TRACE) && defined(Q_OS_MAC)
+#include <mach/mach_time.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+class QUrl;
+class QDeclarativeTrace
+{
+public:
+ inline QDeclarativeTrace(const char *desc);
+ inline ~QDeclarativeTrace();
+
+ inline void addDetail(const char *);
+ inline void addDetail(const char *, int);
+ inline void addDetail(const char *, const QString &);
+ inline void addDetail(const char *, const QUrl &);
+
+ inline void event(const char *desc);
+
+#ifdef QML_ENABLE_TRACE
+
+#ifdef Q_OS_MAC
+ typedef uint64_t TimeType;
+#else
+ typedef timespec TimeType;
+#endif
+
+ struct Entry : public QDeclarativePool::POD {
+ enum Type { Null, RangeStart, RangeEnd, Detail, IntDetail, StringDetail, UrlDetail, Event };
+ inline Entry();
+ inline Entry(Type);
+ Type type;
+ Entry *next;
+ };
+ struct RangeEnd : public Entry {
+ inline RangeEnd();
+ TimeType time;
+ };
+ struct RangeStart : public Entry {
+ inline RangeStart();
+ const char *description;
+ TimeType time;
+ QDeclarativeTrace::RangeEnd *end;
+ };
+ struct Detail : public Entry {
+ inline Detail();
+ inline Detail(Type t);
+ const char *description;
+ };
+ struct IntDetail : public Detail {
+ inline IntDetail();
+ int value;
+ };
+ struct StringDetail : public Detail {
+ inline StringDetail();
+ QString *value;
+ };
+ struct UrlDetail : public Detail {
+ inline UrlDetail();
+ QUrl *value;
+ };
+ struct Event : public Entry {
+ inline Event();
+ const char *description;
+ TimeType time;
+ QDeclarativeTrace::RangeStart *start;
+ };
+
+ struct Pool : public QDeclarativePool {
+ Pool();
+ ~Pool();
+ };
+
+ static Pool logPool;
+ static Entry *first;
+ static Entry *last;
+
+private:
+ RangeStart *start;
+
+ static TimeType gettime() {
+#ifdef Q_OS_MAC
+ return mach_absolute_time();
+#else
+ TimeType ts;
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ return ts;
+#endif
+ }
+#endif
+};
+
+#ifdef QML_ENABLE_TRACE
+QDeclarativeTrace::Entry::Entry()
+: type(Null), next(0)
+{
+}
+
+QDeclarativeTrace::Entry::Entry(Type type)
+: type(type), next(0)
+{
+ QDeclarativeTrace::last->next = this;
+ QDeclarativeTrace::last = this;
+}
+
+QDeclarativeTrace::RangeEnd::RangeEnd()
+: QDeclarativeTrace::Entry(QDeclarativeTrace::Entry::RangeEnd),
+ time(gettime())
+{
+}
+
+QDeclarativeTrace::RangeStart::RangeStart()
+: QDeclarativeTrace::Entry(QDeclarativeTrace::Entry::RangeStart),
+ description(0), time(gettime())
+{
+}
+
+QDeclarativeTrace::Detail::Detail()
+: QDeclarativeTrace::Entry(QDeclarativeTrace::Entry::Detail),
+ description(0)
+{
+}
+
+QDeclarativeTrace::Detail::Detail(Type type)
+: QDeclarativeTrace::Entry(type), description(0)
+{
+}
+
+QDeclarativeTrace::IntDetail::IntDetail()
+: QDeclarativeTrace::Detail(QDeclarativeTrace::Entry::IntDetail),
+ value(0)
+{
+}
+
+QDeclarativeTrace::StringDetail::StringDetail()
+: QDeclarativeTrace::Detail(QDeclarativeTrace::Entry::StringDetail),
+ value(0)
+{
+}
+
+QDeclarativeTrace::UrlDetail::UrlDetail()
+: QDeclarativeTrace::Detail(QDeclarativeTrace::Entry::UrlDetail),
+ value(0)
+{
+}
+
+QDeclarativeTrace::Event::Event()
+: QDeclarativeTrace::Entry(QDeclarativeTrace::Entry::Event),
+ description(0), time(gettime()), start(0)
+{
+}
+#endif
+
+QDeclarativeTrace::QDeclarativeTrace(const char *desc)
+{
+#ifdef QML_ENABLE_TRACE
+ RangeStart *e = logPool.New<RangeStart>();
+ e->description = desc;
+ e->end = 0;
+ start = e;
+#else
+ Q_UNUSED(desc);
+#endif
+}
+
+QDeclarativeTrace::~QDeclarativeTrace()
+{
+#ifdef QML_ENABLE_TRACE
+ RangeEnd *e = logPool.New<RangeEnd>();
+ start->end = e;
+#endif
+}
+
+void QDeclarativeTrace::addDetail(const char *desc)
+{
+#ifdef QML_ENABLE_TRACE
+ Detail *e = logPool.New<Detail>();
+ e->description = desc;
+#else
+ Q_UNUSED(desc);
+#endif
+}
+
+void QDeclarativeTrace::addDetail(const char *desc, int v)
+{
+#ifdef QML_ENABLE_TRACE
+ IntDetail *e = logPool.New<IntDetail>();
+ e->description = desc;
+ e->value = v;
+#else
+ Q_UNUSED(desc);
+ Q_UNUSED(v);
+#endif
+}
+
+void QDeclarativeTrace::addDetail(const char *desc, const QString &v)
+{
+#ifdef QML_ENABLE_TRACE
+ StringDetail *e = logPool.New<StringDetail>();
+ e->description = desc;
+ e->value = logPool.NewString(v);
+#else
+ Q_UNUSED(desc);
+ Q_UNUSED(v);
+#endif
+}
+
+void QDeclarativeTrace::addDetail(const char *desc, const QUrl &v)
+{
+#ifdef QML_ENABLE_TRACE
+ UrlDetail *e = logPool.New<UrlDetail>();
+ e->description = desc;
+ e->value = logPool.NewUrl(v);
+#else
+ Q_UNUSED(desc);
+ Q_UNUSED(v);
+#endif
+}
+
+void QDeclarativeTrace::event(const char *desc)
+{
+#ifdef QML_ENABLE_TRACE
+ Event *e = logPool.New<Event>();
+ e->start = start;
+ e->description = desc;
+#else
+ Q_UNUSED(desc);
+#endif
+}
+
+QT_END_NAMESPACE
+
+#endif // QDECLARATIVETRACE_P_H
diff --git a/src/declarative/qml/qdeclarativebinding.cpp b/src/declarative/qml/qdeclarativebinding.cpp
index fbfba6d8d3..84b49e10a8 100644
--- a/src/declarative/qml/qdeclarativebinding.cpp
+++ b/src/declarative/qml/qdeclarativebinding.cpp
@@ -48,6 +48,7 @@
#include "qdeclarativecompiler_p.h"
#include "qdeclarativedata_p.h"
#include <private/qdeclarativedebugtrace_p.h>
+#include <private/qdeclarativetrace_p.h>
#include <QVariant>
#include <QtCore/qdebug.h>
@@ -215,7 +216,7 @@ void QDeclarativeBindingPrivate::refresh()
}
QDeclarativeBindingPrivate::QDeclarativeBindingPrivate()
-: updating(false), enabled(false)
+: updating(false), enabled(false), columnNumber(0)
{
}
@@ -239,7 +240,7 @@ QDeclarativeBinding::createBinding(Identifier id, QObject *obj, QDeclarativeCont
typeData = engine->typeLoader.get(ctxtdata->url);
cdata = typeData->compiledData();
}
- QDeclarativeBinding *rv = cdata ? new QDeclarativeBinding(cdata->primitives.at(id), true, obj, ctxtdata, url, lineNumber, parent) : 0;
+ QDeclarativeBinding *rv = cdata ? new QDeclarativeBinding(cdata->primitives.at(id), true, obj, ctxtdata, url, lineNumber, 0, parent) : 0;
if (cdata)
cdata->release();
if (typeData)
@@ -265,11 +266,15 @@ QDeclarativeBinding::QDeclarativeBinding(const QString &str, QObject *obj, QDecl
QDeclarativeBinding::QDeclarativeBinding(const QString &str, bool isRewritten, QObject *obj,
QDeclarativeContextData *ctxt,
- const QString &url, int lineNumber, QObject *parent)
+ const QString &url, int lineNumber, int columnNumber,
+ QObject *parent)
: QDeclarativeExpression(ctxt, obj, str, isRewritten, url, lineNumber, *new QDeclarativeBindingPrivate)
{
+ Q_D(QDeclarativeBinding);
+
setParent(parent);
setNotifyOnValueChanged(true);
+ d->columnNumber = columnNumber;
}
/*!
@@ -351,6 +356,11 @@ void QDeclarativeBinding::update(QDeclarativePropertyPrivate::WriteFlags flags)
if (!d->enabled || !d->context() || !d->context()->isValid())
return;
+ QDeclarativeTrace trace("General Binding Update");
+ trace.addDetail("URL", d->url);
+ trace.addDetail("Line", d->line);
+ trace.addDetail("Column", d->columnNumber);
+
if (!d->updating) {
QDeclarativeBindingProfiler prof(this);
d->updating = true;
@@ -379,6 +389,8 @@ void QDeclarativeBinding::update(QDeclarativePropertyPrivate::WriteFlags flags)
v8::Context::Scope scope(ep->v8engine()->context());
v8::Local<v8::Value> result = d->v8value(0, &isUndefined);
+ trace.event("writing binding result");
+
bool needsErrorData = false;
if (!watcher.wasDeleted() && !d->error.isValid())
needsErrorData = !QDeclarativePropertyPrivate::writeBinding(d->property, d, result,
diff --git a/src/declarative/qml/qdeclarativebinding_p.h b/src/declarative/qml/qdeclarativebinding_p.h
index 8f4c736d6a..3fcb12b6c5 100644
--- a/src/declarative/qml/qdeclarativebinding_p.h
+++ b/src/declarative/qml/qdeclarativebinding_p.h
@@ -153,7 +153,7 @@ public:
QDeclarativeBinding(const QString &, QObject *, QDeclarativeContext *, QObject *parent=0);
QDeclarativeBinding(const QString &, QObject *, QDeclarativeContextData *, QObject *parent=0);
QDeclarativeBinding(const QString &, bool isRewritten, QObject *, QDeclarativeContextData *,
- const QString &url, int lineNumber, QObject *parent=0);
+ const QString &url, int lineNumber, int columnNumber = 0, QObject *parent=0);
QDeclarativeBinding(void *, QObject *, QDeclarativeContextData *, QObject *parent=0);
void setTarget(const QDeclarativeProperty &);
diff --git a/src/declarative/qml/qdeclarativebinding_p_p.h b/src/declarative/qml/qdeclarativebinding_p_p.h
index c704919f78..d5615455bd 100644
--- a/src/declarative/qml/qdeclarativebinding_p_p.h
+++ b/src/declarative/qml/qdeclarativebinding_p_p.h
@@ -77,6 +77,7 @@ protected:
private:
bool updating:1;
bool enabled:1;
+ int columnNumber;
QDeclarativeProperty property;
};
diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp
index 5500efa42f..44f1f5901d 100644
--- a/src/declarative/qml/qdeclarativecompiler.cpp
+++ b/src/declarative/qml/qdeclarativecompiler.cpp
@@ -3328,6 +3328,7 @@ void QDeclarativeCompiler::genBindingAssignment(QDeclarativeScript::Value *bindi
store.isRoot = (compileState->root == obj);
}
store.line = binding->location.start.line;
+ store.column = binding->location.start.column;
output->addInstruction(store);
} else if (ref.dataType == BindingReference::V8) {
Instruction::StoreV8Binding store;
@@ -3340,6 +3341,7 @@ void QDeclarativeCompiler::genBindingAssignment(QDeclarativeScript::Value *bindi
store.isRoot = (compileState->root == obj);
}
store.line = binding->location.start.line;
+ store.column = binding->location.start.column;
Q_ASSERT(ref.bindingContext.owner == 0 ||
(ref.bindingContext.owner != 0 && valueTypeProperty));
@@ -3356,6 +3358,7 @@ void QDeclarativeCompiler::genBindingAssignment(QDeclarativeScript::Value *bindi
store.assignBinding.context = ref.bindingContext.stack;
store.assignBinding.owner = ref.bindingContext.owner;
store.assignBinding.line = binding->location.start.line;
+ store.assignBinding.column = binding->location.start.column;
if (valueTypeProperty) {
store.assignBinding.isRoot = (compileState->root == valueTypeProperty->parent);
diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp
index 9a7d77115c..fdecd76da9 100644
--- a/src/declarative/qml/qdeclarativecomponent.cpp
+++ b/src/declarative/qml/qdeclarativecomponent.cpp
@@ -814,6 +814,7 @@ void QDeclarativeComponentPrivate::complete(QDeclarativeEnginePrivate *enginePri
void QDeclarativeComponent::completeCreate()
{
Q_D(QDeclarativeComponent);
+
d->completeCreate();
}
diff --git a/src/declarative/qml/qdeclarativeinstruction_p.h b/src/declarative/qml/qdeclarativeinstruction_p.h
index b36a664443..6da2fd834f 100644
--- a/src/declarative/qml/qdeclarativeinstruction_p.h
+++ b/src/declarative/qml/qdeclarativeinstruction_p.h
@@ -241,6 +241,7 @@ union QDeclarativeInstruction
short owner;
bool isRoot;
ushort line;
+ ushort column;
};
struct instr_assignBinding {
QML_INSTR_HEADER
@@ -250,6 +251,7 @@ union QDeclarativeInstruction
short owner;
bool isRoot;
ushort line;
+ ushort column;
};
struct instr_fetch {
QML_INSTR_HEADER
diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp
index aa31cad4f2..4f4e57c8d2 100644
--- a/src/declarative/qml/qdeclarativevme.cpp
+++ b/src/declarative/qml/qdeclarativevme.cpp
@@ -121,6 +121,11 @@ void QDeclarativeVME::init(QDeclarativeContextData *ctxt, QDeclarativeCompiledDa
bindValues.allocate(i->init.bindingsSize);
parserStatus.allocate(i->init.parserStatusSize);
+#ifdef QML_ENABLE_TRACE
+ parserStatusData.allocate(i->init.parserStatusSize);
+ rootComponent = comp;
+#endif
+
rootContext = 0;
engine = ctxt->engine;
}
@@ -155,6 +160,11 @@ bool QDeclarativeVME::initDeferred(QObject *object)
objects.push(object);
+#ifdef QML_ENABLE_TRACE
+ parserStatusData.allocate(i->deferInit.parserStatusSize);
+ rootComponent = comp;
+#endif
+
rootContext = 0;
engine = ctxt->engine;
@@ -177,6 +187,11 @@ QObject *QDeclarativeVME::execute(QList<QDeclarativeError> *errors, const Interr
{
Q_ASSERT(states.count() >= 1);
+#ifdef QML_ENABLE_TRACE
+ QDeclarativeTrace trace("VME Execute");
+ trace.addDetail("URL", rootComponent->url);
+#endif
+
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(states.at(0).context->engine);
ActiveVMERestorer restore(this, ep);
@@ -715,6 +730,10 @@ QObject *QDeclarativeVME::run(QList<QDeclarativeError> *errors,
QObject *target = objects.top();
QDeclarativeParserStatus *status = reinterpret_cast<QDeclarativeParserStatus *>(reinterpret_cast<char *>(target) + instr.castValue);
parserStatus.push(status);
+#ifdef QML_ENABLE_TRACE
+ Q_ASSERT(QObjectPrivate::get(target)->declarativeData);
+ parserStatusData.push(static_cast<QDeclarativeData *>(QObjectPrivate::get(target)->declarativeData));
+#endif
status->d = &parserStatus.top();
status->classBegin();
@@ -735,7 +754,8 @@ QObject *QDeclarativeVME::run(QList<QDeclarativeError> *errors,
QML_NEXT_INSTR(StoreBinding);
QDeclarativeBinding *bind = new QDeclarativeBinding(PRIMITIVES.at(instr.value), true,
- context, CTXT, COMP->name, instr.line);
+ context, CTXT, COMP->name, instr.line,
+ instr.column);
bindValues.push(bind);
bind->m_mePtr = &bindValues.top();
bind->setTarget(target, instr.property, CTXT);
@@ -753,7 +773,8 @@ QObject *QDeclarativeVME::run(QList<QDeclarativeError> *errors,
QML_NEXT_INSTR(StoreBindingOnAlias);
QDeclarativeBinding *bind = new QDeclarativeBinding(PRIMITIVES.at(instr.value), true,
- context, CTXT, COMP->name, instr.line);
+ context, CTXT, COMP->name, instr.line,
+ instr.column);
bindValues.push(bind);
bind->m_mePtr = &bindValues.top();
bind->setTarget(target, instr.property, CTXT);
@@ -776,7 +797,8 @@ QObject *QDeclarativeVME::run(QList<QDeclarativeError> *errors,
QML_NEXT_INSTR(StoreV4Binding);
QDeclarativeAbstractBinding *binding =
- CTXT->v4bindings->configBinding(instr.value, target, scope, property, instr.line);
+ CTXT->v4bindings->configBinding(instr.value, target, scope, property,
+ instr.line, instr.column);
bindValues.push(binding);
binding->m_mePtr = &bindValues.top();
binding->addToObject(target, property);
@@ -793,7 +815,8 @@ QObject *QDeclarativeVME::run(QList<QDeclarativeError> *errors,
QDeclarativeAbstractBinding *binding =
CTXT->v8bindings->configBinding(instr.value, target, scope,
- instr.property, instr.line);
+ instr.property, instr.line,
+ instr.column);
bindValues.push(binding);
binding->m_mePtr = &bindValues.top();
binding->addToObject(target, QDeclarativePropertyPrivate::bindingIndex(instr.property));
@@ -1019,6 +1042,9 @@ void QDeclarativeVME::reset()
lists.deallocate();
bindValues.deallocate();
parserStatus.deallocate();
+#ifdef QML_ENABLE_TRACE
+ parserStatusData.deallocate();
+#endif
finalizeCallbacks.clear();
states.clear();
rootContext = 0;
@@ -1158,9 +1184,17 @@ QDeclarativeContextData *QDeclarativeVME::complete(const Interrupt &interrupt)
if (!engine)
return 0;
+ QDeclarativeTrace trace("VME Complete");
+#ifdef QML_ENABLE_TRACE
+ trace.addDetail("URL", rootComponent->url);
+#endif
+
ActiveVMERestorer restore(this, QDeclarativeEnginePrivate::get(engine));
QRecursionWatcher<QDeclarativeVME, &QDeclarativeVME::recursion> watcher(this);
+ {
+ QDeclarativeTrace trace("VME Binding Enable");
+ trace.event("begin binding eval");
while (!bindValues.isEmpty()) {
QDeclarativeAbstractBinding *b = bindValues.pop();
@@ -1174,12 +1208,23 @@ QDeclarativeContextData *QDeclarativeVME::complete(const Interrupt &interrupt)
return 0;
}
bindValues.deallocate();
+ }
+ {
+ QDeclarativeTrace trace("VME Component Complete");
while (!parserStatus.isEmpty()) {
QDeclarativeParserStatus *status = parserStatus.pop();
+#ifdef QML_ENABLE_TRACE
+ QDeclarativeData *data = parserStatusData.pop();
+#endif
if (status && status->d) {
status->d = 0;
+#ifdef QML_ENABLE_TRACE
+ QDeclarativeTrace trace("Component complete");
+ trace.addDetail("URL", data->outerContext->url);
+ trace.addDetail("Line", data->lineNumber);
+#endif
status->componentComplete();
}
@@ -1187,7 +1232,10 @@ QDeclarativeContextData *QDeclarativeVME::complete(const Interrupt &interrupt)
return 0;
}
parserStatus.deallocate();
+ }
+ {
+ QDeclarativeTrace trace("VME Finalize Callbacks");
for (int ii = 0; ii < finalizeCallbacks.count(); ++ii) {
QDeclarativeEnginePrivate::FinalizeCallback callback = finalizeCallbacks.at(ii);
QObject *obj = callback.first;
@@ -1199,7 +1247,10 @@ QDeclarativeContextData *QDeclarativeVME::complete(const Interrupt &interrupt)
return 0;
}
finalizeCallbacks.clear();
+ }
+ {
+ QDeclarativeTrace trace("VME Component.onCompleted Callbacks");
while (componentAttached) {
QDeclarativeComponentAttached *a = componentAttached;
a->rem();
@@ -1212,6 +1263,7 @@ QDeclarativeContextData *QDeclarativeVME::complete(const Interrupt &interrupt)
if (watcher.hasRecursed() || interrupt.shouldInterrupt())
return 0;
}
+ }
QDeclarativeContextData *rv = rootContext;
diff --git a/src/declarative/qml/qdeclarativevme_p.h b/src/declarative/qml/qdeclarativevme_p.h
index 4edceb283a..63cb7bef85 100644
--- a/src/declarative/qml/qdeclarativevme_p.h
+++ b/src/declarative/qml/qdeclarativevme_p.h
@@ -67,6 +67,8 @@
#include <private/qdeclarativeengine_p.h>
#include <private/qfinitestack_p.h>
+#include <private/qdeclarativetrace_p.h>
+
QT_BEGIN_NAMESPACE
class QObject;
@@ -145,11 +147,19 @@ private:
QDeclarativeEngine *engine;
QRecursionNode recursion;
+#ifdef QML_ENABLE_TRACE
+ QDeclarativeCompiledData *rootComponent;
+#endif
+
QFiniteStack<QObject *> objects;
QFiniteStack<QDeclarativeVMETypes::List> lists;
QFiniteStack<QDeclarativeAbstractBinding *> bindValues;
QFiniteStack<QDeclarativeParserStatus *> parserStatus;
+#ifdef QML_ENABLE_TRACE
+ QFiniteStack<QDeclarativeData *> parserStatusData;
+#endif
+
QDeclarativeGuardedContextData rootContext;
QDeclarativeGuardedContextData creationContext;
diff --git a/src/declarative/qml/v4/qv4bindings.cpp b/src/declarative/qml/v4/qv4bindings.cpp
index 2dc812f47b..04c410c15d 100644
--- a/src/declarative/qml/v4/qv4bindings.cpp
+++ b/src/declarative/qml/v4/qv4bindings.cpp
@@ -49,6 +49,7 @@
#include <private/qdeclarativeaccessors_p.h>
#include <private/qdeclarativedebugtrace_p.h>
#include <private/qdeclarativemetatype_p.h>
+#include <private/qdeclarativetrace_p.h>
#include <QtDeclarative/qdeclarativeinfo.h>
#include <QtCore/qnumeric.h>
@@ -212,7 +213,8 @@ QV4Bindings::~QV4Bindings()
}
QDeclarativeAbstractBinding *QV4Bindings::configBinding(int index, QObject *target,
- QObject *scope, int property, int line)
+ QObject *scope, int property,
+ int line, int column)
{
Binding *rv = bindings + index;
@@ -221,6 +223,7 @@ QDeclarativeAbstractBinding *QV4Bindings::configBinding(int index, QObject *targ
rv->target = target;
rv->scope = scope;
rv->line = line;
+ rv->column = column;
rv->parent = this;
addref(); // This is decremented in Binding::destroy()
@@ -270,8 +273,10 @@ void QV4Bindings::subscriptionNotify(int id)
QV4Program::BindingReference *bindingRef = list->bindings + ii;
Binding *binding = bindings + bindingRef->binding;
- if (binding->executedBlocks & bindingRef->blockMask)
+
+ if (binding->executedBlocks & bindingRef->blockMask) {
run(binding, QDeclarativePropertyPrivate::DontRemoveBinding);
+ }
}
}
@@ -284,6 +289,11 @@ void QV4Bindings::run(Binding *binding, QDeclarativePropertyPrivate::WriteFlags
if (!context || !context->isValid())
return;
+ QDeclarativeTrace trace("V4 Binding Update");
+ trace.addDetail("URL", context->url);
+ trace.addDetail("Line", binding->line);
+ trace.addDetail("Column", binding->column);
+
if (binding->updating) {
QString name;
if (binding->property & 0xFFFF0000) {
diff --git a/src/declarative/qml/v4/qv4bindings_p.h b/src/declarative/qml/v4/qv4bindings_p.h
index b961cc53fd..b9e368599b 100644
--- a/src/declarative/qml/v4/qv4bindings_p.h
+++ b/src/declarative/qml/v4/qv4bindings_p.h
@@ -72,7 +72,8 @@ public:
virtual ~QV4Bindings();
QDeclarativeAbstractBinding *configBinding(int index, QObject *target,
- QObject *scope, int property, int line);
+ QObject *scope, int property,
+ int line, int column);
#ifdef QML_THREADED_INTERPRETER
static void **getDecodeInstrTable();
@@ -96,6 +97,7 @@ private:
int property;
QObject *scope;
int line;
+ int column;
QObject *target;
quint32 executedBlocks;
diff --git a/src/declarative/qml/v8/qv8bindings.cpp b/src/declarative/qml/v8/qv8bindings.cpp
index 3386c5ddc8..510d6138f6 100644
--- a/src/declarative/qml/v8/qv8bindings.cpp
+++ b/src/declarative/qml/v8/qv8bindings.cpp
@@ -48,11 +48,12 @@
#include <private/qdeclarativebinding_p_p.h>
#include <private/qdeclarativeexpression_p.h>
#include <private/qobject_p.h>
+#include <private/qdeclarativetrace_p.h>
QT_BEGIN_NAMESPACE
QV8Bindings::Binding::Binding()
-: index(-1), enabled(false), updating(false), line(-1), object(0), parent(0)
+: index(-1), enabled(false), updating(false), line(-1), column(-1), object(0), parent(0)
{
}
@@ -75,6 +76,11 @@ void QV8Bindings::Binding::update(QDeclarativePropertyPrivate::WriteFlags flags)
if (!enabled)
return;
+ QDeclarativeTrace trace("V8 Binding Update");
+ trace.addDetail("URL", parent->url);
+ trace.addDetail("Line", line);
+ trace.addDetail("Column", column);
+
QDeclarativeContextData *context = QDeclarativeAbstractExpression::context();
if (!context || !context->isValid())
return;
@@ -93,6 +99,7 @@ void QV8Bindings::Binding::update(QDeclarativePropertyPrivate::WriteFlags flags)
v8::Local<v8::Value> result = evaluate(v8::Handle<v8::Function>::Cast(parent->functions->Get(index)),
&isUndefined);
+ trace.event("writing V8 result");
bool needsErrorData = false;
if (!watcher.wasDeleted() && !error.isValid()) {
typedef QDeclarativePropertyPrivate PP;
@@ -183,11 +190,12 @@ QV8Bindings::~QV8Bindings()
QDeclarativeAbstractBinding *QV8Bindings::configBinding(int index, QObject *target, QObject *scope,
const QDeclarativePropertyData &p,
- int line)
+ int line, int column)
{
QV8Bindings::Binding *rv = bindings + index;
rv->line = line;
+ rv->column = column;
rv->index = index;
rv->object = target;
rv->property = p;
diff --git a/src/declarative/qml/v8/qv8bindings_p.h b/src/declarative/qml/v8/qv8bindings_p.h
index 904062551d..12dd5d791b 100644
--- a/src/declarative/qml/v8/qv8bindings_p.h
+++ b/src/declarative/qml/v8/qv8bindings_p.h
@@ -75,7 +75,7 @@ public:
QDeclarativeAbstractBinding *configBinding(int index, QObject *target, QObject *scope,
const QDeclarativePropertyData &prop,
- int line);
+ int line, int column);
private:
Q_DISABLE_COPY(QV8Bindings)
@@ -100,6 +100,7 @@ private:
bool enabled:1;
bool updating:1;
int line;
+ int column;
QObject *object;
QDeclarativePropertyData property;
QV8Bindings *parent;