QRegularExpression: add an option to prevent automatic optimization
If a user doesn't like that QRegularExpression might do an uncontrolled CPU/memory spike when it decides to optimize a pattern, offer a way to disable the automatic optimization. Change-Id: I38a98a3bfb239cfad9f977b0eeb75903268e747f Reviewed-by: Lars Knoll <lars.knoll@digia.com> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
260f24228b
commit
5b300a1526
@ -705,6 +705,17 @@ QT_BEGIN_NAMESPACE
|
|||||||
JIT-compiled) on its first usage, instead of after a certain (undefined)
|
JIT-compiled) on its first usage, instead of after a certain (undefined)
|
||||||
number of usages. See also \l{QRegularExpression::}{optimize()}.
|
number of usages. See also \l{QRegularExpression::}{optimize()}.
|
||||||
This enum value has been introduced in Qt 5.4.
|
This enum value has been introduced in Qt 5.4.
|
||||||
|
|
||||||
|
\value DontAutomaticallyOptimizeOption
|
||||||
|
Regular expressions are automatically optimized after a
|
||||||
|
certain number of usages; setting this option prevents such
|
||||||
|
optimizations, therefore avoiding possible unpredictable spikes in
|
||||||
|
CPU and memory usage. If both this option and the
|
||||||
|
\c{OptimizeOnFirstUsageOption} option are set, then this option takes
|
||||||
|
precedence. Note: this option will still let the regular expression
|
||||||
|
to be optimized by manually calling
|
||||||
|
\l{QRegularExpression::}{optimize()}. This enum value has been
|
||||||
|
introduced in Qt 5.4.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -1108,7 +1119,10 @@ static bool isJitEnabled()
|
|||||||
setting the studyData member variable to the result of the study. It gets
|
setting the studyData member variable to the result of the study. It gets
|
||||||
called by doMatch() every time a match is performed. As of now, the
|
called by doMatch() every time a match is performed. As of now, the
|
||||||
optimizations on the pattern are performed after a certain number of usages
|
optimizations on the pattern are performed after a certain number of usages
|
||||||
(i.e. the qt_qregularexpression_optimize_after_use_count constant).
|
(i.e. the qt_qregularexpression_optimize_after_use_count constant) unless
|
||||||
|
the DontAutomaticallyOptimizeOption option is set on the QRegularExpression
|
||||||
|
object, or anyhow by calling optimize() (which will pass
|
||||||
|
ImmediateOptimizeOption).
|
||||||
|
|
||||||
Notice that although the method is protected by a mutex, one thread may
|
Notice that although the method is protected by a mutex, one thread may
|
||||||
invoke this function and return immediately (i.e. not study the pattern,
|
invoke this function and return immediately (i.e. not study the pattern,
|
||||||
@ -1248,13 +1262,15 @@ QRegularExpressionMatchPrivate *QRegularExpressionPrivate::doMatch(const QString
|
|||||||
matchType, matchOptions,
|
matchType, matchOptions,
|
||||||
capturingCount + 1);
|
capturingCount + 1);
|
||||||
|
|
||||||
const OptimizePatternOption optimizePatternOption =
|
if (!(patternOptions & QRegularExpression::DontAutomaticallyOptimizeOption)) {
|
||||||
(patternOptions & QRegularExpression::OptimizeOnFirstUsageOption)
|
const OptimizePatternOption optimizePatternOption =
|
||||||
? ImmediateOptimizeOption
|
(patternOptions & QRegularExpression::OptimizeOnFirstUsageOption)
|
||||||
: LazyOptimizeOption;
|
? ImmediateOptimizeOption
|
||||||
|
: LazyOptimizeOption;
|
||||||
|
|
||||||
// this is mutex protected
|
// this is mutex protected
|
||||||
const_cast<QRegularExpressionPrivate *>(this)->optimizePattern(optimizePatternOption);
|
const_cast<QRegularExpressionPrivate *>(this)->optimizePattern(optimizePatternOption);
|
||||||
|
}
|
||||||
|
|
||||||
// work with a local copy of the study data, as we are running pcre_exec
|
// work with a local copy of the study data, as we are running pcre_exec
|
||||||
// potentially more than once, and we don't want to run call it
|
// potentially more than once, and we don't want to run call it
|
||||||
@ -2370,6 +2386,8 @@ QDebug operator<<(QDebug debug, QRegularExpression::PatternOptions patternOption
|
|||||||
flags.append("UseUnicodePropertiesOption|");
|
flags.append("UseUnicodePropertiesOption|");
|
||||||
if (patternOptions & QRegularExpression::OptimizeOnFirstUsageOption)
|
if (patternOptions & QRegularExpression::OptimizeOnFirstUsageOption)
|
||||||
flags.append("OptimizeOnFirstUsageOption|");
|
flags.append("OptimizeOnFirstUsageOption|");
|
||||||
|
if (patternOptions & QRegularExpression::DontAutomaticallyOptimizeOption)
|
||||||
|
flags.append("DontAutomaticallyOptimizeOption|");
|
||||||
flags.chop(1);
|
flags.chop(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +70,8 @@ public:
|
|||||||
InvertedGreedinessOption = 0x0010,
|
InvertedGreedinessOption = 0x0010,
|
||||||
DontCaptureOption = 0x0020,
|
DontCaptureOption = 0x0020,
|
||||||
UseUnicodePropertiesOption = 0x0040,
|
UseUnicodePropertiesOption = 0x0040,
|
||||||
OptimizeOnFirstUsageOption = 0x0080
|
OptimizeOnFirstUsageOption = 0x0080,
|
||||||
|
DontAutomaticallyOptimizeOption = 0x0100
|
||||||
};
|
};
|
||||||
Q_DECLARE_FLAGS(PatternOptions, PatternOption)
|
Q_DECLARE_FLAGS(PatternOptions, PatternOption)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user