~ubuntu-branches/ubuntu/wily/qtdeclarative-opensource-src/wily-proposed

« back to all changes in this revision

Viewing changes to src/qml/debugger/qv4profilerservice.cpp

  • Committer: Package Import Robot
  • Author(s): Ricardo Salveti de Araujo, Ricardo Salveti de Araujo, Timo Jyrinki
  • Date: 2014-06-19 02:39:21 UTC
  • mfrom: (0.1.18 experimental)
  • Revision ID: package-import@ubuntu.com-20140619023921-yb2oasnuetz9b0fc
Tags: 5.3.0-3ubuntu4
[ Ricardo Salveti de Araujo ]
* debian/control:
  - Updating dependencies as we now also have libqt5quickwidgets5-gles
* libqt5quickwidgets5.symbols: updating to allow gles variant

[ Timo Jyrinki ]
* Update libqt5quickparticles5.symbols from build logs

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
 
4
** Contact: http://www.qt-project.org/legal
 
5
**
 
6
** This file is part of the QtQml module of the Qt Toolkit.
 
7
**
 
8
** $QT_BEGIN_LICENSE:LGPL$
 
9
** Commercial License Usage
 
10
** Licensees holding valid commercial Qt licenses may use this file in
 
11
** accordance with the commercial license agreement provided with the
 
12
** Software or, alternatively, in accordance with the terms contained in
 
13
** a written agreement between you and Digia.  For licensing terms and
 
14
** conditions see http://qt.digia.com/licensing.  For further information
 
15
** use the contact form at http://qt.digia.com/contact-us.
 
16
**
 
17
** GNU Lesser General Public License Usage
 
18
** Alternatively, this file may be used under the terms of the GNU Lesser
 
19
** General Public License version 2.1 as published by the Free Software
 
20
** Foundation and appearing in the file LICENSE.LGPL included in the
 
21
** packaging of this file.  Please review the following information to
 
22
** ensure the GNU Lesser General Public License version 2.1 requirements
 
23
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 
24
**
 
25
** In addition, as a special exception, Digia gives you certain additional
 
26
** rights.  These rights are described in the Digia Qt LGPL Exception
 
27
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
 
28
**
 
29
** GNU General Public License Usage
 
30
** Alternatively, this file may be used under the terms of the GNU
 
31
** General Public License version 3.0 as published by the Free Software
 
32
** Foundation and appearing in the file LICENSE.GPL included in the
 
33
** packaging of this file.  Please review the following information to
 
34
** ensure the GNU General Public License version 3.0 requirements will be
 
35
** met: http://www.gnu.org/copyleft/gpl.html.
 
36
**
 
37
**
 
38
** $QT_END_LICENSE$
 
39
**
 
40
****************************************************************************/
 
41
 
 
42
#include "qv4profilerservice_p.h"
 
43
#include "qqmlconfigurabledebugservice_p_p.h"
 
44
 
 
45
#include <QtCore/QHash>
 
46
#include <QtCore/QMutex>
 
47
#include <QtCore/QWaitCondition>
 
48
 
 
49
QT_BEGIN_NAMESPACE
 
50
 
 
51
Q_GLOBAL_STATIC(QV4ProfilerService, v4ProfilerInstance)
 
52
 
 
53
#if 0
 
54
// ### FIXME: v4
 
55
class DebugServiceOutputStream : public v8::OutputStream
 
56
{
 
57
public:
 
58
    DebugServiceOutputStream()
 
59
        : v8::OutputStream() {}
 
60
    void EndOfStream() {}
 
61
    WriteResult WriteAsciiChunk(char *rawData, int size)
 
62
    {
 
63
        QByteArray data;
 
64
        QQmlDebugStream ds(&data, QIODevice::WriteOnly);
 
65
        ds << QV4ProfilerService::V4SnapshotChunk << QByteArray(rawData, size);
 
66
        messages.append(data);
 
67
        return kContinue;
 
68
    }
 
69
    QList<QByteArray> messages;
 
70
};
 
71
#endif
 
72
 
 
73
// convert to a QByteArray that can be sent to the debug client
 
74
QByteArray QV4ProfilerData::toByteArray() const
 
75
{
 
76
    QByteArray data;
 
77
    //### using QDataStream is relatively expensive
 
78
    QQmlDebugStream ds(&data, QIODevice::WriteOnly);
 
79
    ds << messageType << filename << functionname << lineNumber << totalTime << selfTime << treeLevel;
 
80
 
 
81
    return data;
 
82
}
 
83
 
 
84
class QV4ProfilerServicePrivate : public QQmlConfigurableDebugServicePrivate
 
