re_intuit_start(): calc fbm_instr() end in bytes
authorDavid Mitchell <davem@iabyn.com>
Sun, 2 Feb 2014 14:47:34 +0000 (14:47 +0000)
committerDavid Mitchell <davem@iabyn.com>
Sat, 8 Feb 2014 13:50:10 +0000 (13:50 +0000)
commit1a08ba3a6099186231e66bc4524910ad4ae3c51d
tree0ddd51c5e5922059cd0c60651f945caee047273d
parent97c6112e8d0139518e10f9af25b2ec9a32a39087
re_intuit_start(): calc fbm_instr() end in bytes

When calculating the end limit of the string to pass to fbm_instr(),
we usually have a pointer to the latest point where the substr could
start, whereas fbm_instr() expects a pointer to the latest point where
the substr could end.

Since fmb_intr() purely matches bytes (it cares not whether those bytes
are part of a utf8 stream of not), the value of the latest end point will
always be:

    (latest start point) + SvCUR(sv) - !!SvTAIL(sv)

i.e. work in bytes, even if we have utf8 values.

In some of the places where fbm_instr() is used, the calculation is being
done partially or fully in chars rather than bytes. This is not incorrect,
and indeed may in theory calculate a slightly lower end limit sometimes
and thus stop the fbm earlier. But this comes at the cost having to do
utf8 length calculations and HOPs back from the end of the string.

So we're trading off not having to do utf8 skips on the last few chars
against the fbm not uselessly searching the last few chars. These roughly
cancel each other out. But since we no longer do HOPs before starting the
fbm, we win every time the fbm doesn't get near the end of the string.

So in conclusion, simpler code and better than or equal performance.
regexec.c