From 156ce398439bd955f8b231e95e391b703d161e75 Mon Sep 17 00:00:00 2001 From: Caroline Chao Date: Mon, 6 Jan 2014 15:19:37 +0100 Subject: Doc: Add links to Qt Quick Test Reference Documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To TestCase and SignalSpy documentation. Change-Id: I83f18ab107e8d047756568ab2cdddd1eaf5574ec Reviewed-by: Alan Alpert Reviewed-by: Topi Reiniƶ --- src/imports/testlib/signalspy.qdoc | 2 +- src/imports/testlib/testcase.qdoc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/imports/testlib/signalspy.qdoc b/src/imports/testlib/signalspy.qdoc index d6f8621c23..c20e268138 100644 --- a/src/imports/testlib/signalspy.qdoc +++ b/src/imports/testlib/signalspy.qdoc @@ -75,7 +75,7 @@ synchronously. For asynchronous signals, the wait() method can be used to block the test until the signal occurs (or a timeout expires). - \sa TestCase + \sa TestCase, {Qt Quick Test Reference Documentation} */ /*! diff --git a/src/imports/testlib/testcase.qdoc b/src/imports/testlib/testcase.qdoc index 4506209f8e..74d2c57098 100644 --- a/src/imports/testlib/testcase.qdoc +++ b/src/imports/testlib/testcase.qdoc @@ -205,7 +205,7 @@ will fail. Use the \l when and windowShown properties to track when the main window has been shown. - \sa SignalSpy + \sa SignalSpy, {Qt Quick Test Reference Documentation} */ /*! -- cgit v1.2.3 From f03de5497d269fadcddc71794869dddbf8870129 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Tue, 7 Jan 2014 11:10:59 +0100 Subject: Use qDebug for all debug under src/quick/scenegraph. Mixing printf and qDebug can make the output come out of sync. Change-Id: Ia71e71b09cb3bf651010eb2eb652db7899b07f0d Reviewed-by: Robin Burchell --- src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp | 6 +++--- src/quick/scenegraph/coreapi/qsgrenderer.cpp | 2 +- src/quick/scenegraph/qsgadaptationlayer.cpp | 2 +- src/quick/scenegraph/qsgthreadedrenderloop.cpp | 3 ++- src/quick/scenegraph/qsgwindowsrenderloop.cpp | 2 +- src/quick/scenegraph/util/qsgatlastexture.cpp | 2 +- src/quick/scenegraph/util/qsgtexture.cpp | 4 ++-- 7 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp index 8ff68e20bc..b1464a26cc 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp @@ -169,7 +169,7 @@ ShaderManager::Shader *ShaderManager::prepareMaterial(QSGMaterial *material) #ifndef QSG_NO_RENDER_TIMING if (qsg_render_timing) - printf(" - compiling material: %dms\n", (int) qsg_renderer_timer.elapsed()); + qDebug(" - compiling material: %dms", (int) qsg_renderer_timer.elapsed()); if (QQmlProfilerService::enabled) { QQmlProfilerService::sceneGraphFrame( @@ -208,7 +208,7 @@ ShaderManager::Shader *ShaderManager::prepareMaterialNoRewrite(QSGMaterial *mate #ifndef QSG_NO_RENDER_TIMING if (qsg_render_timing) - printf(" - compiling material: %dms\n", (int) qsg_renderer_timer.elapsed()); + qDebug(" - compiling material: %dms", (int) qsg_renderer_timer.elapsed()); if (QQmlProfilerService::enabled) { QQmlProfilerService::sceneGraphFrame( @@ -2249,7 +2249,7 @@ void Renderer::preprocess() void Renderer::render() { if (Q_UNLIKELY(debug_dump)) { - printf("\n\n"); + qDebug("\n"); QSGNodeDumper::dump(rootNode()); } diff --git a/src/quick/scenegraph/coreapi/qsgrenderer.cpp b/src/quick/scenegraph/coreapi/qsgrenderer.cpp index df70b5c5eb..e35bfe5494 100644 --- a/src/quick/scenegraph/coreapi/qsgrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgrenderer.cpp @@ -279,7 +279,7 @@ void QSGRenderer::renderScene(const QSGBindable &bindable) #ifndef QSG_NO_RENDER_TIMING if (qsg_render_timing) { - printf(" - Breakdown of render time: preprocess=%d, updates=%d, binding=%d, render=%d, total=%d\n", + qDebug(" - Breakdown of render time: preprocess=%d, updates=%d, binding=%d, render=%d, total=%d", int(preprocessTime / 1000000), int((updatePassTime - preprocessTime) / 1000000), int((bindTime - updatePassTime) / 1000000), diff --git a/src/quick/scenegraph/qsgadaptationlayer.cpp b/src/quick/scenegraph/qsgadaptationlayer.cpp index 58c843a286..cb9e4bdf88 100644 --- a/src/quick/scenegraph/qsgadaptationlayer.cpp +++ b/src/quick/scenegraph/qsgadaptationlayer.cpp @@ -189,7 +189,7 @@ void QSGDistanceFieldGlyphCache::update() #ifndef QSG_NO_RENDER_TIMING if (qsg_render_timing) { - printf(" - glyphs: count=%d, render=%d, store=%d, total=%d\n", + qDebug(" - glyphs: count=%d, render=%d, store=%d, total=%d", count, int(renderTime/1000000), (int) qsg_render_timer.elapsed() - int(renderTime/1000000), diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp index d779285a44..d8fe947122 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp +++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp @@ -1136,7 +1136,8 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w) #ifndef QSG_NO_RENDER_TIMING if (qsg_render_timing) - qDebug(" - on GUI: polish=%d, lock=%d, block/sync=%d -- animations=%d", + qDebug(" - Gui Thread: window=%p, polish=%d, lock=%d, block/sync=%d -- animations=%d", + w->window, int(polishTime/1000000), int((waitTime - polishTime)/1000000), int((syncTime - waitTime)/1000000), diff --git a/src/quick/scenegraph/qsgwindowsrenderloop.cpp b/src/quick/scenegraph/qsgwindowsrenderloop.cpp index 0b6d42aca6..5d9583cafb 100644 --- a/src/quick/scenegraph/qsgwindowsrenderloop.cpp +++ b/src/quick/scenegraph/qsgwindowsrenderloop.cpp @@ -61,7 +61,7 @@ extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_ #ifdef QSG_RENDER_LOOP_DEBUG static QElapsedTimer qsg_debug_timer; -# define RLDEBUG(x) printf("(%6d) %s : %4d - %s\n", (int) qsg_debug_timer.elapsed(), __FILE__, __LINE__, x) +# define RLDEBUG(x) qDebug("(%6d) %s : %4d - %s", (int) qsg_debug_timer.elapsed(), __FILE__, __LINE__, x) #else # define RLDEBUG(x) #endif diff --git a/src/quick/scenegraph/util/qsgatlastexture.cpp b/src/quick/scenegraph/util/qsgatlastexture.cpp index 75bf0b6e3c..389945849f 100644 --- a/src/quick/scenegraph/util/qsgatlastexture.cpp +++ b/src/quick/scenegraph/util/qsgatlastexture.cpp @@ -375,7 +375,7 @@ bool Atlas::bind(QSGTexture::Filtering filtering) #ifndef QSG_NO_RENDER_TIMING if (qsg_render_timing) { - printf(" - AtlasTexture(%dx%d), uploaded in %d ms\n", + qDebug(" - AtlasTexture(%dx%d), uploaded in %d ms", m_pending_uploads.at(i)->image().width(), m_pending_uploads.at(i)->image().height(), (int) (qsg_renderer_timer.elapsed())); diff --git a/src/quick/scenegraph/util/qsgtexture.cpp b/src/quick/scenegraph/util/qsgtexture.cpp index 51b3bafaf7..df724d8a01 100644 --- a/src/quick/scenegraph/util/qsgtexture.cpp +++ b/src/quick/scenegraph/util/qsgtexture.cpp @@ -629,7 +629,7 @@ void QSGPlainTexture::bind() glDeleteTextures(1, &m_texture_id); #ifndef QSG_NO_RENDER_TIMING if (qsg_render_timing) { - printf(" - texture deleted in %dms (size: %dx%d)\n", + qDebug(" - texture deleted in %dms (size: %dx%d)", (int) qsg_renderer_timer.elapsed(), m_texture_size.width(), m_texture_size.height()); @@ -725,7 +725,7 @@ void QSGPlainTexture::bind() if (qsg_render_timing) { mipmapTime = qsg_renderer_timer.nsecsElapsed(); - printf(" - plaintexture(%dx%d) bind=%d, convert=%d, swizzle=%d (%s->%s), upload=%d, mipmap=%d, total=%d\n", + qDebug(" - plaintexture(%dx%d) bind=%d, convert=%d, swizzle=%d (%s->%s), upload=%d, mipmap=%d, total=%d", m_texture_size.width(), m_texture_size.height(), int(bindTime/1000000), int((convertTime - bindTime)/1000000), -- cgit v1.2.3 From 7e115c5c5e954ab560afccbd04cb295232a0924c Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Tue, 7 Jan 2014 09:59:10 +0100 Subject: [ChangeLog][QtQml] Fix JavaScript Array.pop() not updating the internal array length correctly While the length property was reporting the correct value, the internal array length was out-of-sync. Task-number: QTBUG-35979 Change-Id: I68820a349cf1ce88c6aabc6a2301a8a861018a10 Reviewed-by: Liang Qi Reviewed-by: Lars Knoll --- src/qml/jsruntime/qv4arrayobject.cpp | 2 +- tests/auto/qml/qjsengine/tst_qjsengine.cpp | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp index 1628cfe4da..296471692c 100644 --- a/src/qml/jsruntime/qv4arrayobject.cpp +++ b/src/qml/jsruntime/qv4arrayobject.cpp @@ -276,7 +276,7 @@ ReturnedValue ArrayPrototype::method_pop(CallContext *ctx) if (scope.hasException()) return Encode::undefined(); if (instance->isArrayObject()) - instance->setArrayLengthUnchecked(len - 1); + instance->setArrayLength(len - 1); else instance->put(ctx->engine->id_length, ScopedValue(scope, Primitive::fromDouble(len - 1))); return result.asReturnedValue(); diff --git a/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/tests/auto/qml/qjsengine/tst_qjsengine.cpp index 726f8636b6..a1662b495c 100644 --- a/tests/auto/qml/qjsengine/tst_qjsengine.cpp +++ b/tests/auto/qml/qjsengine/tst_qjsengine.cpp @@ -146,6 +146,8 @@ private slots: void threadedEngine(); void functionDeclarationsInConditionals(); + + void arrayPop_QTBUG_35979(); }; tst_QJSEngine::tst_QJSEngine() @@ -2692,6 +2694,17 @@ void tst_QJSEngine::functionDeclarationsInConditionals() QCOMPARE(result.toBool(), true); } +void tst_QJSEngine::arrayPop_QTBUG_35979() +{ + QJSEngine eng; + QJSValue result = eng.evaluate("" + "var x = [1, 2]\n" + "x.pop()\n" + "x[1] = 3\n" + "x.toString()\n"); + QCOMPARE(result.toString(), QString("1,3")); +} + QTEST_MAIN(tst_QJSEngine) #include "tst_qjsengine.moc" -- cgit v1.2.3 From cb78684aeef3116e6f9f8a538db04256cabd7715 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Tue, 7 Jan 2014 10:09:28 -0800 Subject: Ameliorate Documentation Task-number: QTBUG-33438 Change-Id: I9187513d3b4c68d99c90726288653aae5c553a67 Reviewed-by: Simon Hausmann --- src/qml/doc/src/qmllanguageref/modules/cppplugins.qdoc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/qml/doc/src/qmllanguageref/modules/cppplugins.qdoc b/src/qml/doc/src/qmllanguageref/modules/cppplugins.qdoc index 7ac1d400eb..b5fe941f9f 100644 --- a/src/qml/doc/src/qmllanguageref/modules/cppplugins.qdoc +++ b/src/qml/doc/src/qmllanguageref/modules/cppplugins.qdoc @@ -34,8 +34,9 @@ The \l{QQmlEngine}{QML engine} load C++ plugins for QML. Such plugins are usually provided in a QML extension module, and can - provide types and functionality for use by clients in QML documents - which import the module. + provide types for use by clients in QML documents which import the module. + A module requires at least one type registered in order to be considered + valid. QQmlExtensionPlugin is a plugin interface that makes it possible to create QML extensions that can be loaded dynamically into QML applications. -- cgit v1.2.3 From 5657d00a92b34aa7528dd7cf7401ff7f493b68c5 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Wed, 8 Jan 2014 15:22:46 +0100 Subject: Keys Attached Property: Fix doc reference to nonexistent properties Change-Id: I5e6a0855b3ad10e3adf6cf73b08a7794daf187da Reviewed-by: Frederik Gladhorn --- src/quick/items/qquickitem.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index ecb08c5a7e..c308a7230a 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -851,7 +851,7 @@ bool QQuickKeysAttached::isConnected(const char *signalName) \list 1 \li Items specified in \c forwardTo \li specific key handlers, e.g. onReturnPressed - \li onKeyPress, onKeyRelease handlers + \li onPressed, onReleased handlers \li Item specific key handling, e.g. TextInput key handling \li parent item \endlist @@ -862,7 +862,7 @@ bool QQuickKeysAttached::isConnected(const char *signalName) \li Item specific key handling, e.g. TextInput key handling \li Items specified in \c forwardTo \li specific key handlers, e.g. onReturnPressed - \li onKeyPress, onKeyRelease handlers + \li onPressed, onReleased handlers \li parent item \endlist -- cgit v1.2.3 From 2f9099443d9acd6583e92785afbb38b2e4dcbfd5 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Thu, 19 Dec 2013 10:37:34 +0100 Subject: V4: optimize dominator frontier storage. Changes the dominator frontier storage from a set of basic-blocks for every basic-block to a BasicBlockSet for every basic-block. This new class stores a maximum of 8 nodes in a vector, and switches to a bit vector when going beyond 8 nodes. This is important in two cases: most basic-blocks have 2-3 nodes in the frontier, and an array is faster than a set in these cases. The few cases where the frontier goes beyond 8 nodes, is when a switch statement is used with lots of cases that all fall-through. On regress-74474-003.js this reduces peak memory usage from 1.68G to 60M. The switch statement in this test results in 27000 basic-blocks. Change-Id: I42646522ba9f8642d42a5d70fc6b760bb47ae69f Reviewed-by: Simon Hausmann --- src/qml/compiler/qv4ssa.cpp | 171 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 164 insertions(+), 7 deletions(-) diff --git a/src/qml/compiler/qv4ssa.cpp b/src/qml/compiler/qv4ssa.cpp index 679cf1b3a7..31a1e4cdc4 100644 --- a/src/qml/compiler/qv4ssa.cpp +++ b/src/qml/compiler/qv4ssa.cpp @@ -259,6 +259,152 @@ inline Temp *unescapableTemp(Expr *e, bool variablesCanEscape) } } +class BasicBlockSet +{ + typedef std::vector Numbers; + typedef std::vector Flags; + + Numbers *blockNumbers; + Flags *blockFlags; + QVector allBlocks; + enum { MaxVectorCapacity = 8 }; + + // Q_DISABLE_COPY(BasicBlockSet); disabled because MSVC wants assignment operator for std::vector + +public: + class const_iterator + { + const BasicBlockSet &set; + // ### These two members could go into a union, but clang won't compile (https://codereview.qt-project.org/#change,74259) + Numbers::const_iterator numberIt; + size_t flagIt; + + friend class BasicBlockSet; + const_iterator(const BasicBlockSet &set, bool end) + : set(set) + { + if (end) { + if (set.blockNumbers) + numberIt = set.blockNumbers->end(); + else + flagIt = set.blockFlags->size(); + } else { + if (set.blockNumbers) { + numberIt = set.blockNumbers->begin(); + } else { + flagIt = 0; + size_t eIt = set.blockFlags->size(); + while (flagIt != eIt) { + if (set.blockFlags->operator[](flagIt)) + break; + else + ++flagIt; + } + } + } + } + + public: + BasicBlock *operator*() const + { + if (set.blockNumbers) + return set.allBlocks[*numberIt]; + else + return set.allBlocks[flagIt]; + } + + bool operator==(const const_iterator &other) const + { + if (&set != &other.set) + return false; + if (set.blockNumbers) + return numberIt == other.numberIt; + else + return flagIt == other.flagIt; + } + + bool operator!=(const const_iterator &other) const + { return !(*this == other); } + + const_iterator &operator++() + { + if (set.blockNumbers) { + ++numberIt; + } else { + size_t eIt = set.blockFlags->size(); + while (flagIt != eIt) { + ++flagIt; + if (flagIt == eIt || set.blockFlags->operator[](flagIt)) + break; + } + } + + return *this; + } + }; + + friend class const_iterator; + +public: + BasicBlockSet(): blockNumbers(0), blockFlags(0) {} +#ifdef Q_COMPILER_RVALUE_REFS + BasicBlockSet(BasicBlockSet &&other): blockNumbers(0), blockFlags(0) + { + std::swap(blockNumbers, other.blockNumbers); + std::swap(blockFlags, other.blockFlags); + std::swap(allBlocks, other.allBlocks); + } + +#endif // Q_COMPILER_RVALUE_REFS + ~BasicBlockSet() { delete blockNumbers; delete blockFlags; } + + void init(const QVector &nodes) + { + Q_ASSERT(allBlocks.isEmpty()); + allBlocks = nodes; + blockNumbers = new Numbers; + blockNumbers->reserve(MaxVectorCapacity); + } + + void insert(BasicBlock *bb) + { + if (blockFlags) { + (*blockFlags)[bb->index] = true; + return; + } + + for (std::vector::const_iterator i = blockNumbers->begin(), ei = blockNumbers->end(); + i != ei; ++i) + if (*i == bb->index) + return; + + if (blockNumbers->size() == MaxVectorCapacity) { + blockFlags = new Flags(allBlocks.size(), false); + for (std::vector::const_iterator i = blockNumbers->begin(), ei = blockNumbers->end(); + i != ei; ++i) + blockFlags->operator[](*i) = true; + delete blockNumbers; + blockNumbers = 0; + blockFlags->operator[](bb->index) = true; + } else { + blockNumbers->push_back(bb->index); + } + } + + const_iterator begin() const { return const_iterator(*this, false); } + const_iterator end() const { return const_iterator(*this, true); } + + QList values() const + { + QList result; + + for (const_iterator it = begin(), eit = end(); it != eit; ++it) + result.append(*it); + + return result; + } +}; + class DominatorTree { typedef int BasicBlockIndex; enum { InvalidBasicBlockIndex = -1 }; @@ -273,7 +419,7 @@ class DominatorTree { std::vector semi; // BasicBlock index -> semi dominator BasicBlock index std::vector idom; // BasicBlock index -> immediate dominator BasicBlock index std::vector samedom; // BasicBlock index -> same dominator BasicBlock index - std::vector > DF; // BasicBlock index -> dominator frontier + std::vector DF; // BasicBlock index -> dominator frontier struct DFSTodo { BasicBlockIndex node, parent; @@ -485,18 +631,20 @@ class DominatorTree { } if (np.todo.empty()) { - QSet S; + BasicBlockSet &S = DF[node]; + S.init(nodes); foreach (BasicBlock *y, nodes[node]->out) if (idom[y->index] != node) S.insert(y); foreach (BasicBlockIndex child, np.children) { - foreach (BasicBlock *w, DF[child]) { + const BasicBlockSet &ws = DF[child]; + for (BasicBlockSet::const_iterator it = ws.begin(), eit = ws.end(); it != eit; ++it) { + BasicBlock *w = *it; const BasicBlockIndex wIndex = w->index; if (node == wIndex || !dominates(node, w->index)) S.insert(w); } } - DF[node] = S; DF_done[node] = true; worklist.pop_back(); } @@ -517,7 +665,9 @@ class DominatorTree { #endif // SHOW_SSA #if !defined(QT_NO_DEBUG) && defined(CAN_TAKE_LOSTS_OF_TIME) foreach (BasicBlock *n, nodes) { - foreach (BasicBlock *fBlock, DF[n->index]) { + const BasicBlockSet &fBlocks = DF[n->index]; + for (BasicBlockSet::const_iterator it = fBlocks.begin(), eit = fBlocks.end(); it != eit; ++it) { + BasicBlock *fBlock = *it; Q_ASSERT(!dominates(n, fBlock) || fBlock == n); bool hasDominatedSucc = false; foreach (BasicBlock *succ, fBlock->in) { @@ -545,7 +695,11 @@ public: computeDF(); } - QSet operator[](BasicBlock *n) const { +// QSet operator[](BasicBlock *n) const { +// return DF[n->index]; +// } + + const BasicBlockSet &dominatorFrontier(BasicBlock *n) const { return DF[n->index]; } @@ -1085,7 +1239,10 @@ void convertToSSA(Function *function, const DominatorTree &df) while (!W.isEmpty()) { BasicBlock *n = W.first(); W.removeFirst(); - foreach (BasicBlock *y, df[n]) { + const BasicBlockSet &dominatorFrontierForN = df.dominatorFrontier(n); + for (BasicBlockSet::const_iterator it = dominatorFrontierForN.begin(), eit = dominatorFrontierForN.end(); + it != eit; ++it) { + BasicBlock *y = *it; if (!A_phi[y].contains(a)) { insertPhiNode(a, y, function); A_phi[y].insert(a); -- cgit v1.2.3