85
{
 
86
    Q_DECLARE_PUBLIC(QV4ProfilerService)
 
87
 
 
88
public:
 
89
    QV4ProfilerServicePrivate()
 
90
        :initialized(false)
 
91
    {
 
92
    }
 
93
 
 
94
    // ### FIXME: v4
 
95
//    void takeSnapshot(v8::HeapSnapshot::Type);
 
96
//    void printProfileTree(const v8::CpuProfileNode *node, int level = 0);
 
97
//    void sendMessages();
 
98
 
 
99
    QList<QV4ProfilerData> m_data;
 
100
 
 
101
    bool initialized;
 
102
    QList<QString> m_ongoing;
 
103
};
 
104
 
 
105
QV4ProfilerService::QV4ProfilerService(QObject *parent)
 
106
    : QQmlConfigurableDebugService(*(new QV4ProfilerServicePrivate()), QStringLiteral("V8Profiler"), 1, parent)
 
107
{
 
108
}
 
109
 
 
110
QV4ProfilerService::~QV4ProfilerService()
 
111
{
 
112
}
 
113
 
 
114
QV4ProfilerService *QV4ProfilerService::instance()
 
115
{
 
116
    return v4ProfilerInstance();
 
117
}
 
118
 
 
119
void QV4ProfilerService::stateAboutToBeChanged(QQmlDebugService::State newState)
 
120
{
 
121
    Q_D(QV4ProfilerService);
 
122
    QMutexLocker lock(configMutex());
 
123
 
 
124
    if (state() == newState)
 
125
        return;
 
126
 
 
127
    if (state() == Enabled) {
 
128
        foreach (const QString &title, d->m_ongoing) {
 
129
            QMetaObject::invokeMethod(this, "stopProfiling", Qt::BlockingQueuedConnection,
 
130
                                      Q_ARG(QString, title));
 
131
        }
 
132
        QMetaObject::invokeMethod(this, "sendProfilingData", Qt::BlockingQueuedConnection);
 
133
    }
 
134
}
 
135
 
 
136
void QV4ProfilerService::messageReceived(const QByteArray &message)
 
137
{
 
138
    Q_D(QV4ProfilerService);
 
139
 
 
140
    QQmlDebugStream ds(message);
 
141
    QByteArray command;
 
142
    QByteArray option;
 
143
    QByteArray title;
 
144
    ds >> command >> option;
 
145
 
 
146
    QMutexLocker lock(configMutex());
 
147
 
 
148
    if (command == "V8PROFILER") {
 
149
        ds >>  title;
 
150
        QString titleStr = QString::fromUtf8(title);
 
151
        if (option == "start") {
 
152
            QMetaObject::invokeMethod(this, "startProfiling", Qt::QueuedConnection, Q_ARG(QString, titleStr));
 
153
        } else if (option == "stop" && d->initialized) {
 
154
            QMetaObject::invokeMethod(this, "stopProfiling", Qt::QueuedConnection, Q_ARG(QString, titleStr));
 
155
            QMetaObject::invokeMethod(this, "sendProfilingData", Qt::QueuedConnection);
 
156
        }
 
157
        d->initialized = true;
 
158
    }
 
159
 
 
160
    if (command == "V8SNAPSHOT") {
 
161
        if (option == "full")
 
162
            QMetaObject::invokeMethod(this, "takeSnapshot", Qt::QueuedConnection);
 
163
        else if (option == "delete") {
 
164
            QMetaObject::invokeMethod(this, "deleteSnapshots", Qt::QueuedConnection);
 
165
        }
 
166
    }
 
167
 
 
168
    // wake up constructor in blocking mode
 
169
    stopWaiting();
 
170
 
 
171
    QQmlDebugService::messageReceived(message);
 
172
}
 
173
 
 
174
void QV4ProfilerService::startProfiling(const QString &title)
 
175
{
 
176
    Q_D(QV4ProfilerService);
 
177
    // Start Profiling
 
178
 
 
179
    if (d->m_ongoing.contains(title))
 
180
        return;
 
181
 
 
182
//    v8::Handle<v8::String> v8title = v8::String::New(reinterpret_cast<const uint16_t*>(title.data()), title.size());
 
183
    // ### FIXME: v4
 
184
//    v8::CpuProfiler::StartProfiling(v8title);
 
185
 
 
186
    d->m_ongoing.append(title);
 
187
 
 
188
    // indicate profiling started
 
189
    QByteArray data;
 
190
    QQmlDebugStream ds(&data, QIODevice::WriteOnly);
 
191
    ds << (int)QV4ProfilerService::V4Started;
 
192
 
 
193
    sendMessage(data);
 
194
}
 
195
 
 
196
void QV4ProfilerService::stopProfiling(const QString &title)
 
