summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-03-08 13:51:55 +0100
committerLars Knoll <lars.knoll@qt.io>2018-03-20 07:54:01 +0000
commitbbdc1b5ccbb19405f997cd67ec53b2c4860105f7 (patch)
tree3318bd920c92682af35bda138739eb12bceb8f55 /src/corelib
parent04f3534815a7b06a0c66989217f11885b96630d8 (diff)
Share and cache QRegExp engines where possible
QRegExpEngine is immutable once created, so we can easily share them between different QRegExp instances. This requires a QHash for engines that are currently in use in addition to the cache for currently unused engines. Task-number: QTBUG-65710 Change-Id: I165c12a7b065c488ecd14258a7cdfe0e62666632 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@qt.io>
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/tools/qregexp.cpp20
1 files changed, 15 insertions, 5 deletions
diff --git a/src/corelib/tools/qregexp.cpp b/src/corelib/tools/qregexp.cpp
index 96ddca56af..43e31ddb8e 100644
--- a/src/corelib/tools/qregexp.cpp
+++ b/src/corelib/tools/qregexp.cpp
@@ -3813,8 +3813,10 @@ struct QRegExpPrivate
};
#if !defined(QT_NO_REGEXP_OPTIM)
-typedef QCache<QRegExpEngineKey, QRegExpEngine> EngineCache;
+typedef QHash<QRegExpEngineKey, QRegExpEngine *> EngineCache;
Q_GLOBAL_STATIC(EngineCache, globalEngineCache)
+typedef QCache<QRegExpEngineKey, QRegExpEngine> UnusedEngineCache;
+Q_GLOBAL_STATIC(UnusedEngineCache, globalUnusedEngineCache)
static QBasicMutex globalEngineCacheMutex;
#endif // QT_NO_REGEXP_OPTIM
@@ -3822,14 +3824,16 @@ static void derefEngine(QRegExpEngine *eng, const QRegExpEngineKey &key)
{
if (!eng->ref.deref()) {
#if !defined(QT_NO_REGEXP_OPTIM)
- if (globalEngineCache()) {
+ if (globalUnusedEngineCache()) {
QMutexLocker locker(&globalEngineCacheMutex);
QT_TRY {
- globalEngineCache()->insert(key, eng, 4 + key.pattern.length() / 4);
+ globalUnusedEngineCache()->insert(key, eng, 4 + key.pattern.length() / 4);
} QT_CATCH(const std::bad_alloc &) {
// in case of an exception (e.g. oom), just delete the engine
delete eng;
}
+ if (globalEngineCache())
+ globalEngineCache()->remove(key);
} else {
delete eng;
}
@@ -3844,9 +3848,11 @@ static void prepareEngine_helper(QRegExpPrivate *priv)
{
bool initMatchState = !priv->eng;
#if !defined(QT_NO_REGEXP_OPTIM)
- if (!priv->eng && globalEngineCache()) {
+ if (!priv->eng && globalUnusedEngineCache()) {
QMutexLocker locker(&globalEngineCacheMutex);
- priv->eng = globalEngineCache()->take(priv->engineKey);
+ priv->eng = globalUnusedEngineCache()->take(priv->engineKey);
+ if (!priv->eng && globalEngineCache())
+ priv->eng = globalEngineCache()->value(priv->engineKey);
if (priv->eng != 0)
priv->eng->ref.ref();
}
@@ -3854,6 +3860,10 @@ static void prepareEngine_helper(QRegExpPrivate *priv)
if (!priv->eng)
priv->eng = new QRegExpEngine(priv->engineKey);
+#if !defined(QT_NO_REGEXP_OPTIM)
+ if (globalEngineCache())
+ globalEngineCache()->insert(priv->engineKey, priv->eng);
+#endif
if (initMatchState)
priv->matchState.prepareForMatch(priv->eng);