diff options
author | Simon Hausmann <simon.hausmann@theqtcompany.com> | 2015-04-09 16:07:08 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@theqtcompany.com> | 2015-04-16 13:41:05 +0000 |
commit | 3aeacf42168339a914cde039c89a5f3d56bab803 (patch) | |
tree | 5cba28ec6072b6c9f73e8e05f9ed5edc3f46ac39 /src | |
parent | 379342c64db71745edb2bf9a9a100fd1798dbf69 (diff) |
Speed up creation of objects without script bindings
Avoid the creation of the QML binding wrappers if we don't need it, by
moving the creation into a function that creates it on demand.
Change-Id: I1af6a8507a114c1a0b83374704981b7ed4c4a3fc
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/qml/qqmlobjectcreator.cpp | 54 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator_p.h | 5 |
2 files changed, 31 insertions, 28 deletions
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index 76c4537103..6b815677a3 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -113,6 +113,7 @@ void QQmlObjectCreator::init(QQmlContextData *providedParentContext) { parentContext = providedParentContext; engine = parentContext->engine; + v4 = QV8Engine::getV4(engine); if (!compiledData->isInitialized()) compiledData->initialize(engine); @@ -126,7 +127,7 @@ void QQmlObjectCreator::init(QQmlContextData *providedParentContext) _ddata = 0; _propertyCache = 0; _vmeMetaObject = 0; - _qmlContext = 0; + _qmlBindingWrapper = 0; } QQmlObjectCreator::~QQmlObjectCreator() @@ -187,7 +188,6 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI sharedState->rootContext->isRootObjectInCreation = true; } - QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine); QV4::Scope scope(v4); Q_ASSERT(sharedState->allJavaScriptObjects || topLevelCreator); @@ -256,20 +256,15 @@ bool QQmlObjectCreator::populateDeferredProperties(QObject *instance) QObject *scopeObject = instance; qSwap(_scopeObject, scopeObject); - QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine); QV4::Scope valueScope(v4); Q_ASSERT(topLevelCreator); Q_ASSERT(!sharedState->allJavaScriptObjects); sharedState->allJavaScriptObjects = valueScope.alloc(compiledData->totalObjectCount); - QV4::ScopedObject qmlScope(valueScope, QV4::QmlContextWrapper::qmlScope(v4, context, _scopeObject)); - QV4::ScopedContext global(valueScope, valueScope.engine->rootContext()); - QV4::Scoped<QV4::QmlBindingWrapper> qmlBindingWrapper(valueScope, v4->memoryManager->alloc<QV4::QmlBindingWrapper>(global, qmlScope)); - // ### GC - QV4::ExecutionContext *qmlContext = QV4::ScopedContext(valueScope, qmlBindingWrapper->context()); + QV4::Value *qmlBindingWrapper = valueScope.alloc(1); - qSwap(_qmlContext, qmlContext); + qSwap(_qmlBindingWrapper, qmlBindingWrapper); qSwap(_propertyCache, cache); qSwap(_qobject, instance); @@ -291,7 +286,7 @@ bool QQmlObjectCreator::populateDeferredProperties(QObject *instance) qSwap(_qobject, instance); qSwap(_propertyCache, cache); - qSwap(_qmlContext, qmlContext); + qSwap(_qmlBindingWrapper, qmlBindingWrapper); qSwap(_scopeObject, scopeObject); phase = ObjectsCreated; @@ -306,7 +301,6 @@ void QQmlObjectCreator::setPropertyValue(QQmlPropertyData *property, const QV4:: int propertyWriteStatus = -1; void *argv[] = { 0, 0, &propertyWriteStatus, &propertyWriteFlags }; - QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine); QV4::Scope scope(v4); int propertyType = property->propType; @@ -826,8 +820,9 @@ bool QQmlObjectCreator::setPropertyBinding(QQmlPropertyData *property, const QV4 if (binding->type == QV4::CompiledData::Binding::Type_Script) { QV4::Function *runtimeFunction = compiledData->compilationUnit->runtimeFunctions[binding->value.compiledScriptIndex]; - QV4::Scope scope(_qmlContext); - QV4::ScopedFunctionObject function(scope, QV4::FunctionObject::createScriptFunction(_qmlContext, runtimeFunction, /*createProto*/ false)); + QV4::Scope scope(v4); + QV4::ScopedContext qmlContext(scope, currentQmlContext()); + QV4::ScopedFunctionObject function(scope, QV4::FunctionObject::createScriptFunction(qmlContext, runtimeFunction, /*createProto*/ false)); if (binding->flags & QV4::CompiledData::Binding::IsSignalHandlerExpression) { int signalIndex = _propertyCache->methodIndexToSignalIndex(property->coreIndex); @@ -946,7 +941,6 @@ bool QQmlObjectCreator::setPropertyBinding(QQmlPropertyData *property, const QV4 } } else if (property->propType == QMetaType::QVariant) { if (property->isVarProperty()) { - QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine); QV4::Scope scope(v4); QV4::ScopedValue wrappedObject(scope, QV4::QObjectWrapper::wrap(QV8Engine::getV4(engine), createdSubObject)); _vmeMetaObject->setVMEProperty(property->coreIndex, wrappedObject); @@ -993,8 +987,9 @@ bool QQmlObjectCreator::setPropertyBinding(QQmlPropertyData *property, const QV4 void QQmlObjectCreator::setupFunctions() { - QV4::Scope scope(_qmlContext); + QV4::Scope scope(v4); QV4::ScopedValue function(scope); + QV4::ScopedContext qmlContext(scope, currentQmlContext()); const quint32 *functionIdx = _compiledObject->functionOffsetTable(); for (quint32 i = 0; i < _compiledObject->nFunctions; ++i, ++functionIdx) { @@ -1005,7 +1000,7 @@ void QQmlObjectCreator::setupFunctions() if (!property->isVMEFunction()) continue; - function = QV4::FunctionObject::createScriptFunction(_qmlContext, runtimeFunction); + function = QV4::FunctionObject::createScriptFunction(qmlContext, runtimeFunction); _vmeMetaObject->setVmeMethod(property->coreIndex, function); } } @@ -1027,6 +1022,17 @@ void QQmlObjectCreator::registerObjectWithContextById(int objectIndex, QObject * context->setIdProperty(idEntry.value(), instance); } +QV4::Heap::ExecutionContext *QQmlObjectCreator::currentQmlContext() +{ + if (!_qmlBindingWrapper->objectValue()) { + QV4::Scope valueScope(v4); + QV4::ScopedObject qmlScope(valueScope, QV4::QmlContextWrapper::qmlScope(v4, context, _scopeObject)); + QV4::ScopedContext global(valueScope, v4->rootContext()); + *_qmlBindingWrapper = v4->memoryManager->alloc<QV4::QmlBindingWrapper>(global, qmlScope); + } + return static_cast<QV4::QmlBindingWrapper*>(_qmlBindingWrapper->objectValue())->context(); +} + QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isContextObject) { QQmlObjectCreationProfiler profiler(sharedState->profiler.profiler); @@ -1166,24 +1172,18 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo QObject *scopeObject = instance; qSwap(_scopeObject, scopeObject); - QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine); - Q_ASSERT(sharedState->allJavaScriptObjects); *sharedState->allJavaScriptObjects = QV4::QObjectWrapper::wrap(v4, instance); ++sharedState->allJavaScriptObjects; QV4::Scope valueScope(v4); - QV4::ScopedObject qmlScope(valueScope, QV4::QmlContextWrapper::qmlScope(v4, context, _scopeObject)); - QV4::ScopedContext global(valueScope, valueScope.engine->rootContext()); - QV4::Scoped<QV4::QmlBindingWrapper> qmlBindingWrapper(valueScope, v4->memoryManager->alloc<QV4::QmlBindingWrapper>(global, qmlScope)); - // ### GC - QV4::ExecutionContext *qmlContext = QV4::ScopedContext(valueScope, qmlBindingWrapper->context()); + QV4::Value *qmlBindingWrapper = valueScope.alloc(1); - qSwap(_qmlContext, qmlContext); + qSwap(_qmlBindingWrapper, qmlBindingWrapper); bool result = populateInstance(index, instance, /*binding target*/instance, /*value type property*/0, bindingsToSkip); - qSwap(_qmlContext, qmlContext); + qSwap(_qmlBindingWrapper, qmlBindingWrapper); qSwap(_scopeObject, scopeObject); return result ? instance : 0; @@ -1287,7 +1287,6 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject * qSwap(_ddata, declarativeData); qSwap(_bindingTarget, bindingTarget); - QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine); QV4::Scope valueScope(v4); QV4::ScopedValue scopeObjectProtector(valueScope); @@ -1332,7 +1331,8 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject * } } - setupFunctions(); + if (_compiledObject->nFunctions > 0) + setupFunctions(); setupBindings(bindingSkipList); qSwap(_vmeMetaObject, vmeMetaObject); diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h index 3886155786..fcf247be5a 100644 --- a/src/qml/qml/qqmlobjectcreator_p.h +++ b/src/qml/qml/qqmlobjectcreator_p.h @@ -107,6 +107,8 @@ private: void registerObjectWithContextById(int objectIndex, QObject *instance) const; + QV4::Heap::ExecutionContext *currentQmlContext(); + enum Phase { Startup, CreatingObjects, @@ -117,6 +119,7 @@ private: } phase; QQmlEngine *engine; + QV4::ExecutionEngine *v4; QQmlCompiledData *compiledData; const QV4::CompiledData::Unit *qmlUnit; QQmlGuardedContextData parentContext; @@ -139,7 +142,7 @@ private: QQmlRefPointer<QQmlPropertyCache> _propertyCache; QQmlVMEMetaObject *_vmeMetaObject; QQmlListProperty<void> _currentList; - QV4::ExecutionContext *_qmlContext; + QV4::Value *_qmlBindingWrapper; friend struct QQmlObjectCreatorRecursionWatcher; }; |