aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2013-12-24 10:33:07 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-12-24 10:33:07 +0100
commit751fa46df9bf06a1003df34b3e74c73c079e8626 (patch)
tree1de5e2588702bf8c29030fdfc55115caaa3ff2e2 /src/qml
parent70004585f89f325f398c556d101bfa1833d87b53 (diff)
parentd588ec795bf905d6d4a4827ad74f3d01315e40bf (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.cpp18
-rw-r--r--src/qml/jsruntime/qv4engine.cpp10
-rw-r--r--src/qml/qml.pro2
-rw-r--r--src/qml/qml/ftw/qqmlthread.cpp41
-rw-r--r--src/qml/types/qqmllistmodel.cpp4
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,