From: Aurindam Jana Date: Thu, 10 Nov 2011 14:59:05 +0000 (+0100) Subject: QV8Engine: Console APIs, Extend functionality X-Git-Url: http://git.silmor.de/gitweb/?a=commitdiff_plain;h=0f2188361b996c4d8b8901412cdcebf35bad1e53;p=konrad%2Fqtdeclarative.git QV8Engine: Console APIs, Extend functionality Added console.trace, console.profile, console.profileEnd. Change-Id: Icc38ddd550989eaba0085ece120695a13ec17322 Reviewed-by: Kai Koehne --- diff --git a/src/declarative/debugger/qdeclarativedebugtrace.cpp b/src/declarative/debugger/qdeclarativedebugtrace.cpp index c28a612..f3f8156 100644 --- a/src/declarative/debugger/qdeclarativedebugtrace.cpp +++ b/src/declarative/debugger/qdeclarativedebugtrace.cpp @@ -98,57 +98,86 @@ void QDeclarativeDebugTrace::initialize() 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}; @@ -157,7 +186,7 @@ void QDeclarativeDebugTrace::addEventImpl(EventType event) 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}; @@ -166,7 +195,7 @@ void QDeclarativeDebugTrace::startRangeImpl(RangeType range) 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}; @@ -175,7 +204,7 @@ void QDeclarativeDebugTrace::rangeDataImpl(RangeType range, const QString &rData 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}; @@ -184,7 +213,7 @@ void QDeclarativeDebugTrace::rangeDataImpl(RangeType range, const QUrl &rData) 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}; @@ -193,7 +222,7 @@ void QDeclarativeDebugTrace::rangeLocationImpl(RangeType range, const QString &f 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}; @@ -202,7 +231,7 @@ void QDeclarativeDebugTrace::rangeLocationImpl(RangeType range, const QUrl &file 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}; @@ -211,7 +240,8 @@ void QDeclarativeDebugTrace::endRangeImpl(RangeType range) void QDeclarativeDebugTrace::animationFrameImpl(qint64 delta) { - if (status() != Enabled || !m_enabled) + Q_ASSERT(QDeclarativeDebugService::isDebuggingEnabled()); + if (!m_enabled) return; int animCount = QUnifiedTimer::instance()->runningAnimationCount(); @@ -234,6 +264,16 @@ void QDeclarativeDebugTrace::processMessage(const QDeclarativeDebugData &message 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 */ @@ -262,15 +302,11 @@ void QDeclarativeDebugTrace::messageReceived(const QByteArray &message) 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(); - } } } diff --git a/src/declarative/debugger/qdeclarativedebugtrace_p.h b/src/declarative/debugger/qdeclarativedebugtrace_p.h index bcea4d0..a52c3ea 100644 --- a/src/declarative/debugger/qdeclarativedebugtrace_p.h +++ b/src/declarative/debugger/qdeclarativedebugtrace_p.h @@ -119,8 +119,9 @@ public: 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 &); @@ -129,11 +130,17 @@ public: 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 &); @@ -142,8 +149,13 @@ private: 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; diff --git a/src/declarative/qml/v8/qdeclarativebuiltinfunctions.cpp b/src/declarative/qml/v8/qdeclarativebuiltinfunctions.cpp index 8613ae4..d3d37c2 100644 --- a/src/declarative/qml/v8/qdeclarativebuiltinfunctions.cpp +++ b/src/declarative/qml/v8/qdeclarativebuiltinfunctions.cpp @@ -48,6 +48,9 @@ #include #include +#include +#include + #include #include #include @@ -55,6 +58,7 @@ #include #include #include +#include #include #include @@ -139,6 +143,58 @@ v8::Handle gc(const v8::Arguments &args) return v8::Undefined(); } +v8::Handle consoleError(const v8::Arguments &args) +{ + return console(Error, args); +} + +v8::Handle consoleLog(const v8::Arguments &args) +{ + //console.log + //console.debug + //print + return console(Log, args); +} + +v8::Handle 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 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 consoleTime(const v8::Arguments &args) { if (args.Length() != 1) @@ -161,12 +217,25 @@ v8::Handle consoleTimeEnd(const v8::Arguments &args) return v8::Undefined(); } -v8::Handle consoleLog(const v8::Arguments &args) +v8::Handle 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 stackTrace = + v8::StackTrace::CurrentStackTrace(10, v8::StackTrace::kOverview); + int stackCount = stackTrace->GetFrameCount(); + + for (uint i = 0; i < stackCount; i++) { + v8::Local 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 consoleWarn(const v8::Arguments &args) @@ -174,11 +243,6 @@ v8::Handle consoleWarn(const v8::Arguments &args) return console(Warn, args); } -v8::Handle consoleError(const v8::Arguments &args) -{ - return console(Error, args); -} - v8::Handle stringArg(const v8::Arguments &args) { QString value = V8ENGINE()->toString(args.This()->ToString()); diff --git a/src/declarative/qml/v8/qdeclarativebuiltinfunctions_p.h b/src/declarative/qml/v8/qdeclarativebuiltinfunctions_p.h index 8a4ac06..dee0ffe 100644 --- a/src/declarative/qml/v8/qdeclarativebuiltinfunctions_p.h +++ b/src/declarative/qml/v8/qdeclarativebuiltinfunctions_p.h @@ -61,11 +61,14 @@ QT_BEGIN_NAMESPACE namespace QDeclarativeBuiltinFunctions { v8::Handle gc(const v8::Arguments &args); -v8::Handle consoleLog(const v8::Arguments &args); -v8::Handle consoleWarn(const v8::Arguments &args); v8::Handle consoleError(const v8::Arguments &args); +v8::Handle consoleLog(const v8::Arguments &args); +v8::Handle consoleProfile(const v8::Arguments &args); +v8::Handle consoleProfileEnd(const v8::Arguments &args); v8::Handle consoleTime(const v8::Arguments &args); v8::Handle consoleTimeEnd(const v8::Arguments &args); +v8::Handle consoleTrace(const v8::Arguments &args); +v8::Handle consoleWarn(const v8::Arguments &args); v8::Handle isQtObject(const v8::Arguments &args); v8::Handle rgba(const v8::Arguments &args); v8::Handle hsla(const v8::Arguments &args); diff --git a/src/declarative/qml/v8/qv8engine.cpp b/src/declarative/qml/v8/qv8engine.cpp index 9b29aec..632a8ea 100644 --- a/src/declarative/qml/v8/qv8engine.cpp +++ b/src/declarative/qml/v8/qv8engine.cpp @@ -525,16 +525,16 @@ void QV8Engine::initializeGlobal(v8::Handle global) v8::Local console = v8::Object::New(); v8::Local consoleLogFn = V8FUNCTION(consoleLog, this); - v8::Local consoleWarnFn = V8FUNCTION(consoleWarn, this); - v8::Local consoleErrorFn = V8FUNCTION(consoleError, this); - v8::Local consoleTimeFn = V8FUNCTION(consoleTime, this); - v8::Local 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 qt = v8::Object::New(); diff --git a/tests/auto/declarative/debugger/qdeclarativedebugtrace/tst_qdeclarativedebugtrace.cpp b/tests/auto/declarative/debugger/qdeclarativedebugtrace/tst_qdeclarativedebugtrace.cpp index 3b5311e..0a23a5b 100644 --- a/tests/auto/declarative/debugger/qdeclarativedebugtrace/tst_qdeclarativedebugtrace.cpp +++ b/tests/auto/declarative/debugger/qdeclarativedebugtrace/tst_qdeclarativedebugtrace.cpp @@ -226,6 +226,7 @@ void tst_QDeclarativeDebugTrace::blockingConnectWithTraceEnabled() 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); @@ -249,6 +250,8 @@ void tst_QDeclarativeDebugTrace::blockingConnectWithTraceDisabled() 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); diff --git a/tests/auto/declarative/qdeclarativeqt/data/consoleLog.qml b/tests/auto/declarative/qdeclarativeqt/data/console.qml similarity index 83% rename from tests/auto/declarative/qdeclarativeqt/data/consoleLog.qml rename to tests/auto/declarative/qdeclarativeqt/data/console.qml index 2692abb..634239c 100644 --- a/tests/auto/declarative/qdeclarativeqt/data/consoleLog.qml +++ b/tests/auto/declarative/qdeclarativeqt/data/console.qml @@ -11,7 +11,8 @@ QtObject { 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") @@ -27,6 +28,9 @@ QtObject { 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 } } diff --git a/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp b/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp index 5b3ea5e..6171800 100644 --- a/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp +++ b/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp @@ -78,7 +78,7 @@ private slots: void createComponent(); void createComponent_pragmaLibrary(); void createQmlObject(); - void consoleLog(); + void console(); void dateTimeConversion(); void dateTimeFormatting(); void dateTimeFormatting_data(); @@ -458,10 +458,14 @@ void tst_qdeclarativeqt::createQmlObject() 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"); @@ -479,8 +483,9 @@ void tst_qdeclarativeqt::consoleLog() 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();