diff options
author | Kent Hansen <kent.hansen@nokia.com> | 2012-03-22 22:30:14 +0100 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-05-29 09:00:57 +0200 |
commit | 6318f91dc0bf1ac428037c963b80b7a5d4e1ad30 (patch) | |
tree | 4b307f601d25d9f6c6aee65fbf754893c1fc6a79 /tests/benchmarks | |
parent | 18eba786347c42e0c1c9a2a5f8331624f1779920 (diff) |
Add internal API for accessing V8 handles of QJS types
Make it possible to use the V8 API directly. This might be necessary
in cases where the QJS API is missing some functionality (e.g.,
controlling the V8 profiler), or for performance reasons (e.g.,
avoiding overhead of QJSValue indirection).
The V8 API is clearly more extensive than the QJS API, and QJS will
likely never reach feature parity with it (since that's outside the
scope of QJS). By providing access to the underlying V8 types, users
can still choose to use V8 directly in the (hopefully rare) cases
where the public QJS API isn't sufficient.
Two new functions are introduced:
- qt_QJSEngineV8Context(QJSEngine *) returns a local handle to the
engine's internal V8 context.
- qt_QJSValueV8Value(const QJSValue &) returns a local handle to the
QJSValue's internal V8 value.
The caller is responsible for
- ensuring that a V8 handle scope is in place;
- entering/exiting the QJSEngine's V8 context.
The documentation and tests show how that can be done.
Also added a benchmark for QJSValue that can be used to measure the
effect of using raw V8 API for some common operations.
Change-Id: I680aeb2f67ffe5eeadd432a05c8084e43921a118
Reviewed-by: Jamey Hicks <jamey.hicks@nokia.com>
Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
Diffstat (limited to 'tests/benchmarks')
-rw-r--r-- | tests/benchmarks/script/qjsvalue/qjsvalue.pro | 11 | ||||
-rw-r--r-- | tests/benchmarks/script/qjsvalue/tst_qjsvalue.cpp | 189 | ||||
-rw-r--r-- | tests/benchmarks/script/script.pro | 4 |
3 files changed, 204 insertions, 0 deletions
diff --git a/tests/benchmarks/script/qjsvalue/qjsvalue.pro b/tests/benchmarks/script/qjsvalue/qjsvalue.pro new file mode 100644 index 0000000000..eb78cc179e --- /dev/null +++ b/tests/benchmarks/script/qjsvalue/qjsvalue.pro @@ -0,0 +1,11 @@ +CONFIG += testcase +TEMPLATE = app +TARGET = tst_bench_qjsvalue +DEPENDPATH += . +INCLUDEPATH += . +macx:CONFIG -= app_bundle +CONFIG += release + +SOURCES += tst_qjsvalue.cpp + +QT += core-private v8-private qml-private testlib diff --git a/tests/benchmarks/script/qjsvalue/tst_qjsvalue.cpp b/tests/benchmarks/script/qjsvalue/tst_qjsvalue.cpp new file mode 100644 index 0000000000..aea74bda3a --- /dev/null +++ b/tests/benchmarks/script/qjsvalue/tst_qjsvalue.cpp @@ -0,0 +1,189 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <qtest.h> +#include <QJSEngine> +#include <QJSValue> +#include <private/v8.h> + +QT_BEGIN_NAMESPACE +extern Q_QML_EXPORT v8::Local<v8::Context> qt_QJSEngineV8Context(QJSEngine *); +extern Q_QML_EXPORT v8::Local<v8::Value> qt_QJSValueV8Value(const QJSValue &); +QT_END_NAMESPACE + +class tst_QJSValue : public QObject +{ + Q_OBJECT +public: + tst_QJSValue() {} + +private slots: + void fillArray(); + void fillArray_V8(); + + void property(); + void property_V8(); + + void setProperty(); + void setProperty_V8(); + + void call(); + void call_V8(); +}; + +void tst_QJSValue::fillArray() +{ + QJSEngine eng; + static const int ArrayLength = 10000; + QJSValue array = eng.newArray(ArrayLength); + QBENCHMARK { + for (int i = 0; i < ArrayLength; ++i) + array.setProperty(i, i); + } +} + +void tst_QJSValue::fillArray_V8() +{ + QJSEngine eng; + static const int ArrayLength = 10000; + QJSValue array = eng.newArray(ArrayLength); + + v8::HandleScope handleScope; + v8::Local<v8::Array> v8array = qt_QJSValueV8Value(array).As<v8::Array>(); + QBENCHMARK { + for (int i = 0; i < ArrayLength; ++i) + v8array->Set(i, v8::Number::New(i)); + } +} + +void tst_QJSValue::property() +{ + QJSEngine eng; + QJSValue object = eng.newObject(); + QString propertyName = QString::fromLatin1("foo"); + object.setProperty(propertyName, 123); + QVERIFY(object.property(propertyName).isNumber()); + QBENCHMARK { + object.property(propertyName); + } +} + +void tst_QJSValue::property_V8() +{ + QJSEngine eng; + QJSValue object = eng.newObject(); + QString propertyName = QString::fromLatin1("foo"); + object.setProperty(propertyName, 123); + QVERIFY(object.property(propertyName).isNumber()); + + v8::HandleScope handleScope; + v8::Local<v8::Object> v8object = qt_QJSValueV8Value(object).As<v8::Object>(); + v8::Local<v8::String> v8propertyName = v8::String::New("foo"); + QVERIFY(v8object->Get(v8propertyName)->IsNumber()); + QBENCHMARK { + v8object->Get(v8propertyName); + } +} + +void tst_QJSValue::setProperty() +{ + QJSEngine eng; + QJSValue object = eng.newObject(); + QString propertyName = QString::fromLatin1("foo"); + QJSValue value(123); + QBENCHMARK { + object.setProperty(propertyName, value); + } +} + +void tst_QJSValue::setProperty_V8() +{ + QJSEngine eng; + QJSValue object = eng.newObject(); + + v8::HandleScope handleScope; + // A context scope is needed for v8::Object::Set(), otherwise we crash. + v8::Local<v8::Context> context = qt_QJSEngineV8Context(&eng); + v8::Context::Scope contextScope(context); + + v8::Local<v8::Object> v8object = qt_QJSValueV8Value(object).As<v8::Object>(); + v8::Local<v8::String> v8propertyName = v8::String::New("foo"); + v8::Local<v8::Value> v8value = v8::Number::New(123); + QBENCHMARK { + v8object->Set(v8propertyName, v8value); + } +} + +#define TEST_FUNCTION_SOURCE "(function() { return 123; })" + +void tst_QJSValue::call() +{ + QJSEngine eng; + QJSValue fun = eng.evaluate(TEST_FUNCTION_SOURCE); + QVERIFY(fun.isCallable()); + QJSValueList args; + QVERIFY(fun.call(args).isNumber()); + QBENCHMARK { + fun.call(args); + } +} + +void tst_QJSValue::call_V8() +{ + QJSEngine eng; + QJSValue fun = eng.evaluate(TEST_FUNCTION_SOURCE); + QVERIFY(fun.isCallable()); + + v8::HandleScope handleScope; + v8::Local<v8::Context> context = qt_QJSEngineV8Context(&eng); + v8::Context::Scope contextScope(context); + + v8::Local<v8::Function> v8fun = qt_QJSValueV8Value(fun).As<v8::Function>(); + v8::Local<v8::Object> v8thisObject = v8::Object::New(); + QVERIFY(v8fun->Call(v8thisObject, /*argc=*/0, /*argv=*/0)->IsNumber()); + QBENCHMARK { + v8fun->Call(v8thisObject, /*argc=*/0, /*argv=*/0); + } +} + +QTEST_MAIN(tst_QJSValue) + +#include "tst_qjsvalue.moc" diff --git a/tests/benchmarks/script/script.pro b/tests/benchmarks/script/script.pro new file mode 100644 index 0000000000..37dc03801d --- /dev/null +++ b/tests/benchmarks/script/script.pro @@ -0,0 +1,4 @@ +TEMPLATE = subdirs + +SUBDIRS += \ + qjsvalue |