diff options
author | Joerg Bornemann <joerg.bornemann@qt.io> | 2017-04-24 11:50:33 +0200 |
---|---|---|
committer | Joerg Bornemann <joerg.bornemann@qt.io> | 2017-04-26 13:24:01 +0000 |
commit | 589021d6eb5d7330d12d0b2efe76dff77f10b0b6 (patch) | |
tree | a42f86d847f12f821ce155e13f1af8525c942301 | |
parent | 1a440ba0708414843280c2f3e5d65b9f169acb51 (diff) |
Merge caches with same key in Evaluator
Reduce hash lookups and memory footprint.
========== Performance data for Resolving ==========
Old instruction count: 2465977485
New instruction count: 2457362647
Relative change: -1 %
Old peak memory usage: 21248960 Bytes
New peak memory usage: 21237680 Bytes
Relative change: -1 %
========== Performance data for Rule Execution ==========
Old instruction count: 4898426038
New instruction count: 4857983226
Relative change: -1 %
Old peak memory usage: 27604240 Bytes
New peak memory usage: 27593424 Bytes
Relative change: -1 %
========== Performance data for Null Build ==========
Old instruction count: 4509789474
New instruction count: 4490616946
Relative change: -1 %
Old peak memory usage: 30680456 Bytes
New peak memory usage: 30670784 Bytes
Relative change: -1 %
Change-Id: Ie613447cf9da4bc3d2bfdab42c9a9b5ace643540
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
-rw-r--r-- | src/lib/corelib/language/evaluator.cpp | 43 | ||||
-rw-r--r-- | src/lib/corelib/language/evaluator.h | 13 | ||||
-rw-r--r-- | src/lib/corelib/language/evaluatorscriptclass.cpp | 21 | ||||
-rw-r--r-- | src/lib/corelib/language/moduleloader.cpp | 6 |
4 files changed, 40 insertions, 43 deletions
diff --git a/src/lib/corelib/language/evaluator.cpp b/src/lib/corelib/language/evaluator.cpp index be581c3b1..07cd4852a 100644 --- a/src/lib/corelib/language/evaluator.cpp +++ b/src/lib/corelib/language/evaluator.cpp @@ -205,31 +205,26 @@ bool Evaluator::evaluateProperty(QScriptValue *result, const Item *item, const Q return true; } -QScriptValue Evaluator::fileScope(const FileContextConstPtr &file) -{ - QScriptValue &result = m_fileScopeMap[file]; - if (result.isObject()) { - // already initialized - return result; +Evaluator::FileContextScopes Evaluator::fileContextScopes(const FileContextConstPtr &file) +{ + FileContextScopes &result = m_fileContextScopesMap[file]; + if (!result.fileScope.isObject()) { + if (file->idScope()) + result.fileScope = scriptValue(file->idScope()); + else + result.fileScope = m_scriptEngine->newObject(); + result.fileScope.setProperty(QLatin1String("filePath"), file->filePath()); + result.fileScope.setProperty(QLatin1String("path"), file->dirPath()); + } + if (!result.importScope.isObject()) { + try { + result.importScope = m_scriptEngine->newObject(); + m_scriptEngine->import(file, result.importScope); + JsExtensions::setupExtensions(file->jsExtensions(), result.importScope); + } catch (const ErrorInfo &e) { + result.importScope = m_scriptEngine->currentContext()->throwError(e.toString()); + } } - - if (file->idScope()) - result = scriptValue(file->idScope()); - else - result = m_scriptEngine->newObject(); - result.setProperty(QLatin1String("filePath"), file->filePath()); - result.setProperty(QLatin1String("path"), file->dirPath()); - return result; -} - -QScriptValue Evaluator::importScope(const FileContextConstPtr &file) -{ - QScriptValue &result = m_importScopeMap[file]; - if (result.isObject()) - return result; - result = m_scriptEngine->newObject(); - m_scriptEngine->import(file, result); - JsExtensions::setupExtensions(file->jsExtensions(), result); return result; } diff --git a/src/lib/corelib/language/evaluator.h b/src/lib/corelib/language/evaluator.h index 759cc5d4e..b602326ca 100644 --- a/src/lib/corelib/language/evaluator.h +++ b/src/lib/corelib/language/evaluator.h @@ -75,8 +75,14 @@ public: QStringList stringListValue(const Item *item, const QString &name, bool *propertyWasSet = 0); QScriptValue scriptValue(const Item *item); - QScriptValue fileScope(const FileContextConstPtr &file); - QScriptValue importScope(const FileContextConstPtr &file); + + struct FileContextScopes + { + QScriptValue fileScope; + QScriptValue importScope; + }; + + FileContextScopes fileContextScopes(const FileContextConstPtr &file); void setCachingEnabled(bool enabled); @@ -93,8 +99,7 @@ private: ScriptEngine *m_scriptEngine; EvaluatorScriptClass *m_scriptClass; mutable QHash<const Item *, QScriptValue> m_scriptValueMap; - mutable QHash<FileContextConstPtr, QScriptValue> m_fileScopeMap; - mutable QHash<FileContextConstPtr, QScriptValue> m_importScopeMap; + mutable QHash<FileContextConstPtr, FileContextScopes> m_fileContextScopesMap; }; class EvalCacheEnabler diff --git a/src/lib/corelib/language/evaluatorscriptclass.cpp b/src/lib/corelib/language/evaluatorscriptclass.cpp index c68a195bc..50aa23707 100644 --- a/src/lib/corelib/language/evaluatorscriptclass.cpp +++ b/src/lib/corelib/language/evaluatorscriptclass.cpp @@ -101,15 +101,6 @@ public: } private: - QScriptValue importScope(Evaluator *evaluator, const FileContextConstPtr &file) - { - try { - return evaluator->importScope(file); - } catch (const ErrorInfo &e) { - return evaluator->engine()->currentContext()->throwError(e.toString()); - } - } - void setupConvenienceProperty(const QString &conveniencePropertyName, QScriptValue *extraScope, const QScriptValue &scriptValue) { @@ -162,6 +153,8 @@ private: for (int i = 0; i < value->alternatives().count(); ++i) { const JSSourceValue::Alternative *alternative = 0; alternative = &value->alternatives().at(i); + const Evaluator::FileContextScopes fileCtxScopes + = data->evaluator->fileContextScopes(value->file()); if (!conditionScopeItem) { // We have to differentiate between module instances and normal items here. // @@ -194,14 +187,14 @@ private: ? data->item->scope() : data->item; conditionScope = data->evaluator->scriptValue(conditionScopeItem); QBS_ASSERT(conditionScope.isObject(), return); - conditionFileScope = data->evaluator->fileScope(value->file()); + conditionFileScope = fileCtxScopes.fileScope; } scriptContext->pushScope(conditionFileScope); pushItemScopes(conditionScopeItem); if (alternative->value->definingItem()) pushItemScopes(alternative->value->definingItem()); scriptContext->pushScope(conditionScope); - const QScriptValue theImportScope = importScope(data->evaluator, value->file()); + const QScriptValue &theImportScope = fileCtxScopes.importScope; if (theImportScope.isError()) { scriptContext->popScope(); scriptContext->popScope(); @@ -275,7 +268,9 @@ private: setupConvenienceProperty(QLatin1String("original"), &extraScope, originalValue); } - pushScope(data->evaluator->fileScope(value->file())); + const Evaluator::FileContextScopes fileCtxScopes + = data->evaluator->fileContextScopes(value->file()); + pushScope(fileCtxScopes.fileScope); pushItemScopes(data->item); if (itemOfProperty && itemOfProperty->type() != ItemType::ModuleInstance) { // Own properties of module instances must not have the instance itself in the scope. @@ -284,7 +279,7 @@ private: if (value->definingItem()) pushItemScopes(value->definingItem()); pushScope(extraScope); - const QScriptValue theImportScope = importScope(data->evaluator, value->file()); + const QScriptValue &theImportScope = fileCtxScopes.importScope; if (theImportScope.isError()) { *result = theImportScope; } else { diff --git a/src/lib/corelib/language/moduleloader.cpp b/src/lib/corelib/language/moduleloader.cpp index b51c337e2..7701a0432 100644 --- a/src/lib/corelib/language/moduleloader.cpp +++ b/src/lib/corelib/language/moduleloader.cpp @@ -2253,8 +2253,10 @@ void ModuleLoader::resolveProbe(ProductContext *productContext, Item *parent, It ScriptEngine * const engine = m_evaluator->engine(); QScriptValue scope = engine->newObject(); engine->currentContext()->pushScope(m_evaluator->scriptValue(parent)); - engine->currentContext()->pushScope(m_evaluator->fileScope(configureScript->file())); - engine->currentContext()->pushScope(m_evaluator->importScope(configureScript->file())); + const Evaluator::FileContextScopes fileCtxScopes + = m_evaluator->fileContextScopes(configureScript->file()); + engine->currentContext()->pushScope(fileCtxScopes.fileScope); + engine->currentContext()->pushScope(fileCtxScopes.importScope); engine->currentContext()->pushScope(scope); for (const ProbeProperty &b : qAsConst(probeBindings)) scope.setProperty(b.first, b.second); |