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.
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;
}
require './test.pl';
}
-plan tests => 716; # Update this when adding/deleting tests.
+plan tests => 717; # Update this when adding/deleting tests.
run_tests() unless caller;
utf8::upgrade($s);
ok($s =~ /\da\d{0,30000}bc/, "\\d{30000}");
+ $s = "-ab\n" x 250_000;
+ $s .= "abx";
+ ok($s =~ /^ab.*x/m, "distant float with /m");
+
}
# These are based on looking at the code in regcomp.c