From c8260f6693d56597cf94306db86a5a8c92344730 Mon Sep 17 00:00:00 2001 From: Debian Qt/KDE Maintainers Date: Sun, 6 Nov 2016 14:01:42 +0000 Subject: [PATCH] revert_c9ffed92 Gbp-Pq: Name revert_c9ffed92.diff --- src/qml/jsruntime/qv4qobjectwrapper.cpp | 10 +---- src/qml/jsruntime/qv4qobjectwrapper_p.h | 2 +- src/qml/qml/qqmldata_p.h | 2 +- src/qml/qml/qqmlengine.cpp | 11 +++-- src/qml/qml/qqmlpropertycache.cpp | 14 ++----- src/qml/qml/qqmlpropertycache_p.h | 16 -------- src/quick/items/qquickitem.cpp | 41 ++++--------------- src/quick/items/qquickitem.h | 2 - src/quick/items/qquickitem_p.h | 4 +- src/quick/items/qquickview.cpp | 25 +++++++++-- src/quick/items/qquickview_p.h | 29 +++++++++++++ src/quick/items/qquickwindowmodule.cpp | 7 ++-- .../auto/quick/qquickitem/tst_qquickitem.cpp | 26 ++++++------ 13 files changed, 93 insertions(+), 96 deletions(-) diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index 2c9fc8f9d..612b204e3 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -674,14 +674,8 @@ bool QObjectWrapper::isEqualTo(Managed *a, Managed *b) ReturnedValue QObjectWrapper::create(ExecutionEngine *engine, QObject *object) { - if (QJSEngine *jsEngine = engine->jsEngine()) { - if (QQmlPropertyCache *cache = QQmlData::ensurePropertyCache(jsEngine, object)) { - ReturnedValue result = QV4::Encode::null(); - void *args[] = { &result, &engine }; - if (cache->callJSFactoryMethod(object, args)) - return result; - } - } + if (engine->jsEngine()) + QQmlData::ensurePropertyCache(engine->jsEngine(), object); return (engine->memoryManager->allocObject(object))->asReturnedValue(); } diff --git a/src/qml/jsruntime/qv4qobjectwrapper_p.h b/src/qml/jsruntime/qv4qobjectwrapper_p.h index 9c5862b80..f101f352f 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper_p.h +++ b/src/qml/jsruntime/qv4qobjectwrapper_p.h @@ -77,7 +77,7 @@ namespace Heap { struct QQmlValueTypeWrapper; -struct Q_QML_EXPORT QObjectWrapper : Object { +struct QObjectWrapper : Object { QObjectWrapper(QObject *object); QPointer object; }; diff --git a/src/qml/qml/qqmldata_p.h b/src/qml/qml/qqmldata_p.h index 7ccab5746..ad2456a68 100644 --- a/src/qml/qml/qqmldata_p.h +++ b/src/qml/qml/qqmldata_p.h @@ -223,7 +223,7 @@ public: static inline void flushPendingBinding(QObject *, int coreIndex); - static QQmlPropertyCache *ensurePropertyCache(QJSEngine *engine, QObject *object); + static void ensurePropertyCache(QJSEngine *engine, QObject *object); private: // For attachedProperties diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 71795a253..517324a80 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -1800,15 +1800,14 @@ void QQmlData::setPendingBindingBit(QObject *obj, int coreIndex) QQmlData_setBit(this, obj, coreIndex * 2 + 1); } -QQmlPropertyCache *QQmlData::ensurePropertyCache(QJSEngine *engine, QObject *object) +void QQmlData::ensurePropertyCache(QJSEngine *engine, QObject *object) { Q_ASSERT(engine); QQmlData *ddata = QQmlData::get(object, /*create*/true); - if (!ddata->propertyCache){ - ddata->propertyCache = QJSEnginePrivate::get(engine)->cache(object); - if (ddata->propertyCache) ddata->propertyCache->addref(); - } - return ddata->propertyCache; + if (ddata->propertyCache) + return; + ddata->propertyCache = QJSEnginePrivate::get(engine)->cache(object); + if (ddata->propertyCache) ddata->propertyCache->addref(); } void QQmlEnginePrivate::sendQuit() diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp index 9c535b8ce..0522aa93e 100644 --- a/src/qml/qml/qqmlpropertycache.cpp +++ b/src/qml/qml/qqmlpropertycache.cpp @@ -240,7 +240,7 @@ Creates a new empty QQmlPropertyCache. QQmlPropertyCache::QQmlPropertyCache(QV4::ExecutionEngine *e) : engine(e), _parent(0), propertyIndexCacheStart(0), methodIndexCacheStart(0), signalHandlerIndexCacheStart(0), _hasPropertyOverrides(false), _ownMetaObject(false), - _metaObject(0), argumentsCache(0), _jsFactoryMethodIndex(-1) + _metaObject(0), argumentsCache(0) { Q_ASSERT(engine); } @@ -251,7 +251,7 @@ Creates a new QQmlPropertyCache of \a metaObject. QQmlPropertyCache::QQmlPropertyCache(QV4::ExecutionEngine *e, const QMetaObject *metaObject) : engine(e), _parent(0), propertyIndexCacheStart(0), methodIndexCacheStart(0), signalHandlerIndexCacheStart(0), _hasPropertyOverrides(false), _ownMetaObject(false), - _metaObject(0), argumentsCache(0), _jsFactoryMethodIndex(-1) + _metaObject(0), argumentsCache(0) { Q_ASSERT(engine); Q_ASSERT(metaObject); @@ -524,16 +524,10 @@ void QQmlPropertyCache::append(const QMetaObject *metaObject, for (int ii = 0; ii < classInfoCount; ++ii) { int idx = ii + classInfoOffset; - const char * const classInfoName = metaObject->classInfo(idx).name(); - if (0 == qstrcmp(classInfoName, "qt_HasQmlAccessors")) { + if (0 == qstrcmp(metaObject->classInfo(idx).name(), "qt_HasQmlAccessors")) { hasFastProperty = true; - } else if (0 == qstrcmp(classInfoName, "DefaultProperty")) { + } else if (0 == qstrcmp(metaObject->classInfo(idx).name(), "DefaultProperty")) { _defaultPropertyName = QString::fromUtf8(metaObject->classInfo(idx).value()); - } else if (0 == qstrcmp(classInfoName, "qt_QmlJSWrapperFactoryMethod")) { - const char * const factoryMethod = metaObject->classInfo(idx).value(); - _jsFactoryMethodIndex = metaObject->indexOfSlot(factoryMethod); - if (_jsFactoryMethodIndex != -1) - _jsFactoryMethodIndex -= metaObject->methodOffset(); } } diff --git a/src/qml/qml/qqmlpropertycache_p.h b/src/qml/qml/qqmlpropertycache_p.h index 830b8398b..96dbc72f3 100644 --- a/src/qml/qml/qqmlpropertycache_p.h +++ b/src/qml/qml/qqmlpropertycache_p.h @@ -80,8 +80,6 @@ class QQmlPropertyCacheCreator; class QQmlPropertyRawData { public: - typedef QObjectPrivate::StaticMetaCallFunction StaticMetaCallFunction; - enum Flag { NoFlags = 0x00000000, ValueTypeFlagMask = 0x0000FFFF, // Flags in valueTypeFlags must fit in this mask @@ -328,8 +326,6 @@ public: void toMetaObjectBuilder(QMetaObjectBuilder &); - inline bool callJSFactoryMethod(QObject *object, void **args) const; - protected: virtual void destroy(); virtual void clear(); @@ -398,7 +394,6 @@ private: QByteArray _dynamicStringData; QString _defaultPropertyName; QQmlPropertyCacheMethodArguments *argumentsCache; - int _jsFactoryMethodIndex; }; // QQmlMetaObject serves as a wrapper around either QMetaObject or QQmlPropertyCache. @@ -567,17 +562,6 @@ int QQmlPropertyCache::signalOffset() const return signalHandlerIndexCacheStart; } -bool QQmlPropertyCache::callJSFactoryMethod(QObject *object, void **args) const -{ - if (_jsFactoryMethodIndex != -1) { - _metaObject->d.static_metacall(object, QMetaObject::InvokeMetaMethod, _jsFactoryMethodIndex, args); - return true; - } - if (_parent) - return _parent->callJSFactoryMethod(object, args); - return false; -} - QQmlMetaObject::QQmlMetaObject() { } diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index 8e53e8b02..aaa7ce04b 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -7067,6 +7067,15 @@ void QQuickItemPrivate::setHasCursorInChild(bool hasCursor) #endif } +void QQuickItemPrivate::markObjects(QV4::ExecutionEngine *e) +{ + Q_Q(QQuickItem); + QV4::QObjectWrapper::markWrapper(q, e); + + foreach (QQuickItem *child, childItems) + QQuickItemPrivate::get(child)->markObjects(e); +} + #ifndef QT_NO_CURSOR /*! @@ -8247,38 +8256,6 @@ QAccessible::Role QQuickItemPrivate::accessibleRole() const } #endif -// helper code to let a visual parent mark its visual children for the garbage collector - -namespace QV4 { -namespace Heap { -struct QQuickItemWrapper : public QObjectWrapper { - QQuickItemWrapper(QQuickItem *item) : QObjectWrapper(item) {} -}; -} -} - -struct QQuickItemWrapper : public QV4::QObjectWrapper { - V4_OBJECT2(QQuickItemWrapper, QV4::QObjectWrapper) - static void markObjects(QV4::Heap::Base *that, QV4::ExecutionEngine *e); -}; - -DEFINE_OBJECT_VTABLE(QQuickItemWrapper); - -void QQuickItemWrapper::markObjects(QV4::Heap::Base *that, QV4::ExecutionEngine *e) -{ - QObjectWrapper::Data *This = static_cast(that); - if (QQuickItem *item = static_cast(This->object.data())) { - foreach (QQuickItem *child, QQuickItemPrivate::get(item)->childItems) - QV4::QObjectWrapper::markWrapper(child, e); - } - QV4::QObjectWrapper::markObjects(that, e); -} - -quint64 QQuickItemPrivate::_q_createJSWrapper(QV4::ExecutionEngine *engine) -{ - return (engine->memoryManager->allocObject(q_func()))->asReturnedValue(); -} - QT_END_NAMESPACE #include diff --git a/src/quick/items/qquickitem.h b/src/quick/items/qquickitem.h index c4ee48fdb..c5c17615e 100644 --- a/src/quick/items/qquickitem.h +++ b/src/quick/items/qquickitem.h @@ -149,7 +149,6 @@ class Q_QUICK_EXPORT QQuickItem : public QObject, public QQmlParserStatus Q_CLASSINFO("DefaultProperty", "data") Q_CLASSINFO("qt_HasQmlAccessors", "true") - Q_CLASSINFO("qt_QmlJSWrapperFactoryMethod", "_q_createJSWrapper(QV4::ExecutionEngine*)") public: enum Flag { @@ -445,7 +444,6 @@ protected: private: Q_PRIVATE_SLOT(d_func(), void _q_resourceObjectDeleted(QObject *)) - Q_PRIVATE_SLOT(d_func(), quint64 _q_createJSWrapper(QV4::ExecutionEngine *)) friend class QQuickWindow; friend class QQuickWindowPrivate; diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h index 8cda5f89c..fed3e88b6 100644 --- a/src/quick/items/qquickitem_p.h +++ b/src/quick/items/qquickitem_p.h @@ -302,7 +302,6 @@ public: void _q_resourceObjectDeleted(QObject *); void _q_windowChanged(QQuickWindow *w); - quint64 _q_createJSWrapper(QV4::ExecutionEngine *engine); enum ChangeType { Geometry = 0x01, @@ -606,6 +605,9 @@ public: virtual void mirrorChange() {} void setHasCursorInChild(bool hasCursor); + + // recursive helper to let a visual parent mark its visual children + void markObjects(QV4::ExecutionEngine *e); }; /* diff --git a/src/quick/items/qquickview.cpp b/src/quick/items/qquickview.cpp index f8973ebfb..f4e400eaf 100644 --- a/src/quick/items/qquickview.cpp +++ b/src/quick/items/qquickview.cpp @@ -56,6 +56,25 @@ QT_BEGIN_NAMESPACE +DEFINE_OBJECT_VTABLE(QV4::QQuickRootItemMarker); + +QV4::Heap::QQuickRootItemMarker *QV4::QQuickRootItemMarker::create(QQmlEngine *engine, QQuickWindow *window) +{ + QV4::ExecutionEngine *e = QQmlEnginePrivate::getV4Engine(engine); + return e->memoryManager->allocObject(window); +} + +void QV4::QQuickRootItemMarker::markObjects(QV4::Heap::Base *that, QV4::ExecutionEngine *e) +{ + QQuickItem *root = static_cast(that)->window->contentItem(); + if (root) { + QQuickItemPrivate *rootPrivate = QQuickItemPrivate::get(root); + rootPrivate->markObjects(e); + } + + QV4::Object::markObjects(that, e); +} + void QQuickViewPrivate::init(QQmlEngine* e) { Q_Q(QQuickView); @@ -69,10 +88,10 @@ void QQuickViewPrivate::init(QQmlEngine* e) engine.data()->setIncubationController(q->incubationController()); { - // The content item has CppOwnership policy (set in QQuickWindow). Ensure the presence of a JS - // wrapper so that the garbage collector can see the policy. QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(engine.data()); - QV4::QObjectWrapper::wrap(v4, contentItem); + QV4::Scope scope(v4); + QV4::Scoped v(scope, QV4::QQuickRootItemMarker::create(engine.data(), q)); + rootItemMarker.set(v4, v); } } diff --git a/src/quick/items/qquickview_p.h b/src/quick/items/qquickview_p.h index fd033daf2..1bbff0de0 100644 --- a/src/quick/items/qquickview_p.h +++ b/src/quick/items/qquickview_p.h @@ -108,8 +108,37 @@ public: QQuickView::ResizeMode resizeMode; QSize initialSize; QElapsedTimer frameTimer; + QV4::PersistentValue rootItemMarker; }; +namespace QV4 { +namespace Heap { + +struct QQuickRootItemMarker : Object { + inline QQuickRootItemMarker(QQuickWindow *window) + : window(window) + { + } + + QQuickWindow *window; +}; + +} + +struct QQuickRootItemMarker : public Object +{ + V4_OBJECT2(QQuickRootItemMarker, Object) + + static Heap::QQuickRootItemMarker *create(QQmlEngine *engine, QQuickWindow *window); + + static void markObjects(QV4::Heap::Base *that, QV4::ExecutionEngine *e); + +}; + + + +} + QT_END_NAMESPACE #endif // QQUICKVIEW_P_H diff --git a/src/quick/items/qquickwindowmodule.cpp b/src/quick/items/qquickwindowmodule.cpp index deb44ce34..e3f62a712 100644 --- a/src/quick/items/qquickwindowmodule.cpp +++ b/src/quick/items/qquickwindowmodule.cpp @@ -105,11 +105,12 @@ void QQuickWindowQmlImpl::classBegin() if (e && !e->incubationController()) e->setIncubationController(incubationController()); } + Q_ASSERT(e); { - // The content item has CppOwnership policy (set in QQuickWindow). Ensure the presence of a JS - // wrapper so that the garbage collector can see the policy. QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(e); - QV4::QObjectWrapper::wrap(v4, d->contentItem); + QV4::Scope scope(v4); + QV4::ScopedObject v(scope, QV4::QQuickRootItemMarker::create(e, this)); + d->rootItemMarker = v; } } diff --git a/tests/auto/quick/qquickitem/tst_qquickitem.cpp b/tests/auto/quick/qquickitem/tst_qquickitem.cpp index 536bb40dc..9fedfb21a 100644 --- a/tests/auto/quick/qquickitem/tst_qquickitem.cpp +++ b/tests/auto/quick/qquickitem/tst_qquickitem.cpp @@ -1771,56 +1771,56 @@ static void gc(QQmlEngine &engine) void tst_qquickitem::visualParentOwnership() { - QQmlEngine engine; - QQmlComponent component(&engine, testFileUrl("visualParentOwnership.qml")); + QQuickView view; + view.setSource(testFileUrl("visualParentOwnership.qml")); - QScopedPointer root(qobject_cast(component.create())); + QQuickItem *root = qobject_cast(view.rootObject()); QVERIFY(root); QVariant newObject; { - QVERIFY(QMetaObject::invokeMethod(root.data(), "createItemWithoutParent", Q_RETURN_ARG(QVariant, newObject))); + QVERIFY(QMetaObject::invokeMethod(root, "createItemWithoutParent", Q_RETURN_ARG(QVariant, newObject))); QPointer newItem = qvariant_cast(newObject); QVERIFY(!newItem.isNull()); QVERIFY(!newItem->parent()); QVERIFY(!newItem->parentItem()); - newItem->setParentItem(root.data()); + newItem->setParentItem(root); - gc(engine); + gc(*view.engine()); QVERIFY(!newItem.isNull()); newItem->setParentItem(0); - gc(engine); + gc(*view.engine()); QVERIFY(newItem.isNull()); } { - QVERIFY(QMetaObject::invokeMethod(root.data(), "createItemWithoutParent", Q_RETURN_ARG(QVariant, newObject))); + QVERIFY(QMetaObject::invokeMethod(root, "createItemWithoutParent", Q_RETURN_ARG(QVariant, newObject))); QPointer firstItem = qvariant_cast(newObject); QVERIFY(!firstItem.isNull()); - firstItem->setParentItem(root.data()); + firstItem->setParentItem(root); - QVERIFY(QMetaObject::invokeMethod(root.data(), "createItemWithoutParent", Q_RETURN_ARG(QVariant, newObject))); + QVERIFY(QMetaObject::invokeMethod(root, "createItemWithoutParent", Q_RETURN_ARG(QVariant, newObject))); QPointer secondItem = qvariant_cast(newObject); QVERIFY(!firstItem.isNull()); secondItem->setParentItem(firstItem); - gc(engine); + gc(*view.engine()); delete firstItem; root->setProperty("keepAliveProperty", newObject); - gc(engine); + gc(*view.engine()); QVERIFY(!secondItem.isNull()); root->setProperty("keepAliveProperty", QVariant()); - gc(engine); + gc(*view.engine()); QVERIFY(secondItem.isNull()); } } -- 2.30.2