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

« back to all changes in this revision

Viewing changes to src/qml/debugger/qv8profilerservice.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 "qv8profilerservice_p.h"
43
 
#include "qqmldebugservice_p_p.h"
44
 
#include <private/qv8profiler_p.h>
45
 
 
46
 
#include <QtCore/QHash>
47
 
#include <QtCore/QMutex>
48
 
#include <QtCore/QWaitCondition>
49
 
 
50
 
QT_BEGIN_NAMESPACE
51
 
 
52
 
Q_GLOBAL_STATIC(QV8ProfilerService, v8ProfilerInstance)
53
 
 
54
 
#if 0
55
 
// ### FIXME: v4
56
 
class DebugServiceOutputStream : public v8::OutputStream
57
 
{
58
 
public:
59
 
    DebugServiceOutputStream()
60
 
        : v8::OutputStream() {}
61
 
    void EndOfStream() {}
62
 
    WriteResult WriteAsciiChunk(char *rawData, int size)
63
 
    {
64
 
        QByteArray data;
65
 
        QQmlDebugStream ds(&data, QIODevice::WriteOnly);
66
 
        ds << QV8ProfilerService::V8SnapshotChunk << QByteArray(rawData, size);
67
 
        messages.append(data);
68
 
        return kContinue;
69
 
    }
70
 
    QList<QByteArray> messages;
71
 
};
72
 
#endif
73
 
 
74
 
// convert to a QByteArray that can be sent to the debug client
75
 
QByteArray QV8ProfilerData::toByteArray() const
76
 
{
77
 
    QByteArray data;
78
 
    //### using QDataStream is relatively expensive
79
 
    QQmlDebugStream ds(&data, QIODevice::WriteOnly);
80
 
    ds << messageType << filename << functionname << lineNumber << totalTime << selfTime << treeLevel;
81
 
 
82
 
    return data;
83
 
}
84
 
 
85
 
class QV8ProfilerServicePrivate : public QQmlDebugServicePrivate
86
 
{
87
 
    Q_DECLARE_PUBLIC(QV8ProfilerService)
88
 
 
89
 
public:
90
 
    QV8ProfilerServicePrivate()
91
 
        :initialized(false)
92
 
    {
93
 
    }
94
 
 
95
 
    // ### FIXME: v4
96
 
//    void takeSnapshot(v8::HeapSnapshot::Type);
97
 
//    void printProfileTree(const v8::CpuProfileNode *node, int level = 0);
98
 
//    void sendMessages();
99
 
 
100
 
    QList<QV8ProfilerData> m_data;
101
 
 
102
 
    bool initialized;
103
 
    QMutex initializeMutex;
104
 
    QWaitCondition initializeCondition;
105
 
    QList<QString> m_ongoing;
106
 
};
107
 
 
108
 
QV8ProfilerService::QV8ProfilerService(QObject *parent)
109
 
    : QQmlDebugService(*(new QV8ProfilerServicePrivate()), QStringLiteral("V8Profiler"), 1, parent)
110
 
{
111
 
    Q_D(QV8ProfilerService);
112
 
 
113
 
    QMutexLocker lock(&d->initializeMutex);
114
 
 
115
 
    if (registerService() == Enabled
116
 
            && QQmlDebugService::blockingMode()) {
117
 
        // let's wait for first message ...
118
 
        d->initializeCondition.wait(&d->initializeMutex);
119
 
    }
120
 
}
121
 
 
122
 
QV8ProfilerService::~QV8ProfilerService()
123
 
{
124
 
}
125
 
 
126
 
QV8ProfilerService *QV8ProfilerService::instance()
127
 
{
128
 
    return v8ProfilerInstance();
129
 
}
130
 
 
131
 
void QV8ProfilerService::initialize()
132
 
{
133
 
    // just make sure that the service is properly registered
134
 
    v8ProfilerInstance();
135
 
}
136
 
 
137
 
void QV8ProfilerService::stateAboutToBeChanged(QQmlDebugService::State newState)
138
 
