cache results of feature search
looking up the same files in the same locations over and over again is a rather significant waste. in particular, looking up the CONFIG flags that don't correspond with features has a measurable impact on qt creator's project loading time. Task-number: QTCREATORBUG-9154 Change-Id: Ibae3d8b7797e706a6416a7d45c77734ab1281b51 Reviewed-by: Daniel Teske <daniel.teske@digia.com> (cherry picked from qtcreator/fa27cd79e05aed4ebd16d5648480cc7d48fefd43) Reviewed-by: Joerg Bornemann <joerg.bornemann@digia.com>
This commit is contained in:
parent
547b7ed29c
commit
3a6a462ad9
@ -1503,7 +1503,7 @@ void QMakeEvaluator::updateFeaturePaths()
|
|||||||
foreach (const QString &root, feature_roots)
|
foreach (const QString &root, feature_roots)
|
||||||
if (IoUtils::exists(root))
|
if (IoUtils::exists(root))
|
||||||
ret << root;
|
ret << root;
|
||||||
m_featureRoots = ret;
|
m_featureRoots = new QMakeFeatureRoots(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
ProString QMakeEvaluator::propertyValue(const ProKey &name) const
|
ProString QMakeEvaluator::propertyValue(const ProKey &name) const
|
||||||
@ -1861,35 +1861,55 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateFeatureFile(
|
|||||||
if (!fn.endsWith(QLatin1String(".prf")))
|
if (!fn.endsWith(QLatin1String(".prf")))
|
||||||
fn += QLatin1String(".prf");
|
fn += QLatin1String(".prf");
|
||||||
|
|
||||||
if (m_featureRoots.isEmpty())
|
if (!m_featureRoots)
|
||||||
updateFeaturePaths();
|
updateFeaturePaths();
|
||||||
int start_root = 0;
|
#ifdef PROEVALUATOR_THREAD_SAFE
|
||||||
QString currFn = currentFileName();
|
m_featureRoots->mutex.lock();
|
||||||
if (IoUtils::fileName(currFn) == IoUtils::fileName(fn)) {
|
|
||||||
QStringRef currPath = IoUtils::pathName(currFn);
|
|
||||||
for (int root = 0; root < m_featureRoots.size(); ++root)
|
|
||||||
if (currPath == m_featureRoots.at(root)) {
|
|
||||||
start_root = root + 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int root = start_root; root < m_featureRoots.size(); ++root) {
|
|
||||||
QString fname = m_featureRoots.at(root) + fn;
|
|
||||||
if (IoUtils::exists(fname)) {
|
|
||||||
fn = fname;
|
|
||||||
goto cool;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#ifdef QMAKE_BUILTIN_PRFS
|
|
||||||
fn.prepend(QLatin1String(":/qmake/features/"));
|
|
||||||
if (QFileInfo(fn).exists())
|
|
||||||
goto cool;
|
|
||||||
#endif
|
#endif
|
||||||
if (!silent)
|
QString currFn = currentFileName();
|
||||||
evalError(fL1S("Cannot find feature %1").arg(fileName));
|
if (IoUtils::fileName(currFn) != IoUtils::fileName(fn))
|
||||||
return ReturnFalse;
|
currFn.clear();
|
||||||
|
// Null values cannot regularly exist in the hash, so they indicate that the value still
|
||||||
|
// needs to be determined. Failed lookups are represented via non-null empty strings.
|
||||||
|
QString *fnp = &m_featureRoots->cache[qMakePair(fn, currFn)];
|
||||||
|
if (fnp->isNull()) {
|
||||||
|
int start_root = 0;
|
||||||
|
const QStringList &paths = m_featureRoots->paths;
|
||||||
|
if (!currFn.isEmpty()) {
|
||||||
|
QStringRef currPath = IoUtils::pathName(currFn);
|
||||||
|
for (int root = 0; root < paths.size(); ++root)
|
||||||
|
if (currPath == paths.at(root)) {
|
||||||
|
start_root = root + 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int root = start_root; root < paths.size(); ++root) {
|
||||||
|
QString fname = paths.at(root) + fn;
|
||||||
|
if (IoUtils::exists(fname)) {
|
||||||
|
fn = fname;
|
||||||
|
goto cool;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef QMAKE_BUILTIN_PRFS
|
||||||
|
fn.prepend(QLatin1String(":/qmake/features/"));
|
||||||
|
if (QFileInfo(fn).exists())
|
||||||
|
goto cool;
|
||||||
|
#endif
|
||||||
|
fn = QLatin1String(""); // Indicate failed lookup. See comment above.
|
||||||
|
|
||||||
cool:
|
cool:
|
||||||
|
*fnp = fn;
|
||||||
|
} else {
|
||||||
|
fn = *fnp;
|
||||||
|
}
|
||||||
|
#ifdef PROEVALUATOR_THREAD_SAFE
|
||||||
|
m_featureRoots->mutex.unlock();
|
||||||
|
#endif
|
||||||
|
if (fn.isEmpty()) {
|
||||||
|
if (!silent)
|
||||||
|
evalError(fL1S("Cannot find feature %1").arg(fileName));
|
||||||
|
return ReturnFalse;
|
||||||
|
}
|
||||||
ProStringList &already = valuesRef(ProKey("QMAKE_INTERNAL_INCLUDED_FEATURES"));
|
ProStringList &already = valuesRef(ProKey("QMAKE_INTERNAL_INCLUDED_FEATURES"));
|
||||||
ProString afn(fn);
|
ProString afn(fn);
|
||||||
if (already.contains(afn)) {
|
if (already.contains(afn)) {
|
||||||
|
@ -55,9 +55,13 @@
|
|||||||
#include <qstack.h>
|
#include <qstack.h>
|
||||||
#include <qstring.h>
|
#include <qstring.h>
|
||||||
#include <qstringlist.h>
|
#include <qstringlist.h>
|
||||||
|
#include <qshareddata.h>
|
||||||
#ifndef QT_BOOTSTRAPPED
|
#ifndef QT_BOOTSTRAPPED
|
||||||
# include <qprocess.h>
|
# include <qprocess.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef PROEVALUATOR_THREAD_SAFE
|
||||||
|
# include <qmutex.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
@ -83,6 +87,20 @@ public:
|
|||||||
virtual void doneWithEval(ProFile *parent) = 0;
|
virtual void doneWithEval(ProFile *parent) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef QPair<QString, QString> QMakeFeatureKey; // key, parent
|
||||||
|
typedef QHash<QMakeFeatureKey, QString> QMakeFeatureHash;
|
||||||
|
|
||||||
|
class QMAKE_EXPORT QMakeFeatureRoots : public QSharedData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QMakeFeatureRoots(const QStringList &_paths) : paths(_paths) {}
|
||||||
|
const QStringList paths;
|
||||||
|
mutable QMakeFeatureHash cache;
|
||||||
|
#ifdef PROEVALUATOR_THREAD_SAFE
|
||||||
|
mutable QMutex mutex;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
// We use a QLinkedList based stack instead of a QVector based one (QStack), so that
|
// We use a QLinkedList based stack instead of a QVector based one (QStack), so that
|
||||||
// the addresses of value maps stay constant. The qmake generators rely on that.
|
// the addresses of value maps stay constant. The qmake generators rely on that.
|
||||||
class QMAKE_EXPORT ProValueMapStack : public QLinkedList<ProValueMap>
|
class QMAKE_EXPORT ProValueMapStack : public QLinkedList<ProValueMap>
|
||||||
@ -284,7 +302,7 @@ public:
|
|||||||
QStringList m_qmakepath;
|
QStringList m_qmakepath;
|
||||||
QStringList m_qmakefeatures;
|
QStringList m_qmakefeatures;
|
||||||
QStringList m_mkspecPaths;
|
QStringList m_mkspecPaths;
|
||||||
QStringList m_featureRoots;
|
QExplicitlySharedDataPointer<QMakeFeatureRoots> m_featureRoots;
|
||||||
ProString m_dirSep;
|
ProString m_dirSep;
|
||||||
ProFunctionDefs m_functionDefs;
|
ProFunctionDefs m_functionDefs;
|
||||||
ProStringList m_returnValue;
|
ProStringList m_returnValue;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user