diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2013-12-24 10:33:07 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-12-24 10:33:07 +0100 |
commit | 751fa46df9bf06a1003df34b3e74c73c079e8626 (patch) | |
tree | 1de5e2588702bf8c29030fdfc55115caaa3ff2e2 /src/qml | |
parent | 70004585f89f325f398c556d101bfa1833d87b53 (diff) | |
parent | d588ec795bf905d6d4a4827ad74f3d01315e40bf (diff) |
Merge "Merge remote-tracking branch 'origin/stable' into dev" into refs/staging/dev
Diffstat (limited to 'src/qml')
-rw-r--r-- | src/qml/compiler/qv4ssa.cpp | 18 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4engine.cpp | 10 | ||||
-rw-r--r-- | src/qml/qml.pro | 2 | ||||
-rw-r--r-- | src/qml/qml/ftw/qqmlthread.cpp | 41 | ||||
-rw-r--r-- | src/qml/types/qqmllistmodel.cpp | 4 |
5 files changed, 53 insertions, 22 deletions
diff --git a/src/qml/compiler/qv4ssa.cpp b/src/qml/compiler/qv4ssa.cpp index b3eb6835df..eccdfff623 100644 --- a/src/qml/compiler/qv4ssa.cpp +++ b/src/qml/compiler/qv4ssa.cpp @@ -2330,7 +2330,7 @@ void splitCriticalEdges(Function *f) // (see for example section 4 (Lifetime Analysis) of [Wimmer1]). This algorithm makes sure that the // blocks of a group are scheduled together, with no non-loop blocks in between. This applies // recursively for nested loops. It also schedules groups of if-then-else-endif blocks together for -// the smae reason. +// the same reason. class BlockScheduler { Function *function; @@ -2357,15 +2357,15 @@ class BlockScheduler if (emitted.alreadyProcessed(in)) continue; - // this is a loop, where there in -> candidate edge is the jump back to the top of the loop. if (dominatorTree.dominates(candidate, in)) + // this is a loop, where there in -> candidate edge is the jump back to the top of the loop. continue; return false; // an incoming edge that is not yet emitted, and is not a back-edge } - // postpone everything, and schedule the loop first. if (candidate->isGroupStart()) { + // postpone everything, and schedule the loop first. postponedGroups.push(currentGroup); currentGroup = WorkForGroup(candidate); } @@ -2389,6 +2389,7 @@ class BlockScheduler return next; } + Q_UNREACHABLE(); return 0; } @@ -3476,11 +3477,11 @@ void Optimizer::run(QQmlEnginePrivate *qmlEngine) // block scheduling, so remove those now. // qout << "Cleaning up unreachable basic blocks..." << endl; cleanupBasicBlocks(function, false); - showMeTheCode(function); +// showMeTheCode(function); // qout << "Doing block scheduling..." << endl; startEndLoops = BlockScheduler(function, df).go(); - showMeTheCode(function); +// showMeTheCode(function); #ifndef QT_NO_DEBUG checkCriticalEdges(function->basicBlocks); @@ -3750,3 +3751,10 @@ MoveMapping::Action MoveMapping::schedule(const Move &m, QList<Move> &todo, QLis // References: // [Wimmer1] C. Wimmer and M. Franz. Linear Scan Register Allocation on SSA Form. In Proceedings of // CGO’10, ACM Press, 2010 +// [Wimmer2] C. Wimmer and H. Mossenbock. Optimized Interval Splitting in a Linear Scan Register +// Allocator. In Proceedings of the ACM/USENIX International Conference on Virtual +// Execution Environments, pages 132–141. ACM Press, 2005. +// [Briggs] P. Briggs, K.D. Cooper, T.J. Harvey, and L.T. Simpson. Practical Improvements to the +// Construction and Destruction of Static Single Assignment Form. +// [Appel] A.W. Appel. Modern Compiler Implementation in Java. Second edition, Cambridge +// University Press. diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index dc8c0da321..539bc5ddd6 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -76,6 +76,7 @@ #if USE(PTHREADS) # include <pthread.h> +# include <sys/resource.h> #endif QT_BEGIN_NAMESPACE @@ -113,6 +114,15 @@ quintptr getStackLimit() pthread_attr_getstack(&attr, &stackBottom, &stackSize); pthread_attr_destroy(&attr); +# if defined(Q_OS_ANDROID) + // Bionic pretends that the main thread has a tiny stack; work around it + if (gettid() == getpid()) { + rlimit limit; + getrlimit(RLIMIT_STACK, &limit); + stackBottom = reinterpret_cast<void*>(reinterpret_cast<quintptr>(stackBottom) + stackSize - limit.rlim_cur); + } +# endif + stackLimit = reinterpret_cast<quintptr>(stackBottom); # endif // This is wrong. StackLimit is the currently committed stack size, not the real end. diff --git a/src/qml/qml.pro b/src/qml/qml.pro index b0ea93e9fb..d060b2d8c8 100644 --- a/src/qml/qml.pro +++ b/src/qml/qml.pro @@ -13,7 +13,7 @@ MODULE_PLUGIN_TYPES = \ exists("qqml_enable_gcov") { QMAKE_CXXFLAGS = -fprofile-arcs -ftest-coverage -fno-elide-constructors - LIBS += -lgcov + LIBS_PRIVATE += -lgcov } QMAKE_DOCS = $$PWD/doc/qtqml.qdocconf diff --git a/src/qml/qml/ftw/qqmlthread.cpp b/src/qml/qml/ftw/qqmlthread.cpp index 3accb9dce5..1ea3f25405 100644 --- a/src/qml/qml/ftw/qqmlthread.cpp +++ b/src/qml/qml/ftw/qqmlthread.cpp @@ -179,15 +179,17 @@ void QQmlThreadPrivate::threadEvent() { lock(); - if (m_shutdown) { - quit(); - wakeOne(); - unlock(); - q->shutdownThread(); - } else { - m_threadProcessing = true; + for (;;) { + if (m_shutdown) { + quit(); + wakeOne(); + unlock(); + q->shutdownThread(); + + return; + } else if (!threadList.isEmpty()) { + m_threadProcessing = true; - while (!threadList.isEmpty()) { QQmlThread::Message *message = threadList.first(); unlock(); @@ -197,13 +199,15 @@ void QQmlThreadPrivate::threadEvent() lock(); delete threadList.takeFirst(); - } + } else { + wakeOne(); - wakeOne(); + m_threadProcessing = false; - m_threadProcessing = false; + unlock(); - unlock(); + return; + } } } @@ -228,8 +232,11 @@ void QQmlThread::shutdown() d->lock(); Q_ASSERT(!d->m_shutdown); d->m_shutdown = true; - if (d->threadList.isEmpty() && d->m_threadProcessing == false) + if (d->threadList.isEmpty() && d->m_threadProcessing == false) { d->triggerThreadEvent(); + } else if (d->mainSync) { + d->wakeOne(); + } d->wait(); d->unlock(); d->QThread::wait(); @@ -333,8 +340,14 @@ void QQmlThread::internalCallMethodInMain(Message *message) d->triggerMainEvent(); } - while (d->mainSync && !d->m_shutdown) + while (d->mainSync) { + if (d->m_shutdown) { + delete d->mainSync; + d->mainSync = 0; + break; + } d->wait(); + } d->unlock(); } diff --git a/src/qml/types/qqmllistmodel.cpp b/src/qml/types/qqmllistmodel.cpp index d6d3de8af3..7e441023c9 100644 --- a/src/qml/types/qqmllistmodel.cpp +++ b/src/qml/types/qqmllistmodel.cpp @@ -1508,11 +1508,11 @@ QQmlListModelParser::ListInstruction *QQmlListModelParser::ListModelData::instru Here is an example that uses WorkerScript to periodically append the current time to a list model: - \snippet quick/threading/threadedlistmodel/timedisplay.qml 0 + \snippet ../quick/threading/threadedlistmodel/timedisplay.qml 0 The included file, \tt dataloader.js, looks like this: - \snippet quick/threading/threadedlistmodel/dataloader.js 0 + \snippet ../quick/threading/threadedlistmodel/dataloader.js 0 The timer in the main example sends messages to the worker script by calling \l WorkerScript::sendMessage(). When this message is received, |