{
139
 
    Q_D(QV8ProfilerService);
140
 
 
141
 
    if (state() == newState)
142
 
        return;
143
 
 
144
 
    if (state() == Enabled) {
145
 
        foreach (const QString &title, d->m_ongoing) {
146
 
            QMetaObject::invokeMethod(this, "stopProfiling", Qt::BlockingQueuedConnection,
147
 
                                      Q_ARG(QString, title));
148
 
        }
149
 
        QMetaObject::invokeMethod(this, "sendProfilingData", Qt::BlockingQueuedConnection);
150
 
    } else {
151
 
        // wake up constructor in blocking mode
152
 
        // (we might got disabled before first message arrived)
153
 
        d->initializeCondition.wakeAll();
154
 
    }
155
 
}
156
 
 
157
 
void QV8ProfilerService::messageReceived(const QByteArray &message)
158
 
{
159
 
    Q_D(QV8ProfilerService);
160
 
 
161
 
    QQmlDebugStream ds(message);
162
 
    QByteArray command;
163
 
    QByteArray option;
164
 
    QByteArray title;
165
 
    ds >> command >> option;
166
 
 
167
 
    QMutexLocker lock(&d->initializeMutex);
168
 
 
169
 
    if (command == "V8PROFILER") {
170
 
        ds >>  title;
171
 
        QString titleStr = QString::fromUtf8(title);
172
 
        if (option == "start") {
173
 
            QMetaObject::invokeMethod(this, "startProfiling", Qt::QueuedConnection, Q_ARG(QString, titleStr));
174
 
        } else if (option == "stop" && d->initialized) {
175
 
            QMetaObject::invokeMethod(this, "stopProfiling", Qt::QueuedConnection, Q_ARG(QString, titleStr));
176
 
            QMetaObject::invokeMethod(this, "sendProfilingData", Qt::QueuedConnection);
177
 
        }
178
 
        d->initialized = true;
179
 
    }
180
 
 
181
 
    if (command == "V8SNAPSHOT") {
182
 
        if (option == "full")
183
 
            QMetaObject::invokeMethod(this, "takeSnapshot", Qt::QueuedConnection);
184
 
        else if (option == "delete") {
185
 
            QMetaObject::invokeMethod(this, "deleteSnapshots", Qt::QueuedConnection);
186
 
        }
187
 
    }
188
 
 
189
 
    // wake up constructor in blocking mode
190
 
    d->initializeCondition.wakeAll();
191
 
 
192
 
    QQmlDebugService::messageReceived(message);
193
 
}
194
 
 
195
 
void QV8ProfilerService::startProfiling(const QString &title)
196
 
{
197
 
    Q_D(QV8ProfilerService);
198
 
    // Start Profiling
199
 
 
200
 
    if (d->m_ongoing.contains(title))
201
 
        return;
202
 
 
203
 
//    v8::Handle<v8::String> v8title = v8::String::New(reinterpret_cast<const uint16_t*>(title.data()), title.size());
204
 
    // ### FIXME: v4
205
 
//    v8::CpuProfiler::StartProfiling(v8title);
206
 
 
207
 
    d->m_ongoing.append(title);
208
 
 
209
 
    // indicate profiling started
210
 
    QByteArray data;
211
 
    QQmlDebugStream ds(&data, QIODevice::WriteOnly);
212
 
    ds << (int)QV8ProfilerService::V8Started;
213
 
 
214
 
    sendMessage(data);
215
 
}
216
 
 
217
 
void QV8ProfilerService::stopProfiling(const QString &title)
218
 
{
219
 
    Q_D(QV8ProfilerService);
220
 
    // Stop profiling
221
 
 
222
 
    if (!d->m_ongoing.contains(title))
223
 
        return;
224
 
    d->m_ongoing.removeOne(title);
225
 
 
226
 
#if 0
227
 
    // ### FIXME: v4
228
 
    v8::HandleScope handle_scope;
229
 
    v8::Handle<v8::String> v8title = v8::String::New(reinterpret_cast<const uint16_t*>(title.data()), title.size());
230
 
    const v8::CpuProfile *cpuProfile = v8::CpuProfiler::StopProfiling(v8title);
231
 
    if (cpuProfile) {
232
 
        // can happen at start
233
 
        const v8::CpuProfileNode *rootNode = cpuProfile->GetTopDownRoot();
234
 
        d->printProfileTree(rootNode);
235
 
    } else {
236
 
#endif
237
 
        // indicate completion, even without data
238
 
        QByteArray data;
239
 
        QQmlDebugStream ds(&data, QIODevice::WriteOnly);
240
 
        ds << (int)QV8ProfilerService::V8Complete;
241
 
 
242
 
        sendMessage(data);
243
 
#if 0
244
 
    }
245
 
#endif
246
 
}
247
 
 
248
 
