Add a tracing API for the QML engine
authorAaron Kennedy <aaron.kennedy@nokia.com>
Fri, 9 Dec 2011 12:39:23 +0000 (12:39 +0000)
committerQt by Nokia <qt-info@nokia.com>
Wed, 14 Dec 2011 03:52:08 +0000 (04:52 +0100)
Change-Id: Ic03583444d586f275897d765be8e1b5e69fdd5d4
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
16 files changed:
src/declarative/qml/ftw/ftw.pri
src/declarative/qml/ftw/qdeclarativepool_p.h
src/declarative/qml/ftw/qdeclarativetrace.cpp [new file with mode: 0644]
src/declarative/qml/ftw/qdeclarativetrace_p.h [new file with mode: 0644]
src/declarative/qml/qdeclarativebinding.cpp
src/declarative/qml/qdeclarativebinding_p.h
src/declarative/qml/qdeclarativebinding_p_p.h
src/declarative/qml/qdeclarativecompiler.cpp
src/declarative/qml/qdeclarativecomponent.cpp
src/declarative/qml/qdeclarativeinstruction_p.h
src/declarative/qml/qdeclarativevme.cpp
src/declarative/qml/qdeclarativevme_p.h
src/declarative/qml/v4/qv4bindings.cpp
src/declarative/qml/v4/qv4bindings_p.h
src/declarative/qml/v8/qv8bindings.cpp
src/declarative/qml/v8/qv8bindings_p.h

index 9df0af8..4414122 100644 (file)
@@ -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 \
 
index 60ff4fa..3a7133c 100644 (file)
@@ -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 (file)
index 0000000..61e8407
--- /dev/null
@@ -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 (file)
index 0000000..6fac539
--- /dev/null
@@ -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
index fbfba6d..84b49e1 100644 (file)
@@ -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, 
index 8f4c736..3fcb12b 100644 (file)
@@ -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 &);
index c704919..d561545 100644 (file)
@@ -77,6 +77,7 @@ protected:
 private:
     bool updating:1;
     bool enabled:1;
+    int columnNumber;
     QDeclarativeProperty property; 
 };
 
index 5500efa..44f1f59 100644 (file)
@@ -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);
index 9a7d771..fdecd76 100644 (file)
@@ -814,6 +814,7 @@ void QDeclarativeComponentPrivate::complete(QDeclarativeEnginePrivate *enginePri
 void QDeclarativeComponent::completeCreate()
 {
     Q_D(QDeclarativeComponent);
+
     d->completeCreate();
 }
 
index b36a664..6da2fd8 100644 (file)
@@ -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
index aa31cad..4f4e57c 100644 (file)
@@ -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;
 
index 4edceb2..63cb7be 100644 (file)
@@ -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;
 
index 2dc812f..04c410c 100644 (file)
@@ -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) {
index b961cc5..b9e3685 100644 (file)
@@ -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;
 
index 3386c5d..510d613 100644 (file)
 #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;
index 9040625..12dd5d7 100644 (file)
@@ -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;