diff options
Diffstat (limited to 'src/corelib/tools/qregexp.cpp')
-rw-r--r-- | src/corelib/tools/qregexp.cpp | 56 |
1 files changed, 32 insertions, 24 deletions
diff --git a/src/corelib/tools/qregexp.cpp b/src/corelib/tools/qregexp.cpp index 96ddca56af..87b30c952e 100644 --- a/src/corelib/tools/qregexp.cpp +++ b/src/corelib/tools/qregexp.cpp @@ -3813,50 +3813,57 @@ struct QRegExpPrivate }; #if !defined(QT_NO_REGEXP_OPTIM) -typedef QCache<QRegExpEngineKey, QRegExpEngine> EngineCache; -Q_GLOBAL_STATIC(EngineCache, globalEngineCache) -static QBasicMutex globalEngineCacheMutex; +struct QRECache +{ + typedef QHash<QRegExpEngineKey, QRegExpEngine *> EngineCache; + typedef QCache<QRegExpEngineKey, QRegExpEngine> UnusedEngineCache; + EngineCache usedEngines; + UnusedEngineCache unusedEngines; +}; +Q_GLOBAL_STATIC(QRECache, engineCache) +static QBasicMutex engineCacheMutex; #endif // QT_NO_REGEXP_OPTIM static void derefEngine(QRegExpEngine *eng, const QRegExpEngineKey &key) { - if (!eng->ref.deref()) { #if !defined(QT_NO_REGEXP_OPTIM) - if (globalEngineCache()) { - QMutexLocker locker(&globalEngineCacheMutex); - QT_TRY { - globalEngineCache()->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; - } + QMutexLocker locker(&engineCacheMutex); + if (!eng->ref.deref()) { + if (QRECache *c = engineCache()) { + c->unusedEngines.insert(key, eng, 4 + key.pattern.length() / 4); + c->usedEngines.remove(key); } else { delete eng; } + } #else - Q_UNUSED(key); + Q_UNUSED(key); + if (!eng->ref.deref()) delete eng; #endif - } } static void prepareEngine_helper(QRegExpPrivate *priv) { - bool initMatchState = !priv->eng; + Q_ASSERT(!priv->eng); + #if !defined(QT_NO_REGEXP_OPTIM) - if (!priv->eng && globalEngineCache()) { - QMutexLocker locker(&globalEngineCacheMutex); - priv->eng = globalEngineCache()->take(priv->engineKey); - if (priv->eng != 0) + QMutexLocker locker(&engineCacheMutex); + if (QRECache *c = engineCache()) { + priv->eng = c->unusedEngines.take(priv->engineKey); + if (!priv->eng) + priv->eng = c->usedEngines.value(priv->engineKey); + if (!priv->eng) + priv->eng = new QRegExpEngine(priv->engineKey); + else priv->eng->ref.ref(); + + c->usedEngines.insert(priv->engineKey, priv->eng); + return; } #endif // QT_NO_REGEXP_OPTIM - if (!priv->eng) - priv->eng = new QRegExpEngine(priv->engineKey); - - if (initMatchState) - priv->matchState.prepareForMatch(priv->eng); + priv->eng = new QRegExpEngine(priv->engineKey); } inline static void prepareEngine(QRegExpPrivate *priv) @@ -3864,6 +3871,7 @@ inline static void prepareEngine(QRegExpPrivate *priv) if (priv->eng) return; prepareEngine_helper(priv); + priv->matchState.prepareForMatch(priv->eng); } static void prepareEngineForMatch(QRegExpPrivate *priv, const QString &str) |