void QV8ProfilerService::takeSnapshot()
249
 
{
250
 
//    Q_D(QV8ProfilerService);
251
 
    // ### FIXME: v4
252
 
//    d->takeSnapshot(v8::HeapSnapshot::kFull);
253
 
}
254
 
 
255
 
void QV8ProfilerService::deleteSnapshots()
256
 
{
257
 
    // ### FIXME: v4
258
 
//    v8::HeapProfiler::DeleteAllSnapshots();
259
 
}
260
 
 
261
 
void QV8ProfilerService::sendProfilingData()
262
 
{
263
 
//    Q_D(QV8ProfilerService);
264
 
    // Send messages to client
265
 
    // ### FIXME: v4
266
 
//    d->sendMessages();
267
 
}
268
 
 
269
 
#if 0
270
 
// ### FIXME: v4
271
 
void QV8ProfilerServicePrivate::printProfileTree(const v8::CpuProfileNode *node, int level)
272
 
{
273
 
    for (int index = 0 ; index < node->GetChildrenCount() ; index++) {
274
 
        const v8::CpuProfileNode* childNode = node->GetChild(index);
275
 
        QString scriptResourceName = QJSConverter::toString(childNode->GetScriptResourceName());
276
 
        if (scriptResourceName.length() > 0) {
277
 
 
278
 
            QV8ProfilerData rd = {(int)QV8ProfilerService::V8Entry, scriptResourceName,
279
 
                QJSConverter::toString(childNode->GetFunctionName()),
280
 
                childNode->GetLineNumber(), childNode->GetTotalTime(), childNode->GetSelfTime(), level};
281
 
            m_data.append(rd);
282
 
 
283
 
            // different nodes might have common children: fix at client side
284
 
            if (childNode->GetChildrenCount() > 0) {
285
 
                printProfileTree(childNode, level+1);
286
 
            }
287
 
        }
288
 
    }
289
 
}
290
 
 
291
 
void QV8ProfilerServicePrivate::takeSnapshot(v8::HeapSnapshot::Type snapshotType)
292
 
{
293
 
    Q_Q(QV8ProfilerService);
294
 
 
295
 
    v8::HandleScope scope;
296
 
    v8::Handle<v8::String> title = v8::String::New("");
297
 
 
298
 
    DebugServiceOutputStream outputStream;
299
 
    const v8::HeapSnapshot *snapshot = v8::HeapProfiler::TakeSnapshot(title, snapshotType);
300
 
    snapshot->Serialize(&outputStream, v8::HeapSnapshot::kJSON);
301
 
    QList<QByteArray> messages = outputStream.messages;
302
 
 
303
 
    //indicate completion
304
 
    QByteArray data;
305
 
    QQmlDebugStream ds(&data, QIODevice::WriteOnly);
306
 
    ds << (int)QV8ProfilerService::V8SnapshotComplete;
307
 
    messages.append(data);
308
 
 
309
 
    q->sendMessages(messages);
310
 
}
311
 
 
312
 
void QV8ProfilerServicePrivate::sendMessages()
313
 
{
314
 
    Q_Q(QV8ProfilerService);
315
 
 
316
 
    QList<QByteArray> messages;
317
 
    for (int i = 0; i < m_data.count(); ++i)
318
 
        messages.append(m_data.at(i).toByteArray());
319
 
    m_data.clear();
320
 
 
321
 
    //indicate completion
322
 
    QByteArray data;
323
 
    QQmlDebugStream ds(&data, QIODevice::WriteOnly);
324
 
    ds << (int)QV8ProfilerService::V8Complete;
325
 
    messages.append(data);
326
 
 
327
 
    q->sendMessages(messages);
328
 
}
329
 
#endif
330
 
 
331
 
QT_END_NAMESPACE