diff --git a/src/libs/qmljs/qmljsinterpreter.cpp b/src/libs/qmljs/qmljsinterpreter.cpp index 94518dbde9908254e1496df6b9611c6320a2088e..3c57475f67d92a7981e4481b3b0a3e92458ceb94 100644 --- a/src/libs/qmljs/qmljsinterpreter.cpp +++ b/src/libs/qmljs/qmljsinterpreter.cpp @@ -182,17 +182,6 @@ QmlObjectValue::QmlObjectValue(FakeMetaObject::ConstPtr metaObject, const QStrin QmlObjectValue::~QmlObjectValue() {} -const Value *QmlObjectValue::findOrCreateSignature(int index, const FakeMetaMethod &method, QString *methodName) const -{ - *methodName = method.methodName(); - const Value *value = _metaSignature.value(index); - if (! value) { - value = new MetaFunction(method, valueOwner()); - _metaSignature.insert(index, value); - } - return value; -} - void QmlObjectValue::processMembers(MemberProcessor *processor) const { // process the meta enums @@ -207,6 +196,19 @@ void QmlObjectValue::processMembers(MemberProcessor *processor) const // all explicitly defined signal names QSet<QString> explicitSignals; + // make MetaFunction instances lazily when first needed + QList<const Value *> *signatures = _metaSignatures; + if (!signatures) { + signatures = new QList<const Value *>; + signatures->reserve(_metaObject->methodCount()); + for (int index = 0; index < _metaObject->methodCount(); ++index) + signatures->append(new MetaFunction(_metaObject->method(index), valueOwner())); + if (!_metaSignatures.testAndSetOrdered(0, signatures)) { + delete signatures; + signatures = _metaSignatures; + } + } + // process the meta methods for (int index = 0; index < _metaObject->methodCount(); ++index) { const FakeMetaMethod method = _metaObject->method(index); @@ -214,7 +216,7 @@ void QmlObjectValue::processMembers(MemberProcessor *processor) const continue; QString methodName; - const Value *signature = findOrCreateSignature(index, method, &methodName); + const Value *signature = signatures->at(index); if (method.methodType() == FakeMetaMethod::Slot && method.access() == FakeMetaMethod::Public) { processor->processSlot(methodName, signature); diff --git a/src/libs/qmljs/qmljsinterpreter.h b/src/libs/qmljs/qmljsinterpreter.h index 804e52b03e33db9d1e5b63dc6c9d795d01cef7a8..92d1978e9fe7a9f3a297a68609230232289baca0 100644 --- a/src/libs/qmljs/qmljsinterpreter.h +++ b/src/libs/qmljs/qmljsinterpreter.h @@ -449,8 +449,6 @@ public: LanguageUtils::FakeMetaEnum getEnum(const QString &typeName, const QmlObjectValue **foundInScope = 0) const; const QmlEnumValue *getEnumValue(const QString &typeName, const QmlObjectValue **foundInScope = 0) const; protected: - const Value *findOrCreateSignature(int index, const LanguageUtils::FakeMetaMethod &method, - QString *methodName) const; bool isDerivedFrom(LanguageUtils::FakeMetaObject::ConstPtr base) const; private: @@ -462,7 +460,7 @@ private: // needed in cases when B 1.0 has A 1.1 as prototype when imported as 1.1 const LanguageUtils::ComponentVersion _componentVersion; const LanguageUtils::ComponentVersion _importVersion; - mutable QHash<int, const Value *> _metaSignature; + mutable QAtomicPointer< QList<const Value *> > _metaSignatures; QHash<QString, const QmlEnumValue * > _enums; int _metaObjectRevision; }; diff --git a/src/libs/qmljs/qmljsvalueowner.cpp b/src/libs/qmljs/qmljsvalueowner.cpp index c6ef8fd52c216461b5b824bd82eb7216a761f4ac..aaa9f4d28b40c4a66b934cc7018a645eb599f881 100644 --- a/src/libs/qmljs/qmljsvalueowner.cpp +++ b/src/libs/qmljs/qmljsvalueowner.cpp @@ -453,6 +453,7 @@ const ObjectValue *ValueOwner::qtObject() const void ValueOwner::registerValue(Value *value) { + // ### get rid of this lock QMutexLocker locker(&_mutex); _registeredValues.append(value); }