197
{
 
198
    Q_D(QV4ProfilerService);
 
199
    // Stop profiling
 
200
 
 
201
    if (!d->m_ongoing.contains(title))
 
202
        return;
 
203
    d->m_ongoing.removeOne(title);
 
204
 
 
205
#if 0
 
206
    // ### FIXME: v4
 
207
    v8::HandleScope handle_scope;
 
208
    v8::Handle<v8::String> v8title = v8::String::New(reinterpret_cast<const uint16_t*>(title.data()), title.size());
 
209
    const v8::CpuProfile *cpuProfile = v8::CpuProfiler::StopProfiling(v8title);
 
210
    if (cpuProfile) {
 
211
        // can happen at start
 
212
        const v8::CpuProfileNode *rootNode = cpuProfile->GetTopDownRoot();
 
213
        d->printProfileTree(rootNode);
 
214
    } else {
 
215
#endif
 
216
        // indicate completion, even without data
 
217
        QByteArray data;
 
218
        QQmlDebugStream ds(&data, QIODevice::WriteOnly);
 
219
        ds << (int)QV4ProfilerService::V4Complete;
 
220
 
 
221
        sendMessage(data);
 
222
#if 0
 
223
    }
 
224
#endif
 
225
}
 
226
 
 
227
void QV4ProfilerService::takeSnapshot()
 
228
{
 
229
//    Q_D(QV4ProfilerService);
 
230
    // ### FIXME: v4
 
231
//    d->takeSnapshot(v8::HeapSnapshot::kFull);
 
232
}
 
233
 
 
234
void QV4ProfilerService::deleteSnapshots()
 
235
{
 
236
    // ### FIXME: v4
 
237
//    v8::HeapProfiler::DeleteAllSnapshots();
 
238
}
 
239
 
 
240
void QV4ProfilerService::sendProfilingData()
 
241
{
 
242
//    Q_D(QV4ProfilerService);
 
243
    // Send messages to client
 
244
    // ### FIXME: v4
 
245
//    d->sendMessages();
 
246
}
 
247
 
 
248
#if 0
 
249
// ### FIXME: v4
 
250
void QV4ProfilerServicePrivate::printProfileTree(const v8::CpuProfileNode *node, int level)
 
251
{
 
252
    for (int index = 0 ; index < node->GetChildrenCount() ; index++) {
 
253
        const v8::CpuProfileNode* childNode = node->GetChild(index);
 
254
        QString scriptResourceName = QJSConverter::toString(childNode->GetScriptResourceName());
 
255
        if (scriptResourceName.length() > 0) {
 
256
 
 
257
            QV4ProfilerData rd = {(int)QV4ProfilerService::V4Entry, scriptResourceName,
 
258
                QJSConverter::toString(childNode->GetFunctionName()),
 
259
                childNode->GetLineNumber(), childNode->GetTotalTime(), childNode->GetSelfTime(), level};
 
260
            m_data.append(rd);
 
261
 
 
262
            // different nodes might have common children: fix at client side
 
263
            if (childNode->GetChildrenCount() > 0) {
 
264
                printProfileTree(childNode, level+1);
 
265
            }
 
266
        }
 
267
    }
 
268
}
 
269
 
 
270
void QV4ProfilerServicePrivate::takeSnapshot(v8::HeapSnapshot::Type snapshotType)
 
271
{
 
272
    Q_Q(QV4ProfilerService);
 
273
 
 
274
    v8::HandleScope scope;
 
275
    v8::Handle<v8::String> title = v8::String::New("");
 
276
 
 
277
    DebugServiceOutputStream outputStream;
 
278
    const v8::HeapSnapshot *snapshot = v8::HeapProfiler::TakeSnapshot(title, snapshotType);
 
279
    snapshot->Serialize(&outputStream, v8::HeapSnapshot::kJSON);
 
280
    QList<QByteArray> messages = outputStream.messages;
 
281
 
 
282
    //indicate completion
 
283
    QByteArray data;
 
284
    QQmlDebugStream ds(&data, QIODevice::WriteOnly);
 
285
    ds << (int)QV4ProfilerService::V4SnapshotComplete;
 
286
    messages.append(data);
 
287
 
 
288
    q->sendMessages(messages);
 
289
}
 
290
 
 
291
void QV4ProfilerServicePrivate::sendMessages()
 
292
{
 
293
    Q_Q(QV4ProfilerService);
 
294
 
 
295
    QList<QByteArray> messages;
 
296
    for (int i = 0; i < m_data.count(); ++i)
 
297
        messages.append(m_data.at(i).toByteArray());
 
298
    m_data.clear();
 
299
 
 
300
    //indicate completion
 
301
    QByteArray data;
 
302
    QQmlDebugStream ds(&data, QIODevice::WriteOnly);
 
303
    ds << (int)QV4ProfilerService::V4Complete;
 
304
    messages.append(data);
 
305
 
 
306
    q->sendMessages(messages);
 
307
}
 
308
#endif
 
309
 
 
310
QT_END_NAMESPACE