diff options
author | David Mitchell <davem@iabyn.com> | 2014-02-07 16:43:19 +0000 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2014-02-08 14:04:55 +0000 |
commit | ec19cf6bc850473f27f9bb92a316cd58fd76797c (patch) | |
tree | f9b15b83a992a1035c37bee788ad46576d6e7637 /regexec.c | |
parent | e7a14a9c2dc20193ef41eda2055fda4ef2dc6c6e (diff) | |
download | perl-ec19cf6bc850473f27f9bb92a316cd58fd76797c.tar.gz |
re_intuit_start(): don't decrease other_last
The /^../m failure code did an unconditional other_last = rx_origin;
if other_last was already high, it could get shrunk and we'd end
up running fbm over the same bit of string repeatedly.
The following code
$s = "-ab\n" x 500_000;
$s .= 'abx';
$s =~ /^ab.*x/m;
(which went quadratic on length) reduces from minutes to millisecs with
this commit. This is because we'd keep going back to near the beginning
of the string and searching for 'x' again.
Diffstat (limited to 'regexec.c')
-rw-r--r-- | regexec.c | 3 |
1 files changed, 2 insertions, 1 deletions
@@ -1121,7 +1121,8 @@ Perl_re_intuit_start(pTHX_ DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log, " Found /%s^%s/m, restarting lookup for check-string at offset %ld...\n", PL_colors[0], PL_colors[1], (long)(t + 1 - strpos))); - other_last = rx_origin; + if (other_last < rx_origin) + other_last = rx_origin; goto restart; } |