Added console.trace, console.profile, console.profileEnd.
Change-Id: Icc38ddd550989eaba0085ece120695a13ec17322
Reviewed-by: Kai Koehne <kai.koehne@nokia.com>
traceInstance();
}
+bool QDeclarativeDebugTrace::startProfiling()
+{
+ return traceInstance()->startProfilingImpl();
+}
+
+bool QDeclarativeDebugTrace::stopProfiling()
+{
+ return traceInstance()->stopProfilingImpl();
+}
+
void QDeclarativeDebugTrace::addEvent(EventType t)
{
- if (QDeclarativeDebugService::isDebuggingEnabled())
- traceInstance()->addEventImpl(t);
+ traceInstance()->addEventImpl(t);
}
void QDeclarativeDebugTrace::startRange(RangeType t)
{
- if (QDeclarativeDebugService::isDebuggingEnabled())
- traceInstance()->startRangeImpl(t);
+ traceInstance()->startRangeImpl(t);
}
void QDeclarativeDebugTrace::rangeData(RangeType t, const QString &data)
{
- if (QDeclarativeDebugService::isDebuggingEnabled())
- traceInstance()->rangeDataImpl(t, data);
+ traceInstance()->rangeDataImpl(t, data);
}
void QDeclarativeDebugTrace::rangeData(RangeType t, const QUrl &data)
{
- if (QDeclarativeDebugService::isDebuggingEnabled())
- traceInstance()->rangeDataImpl(t, data);
+ traceInstance()->rangeDataImpl(t, data);
}
void QDeclarativeDebugTrace::rangeLocation(RangeType t, const QString &fileName, int line)
{
- if (QDeclarativeDebugService::isDebuggingEnabled())
- traceInstance()->rangeLocationImpl(t, fileName, line);
+ traceInstance()->rangeLocationImpl(t, fileName, line);
}
void QDeclarativeDebugTrace::rangeLocation(RangeType t, const QUrl &fileName, int line)
{
- if (QDeclarativeDebugService::isDebuggingEnabled())
- traceInstance()->rangeLocationImpl(t, fileName, line);
+ traceInstance()->rangeLocationImpl(t, fileName, line);
}
void QDeclarativeDebugTrace::endRange(RangeType t)
{
- if (QDeclarativeDebugService::isDebuggingEnabled())
- traceInstance()->endRangeImpl(t);
+ traceInstance()->endRangeImpl(t);
}
void QDeclarativeDebugTrace::animationFrame(qint64 delta)
{
- Q_ASSERT(QDeclarativeDebugService::isDebuggingEnabled());
traceInstance()->animationFrameImpl(delta);
}
+void QDeclarativeDebugTrace::sendProfilingData()
+{
+ traceInstance()->sendMessages();
+}
+
+bool QDeclarativeDebugTrace::startProfilingImpl()
+{
+ bool success = false;
+ if (!profilingEnabled()) {
+ setProfilingEnabled(true);
+ addEventImpl(StartTrace);
+ success = true;
+ }
+ return success;
+}
+
+bool QDeclarativeDebugTrace::stopProfilingImpl()
+{
+ bool success = false;
+ if (profilingEnabled()) {
+ addEventImpl(EndTrace);
+ setProfilingEnabled(false);
+ success = true;
+ }
+ return success;
+}
+
void QDeclarativeDebugTrace::addEventImpl(EventType event)
{
- if (status() != Enabled || !m_enabled)
+ if (!QDeclarativeDebugService::isDebuggingEnabled() || !m_enabled)
return;
QDeclarativeDebugData ed = {m_timer.nsecsElapsed(), (int)Event, (int)event, QString(), -1, 0, 0};
void QDeclarativeDebugTrace::startRangeImpl(RangeType range)
{
- if (status() != Enabled || !m_enabled)
+ if (!QDeclarativeDebugService::isDebuggingEnabled() || !m_enabled)
return;
QDeclarativeDebugData rd = {m_timer.nsecsElapsed(), (int)RangeStart, (int)range, QString(), -1, 0, 0};
void QDeclarativeDebugTrace::rangeDataImpl(RangeType range, const QString &rData)
{
- if (status() != Enabled || !m_enabled)
+ if (!QDeclarativeDebugService::isDebuggingEnabled() || !m_enabled)
return;
QDeclarativeDebugData rd = {m_timer.nsecsElapsed(), (int)RangeData, (int)range, rData, -1, 0, 0};
void QDeclarativeDebugTrace::rangeDataImpl(RangeType range, const QUrl &rData)
{
- if (status() != Enabled || !m_enabled)
+ if (!QDeclarativeDebugService::isDebuggingEnabled() || !m_enabled)
return;
QDeclarativeDebugData rd = {m_timer.nsecsElapsed(), (int)RangeData, (int)range, rData.toString(QUrl::FormattingOption(0x100)), -1, 0, 0};
void QDeclarativeDebugTrace::rangeLocationImpl(RangeType range, const QString &fileName, int line)
{
- if (status() != Enabled || !m_enabled)
+ if (!QDeclarativeDebugService::isDebuggingEnabled() || !m_enabled)
return;
QDeclarativeDebugData rd = {m_timer.nsecsElapsed(), (int)RangeLocation, (int)range, fileName, line, 0, 0};
void QDeclarativeDebugTrace::rangeLocationImpl(RangeType range, const QUrl &fileName, int line)
{
- if (status() != Enabled || !m_enabled)
+ if (!QDeclarativeDebugService::isDebuggingEnabled() || !m_enabled)
return;
QDeclarativeDebugData rd = {m_timer.nsecsElapsed(), (int)RangeLocation, (int)range, fileName.toString(QUrl::FormattingOption(0x100)), line, 0, 0};
void QDeclarativeDebugTrace::endRangeImpl(RangeType range)
{
- if (status() != Enabled || !m_enabled)
+ if (!QDeclarativeDebugService::isDebuggingEnabled() || !m_enabled)
return;
QDeclarativeDebugData rd = {m_timer.nsecsElapsed(), (int)RangeEnd, (int)range, QString(), -1, 0, 0};
void QDeclarativeDebugTrace::animationFrameImpl(qint64 delta)
{
- if (status() != Enabled || !m_enabled)
+ Q_ASSERT(QDeclarativeDebugService::isDebuggingEnabled());
+ if (!m_enabled)
return;
int animCount = QUnifiedTimer::instance()->runningAnimationCount();
m_data.append(message);
}
+bool QDeclarativeDebugTrace::profilingEnabled()
+{
+ return m_enabled;
+}
+
+void QDeclarativeDebugTrace::setProfilingEnabled(bool enable)
+{
+ m_enabled = enable;
+}
+
/*
Send the messages queued up by processMessage
*/
m_messageReceived = true;
- if (m_enabled != enabled) {
- if (enabled) {
- m_enabled = true;
- addEventImpl(StartTrace);
- } else {
- addEventImpl(EndTrace);
- m_enabled = false;
+ if (enabled) {
+ startProfilingImpl();
+ } else {
+ if (stopProfilingImpl())
sendMessages();
- }
}
}
static void initialize();
+ static bool startProfiling();
+ static bool stopProfiling();
static void addEvent(EventType);
-
static void startRange(RangeType);
static void rangeData(RangeType, const QString &);
static void rangeData(RangeType, const QUrl &);
static void endRange(RangeType);
static void animationFrame(qint64);
+ static void sendProfilingData();
+
QDeclarativeDebugTrace();
~QDeclarativeDebugTrace();
+
protected:
virtual void messageReceived(const QByteArray &);
+
private:
+ bool startProfilingImpl();
+ bool stopProfilingImpl();
void addEventImpl(EventType);
void startRangeImpl(RangeType);
void rangeDataImpl(RangeType, const QString &);
void rangeLocationImpl(RangeType, const QUrl &, int);
void endRangeImpl(RangeType);
void animationFrameImpl(qint64);
- void processMessage(const QDeclarativeDebugData &);
+
+ bool profilingEnabled();
+ void setProfilingEnabled(bool enable);
void sendMessages();
+ void processMessage(const QDeclarativeDebugData &);
+
+private:
QElapsedTimer m_timer;
bool m_enabled;
bool m_messageReceived;
#include <private/qdeclarativelocale_p.h>
#include <private/qv8engine_p.h>
+#include <private/qv8profilerservice_p.h>
+#include <private/qdeclarativedebugtrace_p.h>
+
#include <QtCore/qstring.h>
#include <QtCore/qdatetime.h>
#include <QtCore/qcryptographichash.h>
#include <QtCore/qsize.h>
#include <QtCore/qpoint.h>
#include <QtCore/qurl.h>
+#include <QtCore/qfile.h>
#include <QtCore/qcoreapplication.h>
#include <QtGui/qcolor.h>
return v8::Undefined();
}
+v8::Handle<v8::Value> consoleError(const v8::Arguments &args)
+{
+ return console(Error, args);
+}
+
+v8::Handle<v8::Value> consoleLog(const v8::Arguments &args)
+{
+ //console.log
+ //console.debug
+ //print
+ return console(Log, args);
+}
+
+v8::Handle<v8::Value> consoleProfile(const v8::Arguments &args)
+{
+ //DeclarativeDebugTrace cannot handle nested profiling
+ //although v8 can handle several profiling at once,
+ //we do not allow that. Hence, we pass an empty(default) title
+ Q_UNUSED(args);
+ QString title;
+
+ if (QDeclarativeDebugTrace::startProfiling()) {
+ QV8ProfilerService::instance()->startProfiling(title);
+ qDebug("Profiling started.");
+ } else {
+ qWarning("Profiling is already in progress. First, end current profiling session.");
+ }
+
+ return v8::Undefined();
+}
+
+v8::Handle<v8::Value> consoleProfileEnd(const v8::Arguments &args)
+{
+ //DeclarativeDebugTrace cannot handle nested profiling
+ //although v8 can handle several profiling at once,
+ //we do not allow that. Hence, we pass an empty(default) title
+ Q_UNUSED(args);
+ QString title;
+
+ if (QDeclarativeDebugTrace::stopProfiling()) {
+ QV8ProfilerService *profiler = QV8ProfilerService::instance();
+ profiler->stopProfiling(title);
+ QDeclarativeDebugTrace::sendProfilingData();
+ profiler->sendProfilingData();
+ qDebug("Profiling ended.");
+ } else {
+ qWarning("Profiling was not started.");
+ }
+
+ return v8::Undefined();
+}
+
v8::Handle<v8::Value> consoleTime(const v8::Arguments &args)
{
if (args.Length() != 1)
return v8::Undefined();
}
-v8::Handle<v8::Value> consoleLog(const v8::Arguments &args)
+v8::Handle<v8::Value> consoleTrace(const v8::Arguments &args)
{
- //console.log
- //console.debug
- //print
- return console(Log, args);
+ if (args.Length() != 0)
+ V8THROW_ERROR("console.trace(): Invalid arguments");
+
+ //The v8 default is currently 10 stack frames.
+ v8::Handle<v8::StackTrace> stackTrace =
+ v8::StackTrace::CurrentStackTrace(10, v8::StackTrace::kOverview);
+ int stackCount = stackTrace->GetFrameCount();
+
+ for (uint i = 0; i < stackCount; i++) {
+ v8::Local<v8::StackFrame> frame = stackTrace->GetFrame(i);
+ v8::String::Utf8Value func_name(frame->GetFunctionName());
+ v8::String::Utf8Value script_name(frame->GetScriptName());
+ int lineNumber = frame->GetLineNumber();
+ int columnNumber = frame->GetColumn();
+ qDebug("%s (%s:%d:%d)\n", *func_name, *script_name, lineNumber, columnNumber);
+ }
+ return v8::Undefined();
}
v8::Handle<v8::Value> consoleWarn(const v8::Arguments &args)
return console(Warn, args);
}
-v8::Handle<v8::Value> consoleError(const v8::Arguments &args)
-{
- return console(Error, args);
-}
-
v8::Handle<v8::Value> stringArg(const v8::Arguments &args)
{
QString value = V8ENGINE()->toString(args.This()->ToString());
namespace QDeclarativeBuiltinFunctions
{
v8::Handle<v8::Value> gc(const v8::Arguments &args);
-v8::Handle<v8::Value> consoleLog(const v8::Arguments &args);
-v8::Handle<v8::Value> consoleWarn(const v8::Arguments &args);
v8::Handle<v8::Value> consoleError(const v8::Arguments &args);
+v8::Handle<v8::Value> consoleLog(const v8::Arguments &args);
+v8::Handle<v8::Value> consoleProfile(const v8::Arguments &args);
+v8::Handle<v8::Value> consoleProfileEnd(const v8::Arguments &args);
v8::Handle<v8::Value> consoleTime(const v8::Arguments &args);
v8::Handle<v8::Value> consoleTimeEnd(const v8::Arguments &args);
+v8::Handle<v8::Value> consoleTrace(const v8::Arguments &args);
+v8::Handle<v8::Value> consoleWarn(const v8::Arguments &args);
v8::Handle<v8::Value> isQtObject(const v8::Arguments &args);
v8::Handle<v8::Value> rgba(const v8::Arguments &args);
v8::Handle<v8::Value> hsla(const v8::Arguments &args);
v8::Local<v8::Object> console = v8::Object::New();
v8::Local<v8::Function> consoleLogFn = V8FUNCTION(consoleLog, this);
- v8::Local<v8::Function> consoleWarnFn = V8FUNCTION(consoleWarn, this);
- v8::Local<v8::Function> consoleErrorFn = V8FUNCTION(consoleError, this);
- v8::Local<v8::Function> consoleTimeFn = V8FUNCTION(consoleTime, this);
- v8::Local<v8::Function> consoleTimeEndFn = V8FUNCTION(consoleTimeEnd, this);
- console->Set(v8::String::New("log"), consoleLogFn);
+
console->Set(v8::String::New("debug"), consoleLogFn);
- console->Set(v8::String::New("warn"), consoleWarnFn);
- console->Set(v8::String::New("error"), consoleErrorFn);
- console->Set(v8::String::New("time"), consoleTimeFn);
- console->Set(v8::String::New("timeEnd"), consoleTimeEndFn);
+ console->Set(v8::String::New("error"), V8FUNCTION(consoleError, this));
+ console->Set(v8::String::New("log"), consoleLogFn);
+ console->Set(v8::String::New("profile"), V8FUNCTION(consoleProfile, this));
+ console->Set(v8::String::New("profileEnd"), V8FUNCTION(consoleProfileEnd, this));
+ console->Set(v8::String::New("time"), V8FUNCTION(consoleTime, this));
+ console->Set(v8::String::New("timeEnd"), V8FUNCTION(consoleTimeEnd, this));
+ console->Set(v8::String::New("trace"), V8FUNCTION(consoleTrace, this));
+ console->Set(v8::String::New("warn"), V8FUNCTION(consoleWarn, this));
v8::Local<v8::Object> qt = v8::Object::New();
QFAIL(qPrintable(failMsg));
}
+ QVERIFY(m_client->traceMessages.count());
// must start with "StartTrace"
QCOMPARE(m_client->traceMessages.first().messageType, (int)QDeclarativeDebugTrace::Event);
QCOMPARE(m_client->traceMessages.first().detailType, (int)QDeclarativeDebugTrace::StartTrace);
QFAIL(qPrintable(failMsg));
}
+ QVERIFY(m_client->traceMessages.count());
+
// must start with "StartTrace"
QCOMPARE(m_client->traceMessages.first().messageType, (int)QDeclarativeDebugTrace::Event);
QCOMPARE(m_client->traceMessages.first().detailType, (int)QDeclarativeDebugTrace::StartTrace);
var f = true
var g = {toString: function() { throw new Error('toString'); }}
-
+ console.profile("profile1")
+ console.time("timer1")
console.log("completed", "ok")
console.log("completed ok")
console.debug("completed ok")
console.log(g)
console.log(1, "pong!", new Object)
console.log(1, ["ping","pong"], new Object, 2)
+ console.trace()
+ console.timeEnd("timer1")
+ console.profileEnd("profile1")
console.log(exception) //This has to be at the end
}
}
void createComponent();
void createComponent_pragmaLibrary();
void createQmlObject();
- void consoleLog();
+ void console();
void dateTimeConversion();
void dateTimeFormatting();
void dateTimeFormatting_data();
delete object;
}
-void tst_qdeclarativeqt::consoleLog()
+void tst_qdeclarativeqt::console()
{
- int startLineNumber = 30;
- QUrl testFileUrl = TEST_FILE("consoleLog.qml");
+ QUrl testFileUrl = TEST_FILE("console.qml");
+ QString testException = QString(QLatin1String("%1:%2: ReferenceError: Can't find variable: exception")).arg(testFileUrl.toString()).arg(34);
+ QString testTrace = QString(QLatin1String("onCompleted (%1:%2:%3)\n")).arg(testFileUrl.toString()).arg(31).arg(17);
+ QTest::ignoreMessage(QtDebugMsg, qPrintable(testTrace));
+ QTest::ignoreMessage(QtDebugMsg, "Profiling started.");
+ QTest::ignoreMessage(QtDebugMsg, "Profiling ended.");
QTest::ignoreMessage(QtDebugMsg, "completed ok");
QTest::ignoreMessage(QtDebugMsg, "completed ok");
QTest::ignoreMessage(QtDebugMsg, "completed ok");
QTest::ignoreMessage(QtDebugMsg, "1 pong! Object");
QTest::ignoreMessage(QtDebugMsg, "1 [ping,pong] Object 2");
- QString testException = QString(QLatin1String("%1:%2: ReferenceError: Can't find variable: exception")).arg(testFileUrl.toString());
- QTest::ignoreMessage(QtWarningMsg, qPrintable(testException.arg(startLineNumber++)));
+
+ QTest::ignoreMessage(QtWarningMsg, qPrintable(testException));
+
QDeclarativeComponent component(&engine, testFileUrl);
QObject *object = component.create();