Skip to content

Commit

Permalink
Add console.time / console.timeEnd API
Browse files Browse the repository at this point in the history
Implement console.time() / console.timeEnd() as also provided by FireBug
/ Safari.

Task-number: QTBUG-22347
Change-Id: I94fcadbb0c54fdf60dc2559e3ae63d613e29630b
Reviewed-by: Michael Brasser <michael.brasser@nokia.com>
  • Loading branch information
Kai Koehne authored and Qt by Nokia committed Nov 9, 2011
1 parent 2b5432b commit cd633df
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 1 deletion.
2 changes: 1 addition & 1 deletion doc/src/declarative/globalobject.qdoc
Expand Up @@ -203,7 +203,7 @@ May throw exception with code property SQLException.DATABASE_ERR, SQLException.S

\section1 Logging

\c console.log() and \c console.debug() can be used to print information
\c console.log(), \c console.debug(), \c console.time(), and \c console.timeEnd() can be used to print information
to the console. See \l{Debugging QML} for more information.

*/
14 changes: 14 additions & 0 deletions doc/src/declarative/qdeclarativedebugging.qdoc
Expand Up @@ -43,6 +43,20 @@ Rectangle {
}
\endqml

\c console.time and console.timeEnd log the time (in milliseconds) that was spent between
the calls. Both take a string argument that identifies the measurement. For example:

\qml
function f() {
console.time("wholeFunction");
console.time("firstPart");
// first part
console.timeEnd("firstPart");
// second part
console.timeEnd("wholeFunction");
}
\endqml

\section1 Debugging Transitions

When a transition doesn't look quite right, it can be helpful to view it in slow
Expand Down
22 changes: 22 additions & 0 deletions src/declarative/qml/v8/qdeclarativebuiltinfunctions.cpp
Expand Up @@ -92,6 +92,28 @@ v8::Handle<v8::Value> print(const v8::Arguments &args)
return v8::Undefined();
}

v8::Handle<v8::Value> consoleTime(const v8::Arguments &args)
{
if (args.Length() != 1)
V8THROW_ERROR("console.time(): Invalid arguments");
QString name = V8ENGINE()->toString(args[0]);
V8ENGINE()->startTimer(name);
return v8::Undefined();
}

v8::Handle<v8::Value> consoleTimeEnd(const v8::Arguments &args)
{
if (args.Length() != 1)
V8THROW_ERROR("console.time(): Invalid arguments");
QString name = V8ENGINE()->toString(args[0]);
bool wasRunning;
qint64 elapsed = V8ENGINE()->stopTimer(name, &wasRunning);
if (wasRunning) {
qDebug("%s: %llims", qPrintable(name), elapsed);
}
return v8::Undefined();
}

v8::Handle<v8::Value> stringArg(const v8::Arguments &args)
{
QString value = V8ENGINE()->toString(args.This()->ToString());
Expand Down
2 changes: 2 additions & 0 deletions src/declarative/qml/v8/qdeclarativebuiltinfunctions_p.h
Expand Up @@ -91,6 +91,8 @@ v8::Handle<v8::Value> qsTr(const v8::Arguments &args);
v8::Handle<v8::Value> qsTrNoOp(const v8::Arguments &args);
v8::Handle<v8::Value> qsTrId(const v8::Arguments &args);
v8::Handle<v8::Value> qsTrIdNoOp(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> stringArg(const v8::Arguments &args);
}

Expand Down
22 changes: 22 additions & 0 deletions src/declarative/qml/v8/qv8engine.cpp
Expand Up @@ -519,10 +519,14 @@ void QV8Engine::initializeGlobal(v8::Handle<v8::Object> global)
{
using namespace QDeclarativeBuiltinFunctions;
v8::Local<v8::Function> printFn = V8FUNCTION(print, this);
v8::Local<v8::Function> consoleTimeFn = V8FUNCTION(consoleTime, this);
v8::Local<v8::Function> consoleTimeEndFn = V8FUNCTION(consoleTimeEnd, this);

v8::Local<v8::Object> console = v8::Object::New();
console->Set(v8::String::New("log"), printFn);
console->Set(v8::String::New("debug"), printFn);
console->Set(v8::String::New("time"), consoleTimeFn);
console->Set(v8::String::New("timeEnd"), consoleTimeEndFn);

v8::Local<v8::Object> qt = v8::Object::New();

Expand Down Expand Up @@ -1398,6 +1402,24 @@ void QV8Engine::emitSignalHandlerException()
emit q->signalHandlerException(scriptValueFromInternal(uncaughtException()));
}

void QV8Engine::startTimer(const QString &timerName)
{
if (!m_time.isValid())
m_time.start();
m_startedTimers[timerName] = m_time.elapsed();
}

qint64 QV8Engine::stopTimer(const QString &timerName, bool *wasRunning)
{
if (!m_startedTimers.contains(timerName)) {
*wasRunning = false;
return 0;
}
*wasRunning = true;
qint64 startedAt = m_startedTimers.take(timerName);
return m_time.elapsed() - startedAt;
}

QThreadStorage<QV8GCCallback::ThreadData *> QV8GCCallback::threadData;
void QV8GCCallback::initializeThreadData()
{
Expand Down
8 changes: 8 additions & 0 deletions src/declarative/qml/v8/qv8engine_p.h
Expand Up @@ -59,6 +59,7 @@
#include <QtCore/qmutex.h>
#include <QtCore/qstack.h>
#include <QtCore/qstringlist.h>
#include <QtCore/QElapsedTimer>

#include <private/qv8_p.h>
#include <qjsengine.h>
Expand Down Expand Up @@ -405,6 +406,10 @@ class Q_DECLARATIVE_EXPORT QV8Engine

void emitSignalHandlerException();

// used for console.time(), console.timeEnd()
void startTimer(const QString &timerName);
qint64 stopTimer(const QString &timerName, bool *wasRunning);

QObject *qtObjectFromJS(v8::Handle<v8::Value> value);
QSet<int> visitedConversionObjects;
protected:
Expand Down Expand Up @@ -436,6 +441,9 @@ class Q_DECLARATIVE_EXPORT QV8Engine

Exception m_exception;

QElapsedTimer m_time;
QHash<QString, qint64> m_startedTimers;

QVariant toBasicVariant(v8::Handle<v8::Value>);

void initializeGlobal(v8::Handle<v8::Object>);
Expand Down

0 comments on commit cd633df

Please sign in to comment.