From 4a86cbe2ca426143bac4b533a1949a1e1514d65e Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 6 May 2016 11:18:06 +0200 Subject: QAccessibleQuickItem: Implement QAccessibleInterface::window(). The window is required to be able to determine the correct scale factor for the screen when High DPI scaling is active. Task-number: QTBUG-52943 Change-Id: If74914659bd64395db23ccfc752ee35e8d43592f Reviewed-by: Frederik Gladhorn --- src/quick/accessible/qaccessiblequickitem.cpp | 5 +++++ src/quick/accessible/qaccessiblequickitem_p.h | 2 ++ 2 files changed, 7 insertions(+) diff --git a/src/quick/accessible/qaccessiblequickitem.cpp b/src/quick/accessible/qaccessiblequickitem.cpp index 44a2caecec..2ce914c0b6 100644 --- a/src/quick/accessible/qaccessiblequickitem.cpp +++ b/src/quick/accessible/qaccessiblequickitem.cpp @@ -48,6 +48,11 @@ QAccessibleQuickItem::QAccessibleQuickItem(QQuickItem *item) { } +QWindow *QAccessibleQuickItem::window() const +{ + return item()->window(); +} + int QAccessibleQuickItem::childCount() const { return childItems().count(); diff --git a/src/quick/accessible/qaccessiblequickitem_p.h b/src/quick/accessible/qaccessiblequickitem_p.h index 1ec569731e..af9f8db249 100644 --- a/src/quick/accessible/qaccessiblequickitem_p.h +++ b/src/quick/accessible/qaccessiblequickitem_p.h @@ -60,6 +60,8 @@ class QAccessibleQuickItem : public QAccessibleObject, public QAccessibleActionI public: QAccessibleQuickItem(QQuickItem *item); + QWindow *window() const Q_DECL_OVERRIDE; + QRect rect() const; QRect viewRect() const; -- cgit v1.2.3 From 65e642f13d5e21d104806179b73dddfeb7b6dc81 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Wed, 4 May 2016 13:51:05 +0200 Subject: Make it possible to call some benchmark functions directly Some benchmarks - such as "elements" - rely on QQmlMetaType::qmlTypeNames(), which is implicitly populated when other benchmarks import for example QtQuick. However when calling them directly, the benchmark data set is much smaller. Therefore let's add QtQuick to the "base" set that is always available. Change-Id: I4b3696a426854195deb1c31ad24d80427da7b340 Reviewed-by: Robin Burchell --- tests/benchmarks/qml/creation/tst_creation.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/benchmarks/qml/creation/tst_creation.cpp b/tests/benchmarks/qml/creation/tst_creation.cpp index 4b985d00f1..38ab577120 100644 --- a/tests/benchmarks/qml/creation/tst_creation.cpp +++ b/tests/benchmarks/qml/creation/tst_creation.cpp @@ -100,6 +100,12 @@ public: tst_creation::tst_creation() { qmlRegisterType("Qt.test", 1, 0, "TestType"); + + // Ensure QtQuick is loaded and imported. Some benchmark like elements() rely on QQmlMetaType::qmlTypeNames() to + // be populated. + QQmlComponent component(&engine); + component.setData("import QtQuick 2.0\nItem{}", QUrl()); + QScopedPointer obj(component.create()); } inline QUrl TEST_FILE(const QString &filename) -- cgit v1.2.3 From 48492b2ee5d2f9ad178982f4c16e895b3083d8df Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Thu, 21 Apr 2016 14:14:08 +0200 Subject: QML: add librarymetrics_performance to the builds. Also make sure that we can easily deploy this test to devices by putting all data inside a qrc file. Change-Id: I175830fde51332b13068b163eba3d68c0535b712 Reviewed-by: Simon Hausmann --- .../qml/librarymetrics_performance/librarymetrics_performance.pro | 2 ++ .../qml/librarymetrics_performance/tst_librarymetrics_performance.cpp | 2 +- tests/benchmarks/qml/qml.pro | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/benchmarks/qml/librarymetrics_performance/librarymetrics_performance.pro b/tests/benchmarks/qml/librarymetrics_performance/librarymetrics_performance.pro index 3bedc0ea18..67f9d3b395 100644 --- a/tests/benchmarks/qml/librarymetrics_performance/librarymetrics_performance.pro +++ b/tests/benchmarks/qml/librarymetrics_performance/librarymetrics_performance.pro @@ -7,3 +7,5 @@ macx:CONFIG -= app_bundle CONFIG += release SOURCES += tst_librarymetrics_performance.cpp + +RESOURCES += data diff --git a/tests/benchmarks/qml/librarymetrics_performance/tst_librarymetrics_performance.cpp b/tests/benchmarks/qml/librarymetrics_performance/tst_librarymetrics_performance.cpp index a83c1479f2..ad72ebc6f0 100644 --- a/tests/benchmarks/qml/librarymetrics_performance/tst_librarymetrics_performance.cpp +++ b/tests/benchmarks/qml/librarymetrics_performance/tst_librarymetrics_performance.cpp @@ -119,7 +119,7 @@ tst_librarymetrics_performance::~tst_librarymetrics_performance() static QUrl testFileUrl(const char * filename) { - return QUrl::fromLocalFile(QString(QLatin1String(filename))); + return QUrl(QLatin1String("qrc:///") + QLatin1String(filename)); } void tst_librarymetrics_performance::metrics_data() diff --git a/tests/benchmarks/qml/qml.pro b/tests/benchmarks/qml/qml.pro index 7969866673..d3ce69c713 100644 --- a/tests/benchmarks/qml/qml.pro +++ b/tests/benchmarks/qml/qml.pro @@ -8,6 +8,7 @@ SUBDIRS += \ qqmlcomponent \ qqmlimage \ qqmlmetaproperty \ + librarymetrics_performance \ # script \ ### FIXME: doesn't build js -- cgit v1.2.3 From 9b8d0bffdafeb4dd9b256113716c07f2c49f3903 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Tue, 3 May 2016 08:31:47 +0200 Subject: Flickable: start movementEndingTimer consistently only on OSX MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Amends 1929fee8e17e9ca66e7fe08faa9ed9fa7fdbb127 to prevent extra bounce at the ends. Task-number: QTBUG-47697 Task-number: QTBUG-53177 Change-Id: I23e63d8e0555e1503ff028ad2f0767b05ef39432 Reviewed-by: Jan Arve Sæther --- src/quick/items/qquickflickable.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index 26c4e66dd4..7d602db57e 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -1392,15 +1392,15 @@ void QQuickFlickable::wheelEvent(QWheelEvent *event) break; case Qt::NoScrollPhase: // default phase with an ordinary wheel mouse case Qt::ScrollUpdate: - if (d->scrollingPhase) { + if (d->scrollingPhase) d->pressed = true; - d->movementEndingTimer.start(MovementEndingTimerInterval, this); - } +#ifdef Q_OS_OSX + d->movementEndingTimer.start(MovementEndingTimerInterval, this); +#endif break; case Qt::ScrollEnd: d->pressed = false; d->scrollingPhase = false; - d->movementEndingTimer.start(MovementEndingTimerInterval, this); d->draggingEnding(); event->accept(); returnToBounds(); -- cgit v1.2.3 From 78ad5069d4925445a9d39579c1f73c7911fc3582 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Wed, 11 May 2016 12:49:52 +0200 Subject: Fix warning about mixing basic font type's pointSize and pixelSize We didn't properly read the font property of TextFieldStyle (which is declared in QML) before writing the pointSize property (see bug report), so it was using the value of a previous assignment. Change-Id: I7746c258d1f3a6e031583da7f007bd0dc4087082 Task-number: QTBUG-52920 Reviewed-by: Simon Hausmann --- src/qml/qml/qqmlvmemetaobject.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index e85b3dc82c..aed5f5af35 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -665,9 +665,10 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void * } else { QV4::MemberData *md = propertiesAsMemberData(); if (md) { - QV4::VariantObject *v = (md->data() + id)->as(); - if (v) - QQml_valueTypeProvider()->readValueType(v->d()->data, a[0], t); + QVariant propertyAsVariant; + if (QV4::VariantObject *v = (md->data() + id)->as()) + propertyAsVariant = v->d()->data; + QQml_valueTypeProvider()->readValueType(propertyAsVariant, a[0], t); } } break; -- cgit v1.2.3 From 74f75a3a120b07bbfe6904512b338db8850874e4 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Mon, 25 Apr 2016 15:01:04 +0200 Subject: V4: Limit call depth by count, not by checking the native stack. Getting the native stack size can be really expensive. For example, on Linux/x86_64 (Ubuntu 15.04), it is at least 200,000 instructions for a single-threaded application. With more threads (like qmlscene) it typically ends up around 1M(!) instructions. Worse, it is called twice in the ExecutionEngine constructor. So, now we limit the depth of JavaScript calls to a fixed number, 1234 by default. This can be changed by setting the environment variable QV4_MAX_CALL_DEPTH to the desired depth. Change-Id: Ic13c8efb2769e64fbc73deee6f6fa39d7c0b7af5 Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4engine.cpp | 109 +++++----------------------------------- src/qml/jsruntime/qv4engine_p.h | 33 ++++++++---- 2 files changed, 36 insertions(+), 106 deletions(-) diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 2560f065cf..49b6dce697 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -105,84 +105,6 @@ static ReturnedValue throwTypeError(CallContext *ctx) return ctx->engine()->throwTypeError(); } -const int MinimumStackSize = 256; // in kbytes - -QT_WARNING_PUSH -QT_WARNING_DISABLE_MSVC(4172) // MSVC 2015: warning C4172: returning address of local variable or temporary: dummy - -quintptr getStackLimit() -{ - quintptr stackLimit; -#if USE(PTHREADS) && !OS(QNX) -# if OS(DARWIN) - pthread_t thread_self = pthread_self(); - void *stackTop = pthread_get_stackaddr_np(thread_self); - stackLimit = reinterpret_cast(stackTop); - quintptr size = 0; - if (pthread_main_np()) { - rlimit limit; - getrlimit(RLIMIT_STACK, &limit); - size = limit.rlim_cur; - } else - size = pthread_get_stacksize_np(thread_self); - stackLimit -= size; -# elif defined(__hppa) - // On some architectures the stack grows upwards. All of these are rather exotic, so simply assume - // everything is fine there. - // Known examples: - // -HP PA-RISC - stackLimit = 0; - -# else - pthread_attr_t attr; -#if HAVE(PTHREAD_NP_H) && OS(FREEBSD) - // on FreeBSD pthread_attr_init() must be called otherwise getting the attrs crashes - if (pthread_attr_init(&attr) == 0 && pthread_attr_get_np(pthread_self(), &attr) == 0) { -#else - if (pthread_getattr_np(pthread_self(), &attr) == 0) { -#endif - void *stackBottom = Q_NULLPTR; - size_t stackSize = 0; - - 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(reinterpret_cast(stackBottom) + stackSize - limit.rlim_cur); - } -# endif - - stackLimit = reinterpret_cast(stackBottom); - } else { - int dummy; - // this is inexact, as part of the stack is used when being called here, - // but let's simply default to 1MB from where the stack is right now - stackLimit = reinterpret_cast(&dummy) - 1024*1024; - } - -# endif -// This is wrong. StackLimit is the currently committed stack size, not the real end. -// only way to get that limit is apparently by using VirtualQuery (Yuck) -//#elif OS(WINDOWS) -// PNT_TIB tib = (PNT_TIB)NtCurrentTeb(); -// stackLimit = static_cast(tib->StackLimit); -#else - int dummy; - // this is inexact, as part of the stack is used when being called here, - // but let's simply default to 1MB from where the stack is right now - // (Note: triggers warning C4172 as of MSVC 2015, returning address of local variable) - stackLimit = reinterpret_cast(&dummy) - 1024*1024; -#endif - - // 256k slack - return stackLimit + MinimumStackSize*1024; -} - -QT_WARNING_POP QJSEngine *ExecutionEngine::jsEngine() const { @@ -194,9 +116,12 @@ QQmlEngine *ExecutionEngine::qmlEngine() const return v8Engine->engine(); } +qint32 ExecutionEngine::maxCallDepth = -1; + ExecutionEngine::ExecutionEngine(EvalISelFactory *factory) : current(0) , hasException(false) + , callDepth(0) , memoryManager(new QV4::MemoryManager(this)) , executableAllocator(new QV4::ExecutableAllocator) , regExpAllocator(new QV4::ExecutableAllocator) @@ -213,6 +138,15 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory) , regExpCache(0) , m_multiplyWrappedQObjects(0) { + if (maxCallDepth == -1) { + bool ok = false; + maxCallDepth = qEnvironmentVariableIntValue("QV4_MAX_CALL_DEPTH", &ok); + if (!ok || maxCallDepth <= 0) { + maxCallDepth = 1234; + } + } + Q_ASSERT(maxCallDepth > 0); + MemoryManager::GCBlocker gcBlocker(memoryManager); if (!factory) { @@ -251,9 +185,6 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory) // set up stack limits jsStackLimit = jsStackBase + JSStackLimit/sizeof(Value); - cStackLimit = getStackLimit(); - if (!recheckCStackLimits()) - qFatal("Fatal: Not enough stack space available for QML. Please increase the process stack size to more than %d KBytes.", MinimumStackSize); identifierTable = new IdentifierTable(this); @@ -1117,22 +1048,6 @@ QQmlError ExecutionEngine::catchExceptionAsQmlError() return error; } -bool ExecutionEngine::recheckCStackLimits() -{ - int dummy; -#ifdef Q_OS_WIN - // ### this is only required on windows, where we currently use heuristics to get the stack limit - if (cStackLimit - reinterpret_cast(&dummy) > 128*1024) - // we're more then 128k away from our stack limit, assume the thread has changed, and - // call getStackLimit -#endif - // this can happen after a thread change - cStackLimit = getStackLimit(); - - return (reinterpret_cast(&dummy) >= cStackLimit); -} - - // Variant conversion code typedef QSet V4ObjectSet; diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h index 4640f3f4cc..7fc880023f 100644 --- a/src/qml/jsruntime/qv4engine_p.h +++ b/src/qml/jsruntime/qv4engine_p.h @@ -75,15 +75,11 @@ namespace CompiledData { struct CompilationUnit; } -#define CHECK_STACK_LIMITS(v4) \ - if ((v4->jsStackTop <= v4->jsStackLimit) && (reinterpret_cast(&v4) >= v4->cStackLimit || v4->recheckCStackLimits())) {} \ - else \ - return v4->throwRangeError(QStringLiteral("Maximum call stack size exceeded.")) - - struct Q_QML_EXPORT ExecutionEngine { private: + static qint32 maxCallDepth; + friend struct ExecutionContextSaver; friend struct ExecutionContext; friend struct Heap::ExecutionContext; @@ -92,6 +88,7 @@ public: Value *jsStackTop; quint32 hasException; + qint32 callDepth; MemoryManager *memoryManager; ExecutableAllocator *executableAllocator; @@ -101,7 +98,6 @@ public: ExecutionContext *currentContext; Value *jsStackLimit; - quintptr cStackLimit; WTF::BumpPointerAllocator *bumperPointerAllocator; // Used by Yarr Regex engine. @@ -431,8 +427,6 @@ public: InternalClass *newClass(const InternalClass &other); - bool recheckCStackLimits(); - // Exception handling Value *exceptionValue; StackTrace exceptionStackTrace; @@ -465,6 +459,8 @@ public: QV4::ReturnedValue metaTypeToJS(int type, const void *data); void assertObjectBelongsToEngine(const Heap::Base &baseObject); + + bool checkStackLimits(ReturnedValue &exception); }; inline void ExecutionEngine::pushContext(Heap::ExecutionContext *context) @@ -517,7 +513,26 @@ inline void Value::mark(ExecutionEngine *e) o->mark(e); } +#define CHECK_STACK_LIMITS(v4) { ReturnedValue e; if ((v4)->checkStackLimits(e)) return e; } \ + ExecutionEngineCallDepthRecorder _executionEngineCallDepthRecorder(v4); + +struct ExecutionEngineCallDepthRecorder +{ + ExecutionEngine *ee; + ExecutionEngineCallDepthRecorder(ExecutionEngine *e): ee(e) { ++ee->callDepth; } + ~ExecutionEngineCallDepthRecorder() { --ee->callDepth; } +}; + +inline bool ExecutionEngine::checkStackLimits(ReturnedValue &exception) +{ + if (Q_UNLIKELY((jsStackTop > jsStackLimit) || (callDepth >= maxCallDepth))) { + exception = throwRangeError(QStringLiteral("Maximum call stack size exceeded.")); + return true; + } + + return false; +} } // namespace QV4 -- cgit v1.2.3 From 6bed1d55b38effa5ccee69423c104dfad374b484 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 26 Oct 2015 12:56:18 -0700 Subject: Remove workaround for the pointer size in bootstrapped tool builds The pointer size is now correctly set in qprocessordetection.h even for bootstrapped builds. Change-Id: I7e6338336dd6468ead24ffff1410d4ba8b1cbdad Reviewed-by: Simon Hausmann Reviewed-by: Erik Verbruggen --- src/qml/jsruntime/qv4value_p.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h index 723afcab54..6bd39355c5 100644 --- a/src/qml/jsruntime/qv4value_p.h +++ b/src/qml/jsruntime/qv4value_p.h @@ -50,11 +50,7 @@ #include "qv4global_p.h" #include -/* We cannot rely on QT_POINTER_SIZE to be set correctly on host builds. In qmldevtools the Value objects - are only used to store primitives, never object pointers. So we can use the 64-bit encoding. */ -#ifdef V4_BOOTSTRAP -#define QV4_USE_64_BIT_VALUE_ENCODING -#elif QT_POINTER_SIZE == 8 +#if QT_POINTER_SIZE == 8 #define QV4_USE_64_BIT_VALUE_ENCODING #endif -- cgit v1.2.3