/****************************************************************************
**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Contact: http://www.qt-project.org/
**
** This file is part of the QtDeclarative module of the Qt Toolkit.
**
#include "qv8profilerservice_p.h"
#include "qdeclarativedebugservice_p_p.h"
-#include "qdeclarativeengine_p.h"
-#include "private/qv8profiler_p.h"
-#include "qjsconverter_p.h"
+#include "private/qjsconverter_impl_p.h"
+#include <private/qv8profiler_p.h>
#include <QtCore/QHash>
QT_BEGIN_NAMESPACE
-Q_GLOBAL_STATIC(QV8ProfilerService, v8ServiceInstance)
+Q_GLOBAL_STATIC(QV8ProfilerService, v8ProfilerInstance)
-class ByteArrayOutputStream : public v8::OutputStream
+class DebugServiceOutputStream : public v8::OutputStream
{
- QByteArray *_buffer;
+ QDeclarativeDebugService &_service;
public:
- ByteArrayOutputStream(QByteArray *buffer)
+ DebugServiceOutputStream(QDeclarativeDebugService &service)
: v8::OutputStream(),
- _buffer(buffer) {}
+ _service(service) {}
void EndOfStream() {}
- WriteResult WriteAsciiChunk(char *data, int size)
+ WriteResult WriteAsciiChunk(char *rawData, int size)
{
- QByteArray b(data, size);
- _buffer->append(b);
+ QByteArray data;
+ QDataStream ds(&data, QIODevice::WriteOnly);
+ ds << QV8ProfilerService::V8SnapshotChunk << QByteArray(rawData, size);
+ _service.sendMessage(data);
return kContinue;
}
};
QList<QV8ProfilerData> m_data;
bool initialized;
- QList<QDeclarativeEngine *> engines;
};
QV8ProfilerService::QV8ProfilerService(QObject *parent)
- : QDeclarativeDebugService(*(new QV8ProfilerServicePrivate()), QLatin1String("V8Profiler"), parent)
+ : QDeclarativeDebugService(*(new QV8ProfilerServicePrivate()), QLatin1String("V8Profiler"), 1, parent)
{
Q_D(QV8ProfilerService);
- if (status() == Enabled) {
+
+ if (registerService() == Enabled) {
// ,block mode, client attached
while (!d->initialized)
waitForMessage();
QV8ProfilerService *QV8ProfilerService::instance()
{
- return v8ServiceInstance();
+ return v8ProfilerInstance();
}
-void QV8ProfilerService::addEngine(QDeclarativeEngine *engine)
+void QV8ProfilerService::initialize()
{
- Q_D(QV8ProfilerService);
- Q_ASSERT(engine);
- Q_ASSERT(!d->engines.contains(engine));
-
- d->engines.append(engine);
-}
-
-void QV8ProfilerService::removeEngine(QDeclarativeEngine *engine)
-{
- Q_D(QV8ProfilerService);
- Q_ASSERT(engine);
- Q_ASSERT(d->engines.contains(engine));
-
- d->engines.removeOne(engine);
+ // just make sure that the service is properly registered
+ v8ProfilerInstance();
}
void QV8ProfilerService::messageReceived(const QByteArray &message)
if (command == "V8PROFILER") {
ds >> title;
if (option == "start") {
- d->initialized = true;
- startProfiling(QString::fromUtf8(title));
+ QMetaObject::invokeMethod(this, "startProfiling", Qt::QueuedConnection, Q_ARG(QString, QString::fromUtf8(title)));
} else if (option == "stop") {
- stopProfiling(QString::fromUtf8(title));
- // Send messages to client
- d->sendMessages();
+ QMetaObject::invokeMethod(this, "stopProfiling", Qt::QueuedConnection, Q_ARG(QString, QString::fromUtf8(title)));
+ QMetaObject::invokeMethod(this, "sendProfilingData", Qt::QueuedConnection);
}
+ d->initialized = true;
}
if (command == "V8SNAPSHOT") {
- QByteArray snapshotType;
- ds >> snapshotType;
-
- if (snapshotType == "aggregated")
- d->takeSnapshot(v8::HeapSnapshot::kAggregated);
- else if (snapshotType == "full")
- d->takeSnapshot(v8::HeapSnapshot::kFull);
- } else if (command == "deletesnapshots") {
- v8::HeapProfiler::DeleteAllSnapshots();
+ if (option == "full")
+ QMetaObject::invokeMethod(this, "takeSnapshot", Qt::QueuedConnection);
+ else if (option == "delete") {
+ QMetaObject::invokeMethod(this, "deleteSnapshots", Qt::QueuedConnection);
}
+ }
QDeclarativeDebugService::messageReceived(message);
}
v8::HandleScope handle_scope;
v8::Handle<v8::String> v8title = v8::String::New(reinterpret_cast<const uint16_t*>(title.data()), title.size());
const v8::CpuProfile *cpuProfile = v8::CpuProfiler::StopProfiling(v8title);
- const v8::CpuProfileNode *rootNode = cpuProfile->GetTopDownRoot();
+ if (cpuProfile) {
+ // can happen at start
+ const v8::CpuProfileNode *rootNode = cpuProfile->GetTopDownRoot();
+ d->printProfileTree(rootNode);
+ }
+}
- d->printProfileTree(rootNode);
+void QV8ProfilerService::takeSnapshot()
+{
+ Q_D(QV8ProfilerService);
+ d->takeSnapshot(v8::HeapSnapshot::kFull);
+}
+
+void QV8ProfilerService::deleteSnapshots()
+{
+ v8::HeapProfiler::DeleteAllSnapshots();
+}
+
+void QV8ProfilerService::sendProfilingData()
+{
+ Q_D(QV8ProfilerService);
+ // Send messages to client
+ d->sendMessages();
}
void QV8ProfilerServicePrivate::printProfileTree(const v8::CpuProfileNode *node, int level)
{
for (int index = 0 ; index < node->GetChildrenCount() ; index++) {
const v8::CpuProfileNode* childNode = node->GetChild(index);
- if (QV8Engine::toStringStatic(childNode->GetScriptResourceName()).length() > 0) {
+ QString scriptResourceName = QJSConverter::toString(childNode->GetScriptResourceName());
+ if (scriptResourceName.length() > 0) {
- QV8ProfilerData rd = {(int)QV8ProfilerService::V8Entry, QV8Engine::toStringStatic(childNode->GetScriptResourceName()),
- QV8Engine::toStringStatic(childNode->GetFunctionName()),
+ QV8ProfilerData rd = {(int)QV8ProfilerService::V8Entry, scriptResourceName,
+ QJSConverter::toString(childNode->GetFunctionName()),
childNode->GetLineNumber(), childNode->GetTotalTime(), childNode->GetSelfTime(), level};
m_data.append(rd);
v8::HandleScope scope;
v8::Local<v8::String> title = v8::String::New("");
+ DebugServiceOutputStream outputStream(*q);
const v8::HeapSnapshot *snapshot = v8::HeapProfiler::TakeSnapshot(title, snapshotType);
+ snapshot->Serialize(&outputStream, v8::HeapSnapshot::kJSON);
+ //indicate completion
QByteArray data;
QDataStream ds(&data, QIODevice::WriteOnly);
- ds << (int)QV8ProfilerService::V8Snapshot;
-
- ByteArrayOutputStream bos(&data);
- snapshot->Serialize(&bos, v8::HeapSnapshot::kJSON);
+ ds << (int)QV8ProfilerService::V8SnapshotComplete;
q->sendMessage(data);
}
{
Q_Q(QV8ProfilerService);
+ QList<QByteArray> messages;
for (int i = 0; i < m_data.count(); ++i)
- q->sendMessage(m_data.at(i).toByteArray());
+ messages << m_data.at(i).toByteArray();
+ q->sendMessages(messages);
m_data.clear();
//indicate completion