This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
regcomp.c: shrink some optimized [class] nodes
authorKarl Williamson <public@khwilliamson.com>
Sat, 7 Jul 2012 17:46:40 +0000 (11:46 -0600)
committerKarl Williamson <public@khwilliamson.com>
Wed, 25 Jul 2012 03:13:46 +0000 (21:13 -0600)
commit6197c735af8f18ed71903781a046a889a1d1946d
treeadcd799df51763873f7d4445f853909da7667bed
parent94d80c53d196e34cf8b3da0c4904fd9242945990
regcomp.c: shrink some optimized [class] nodes

Various bracketed character class specifications don't need the full
generality, and can be optimized into smaller, faster nodes.  Recent
commits, such as 3a64b5154fffec75126d34d25954f0aef30d9f8a have
introduced some such optimizations.  However, their commit messages are
wrong, in that they don't end taking up any less space than the original
ANYOF node, as there is no provision for giving it back, once reserved.

This commit corrects that for non-locale nodes.  Restructuring of the
code, more than I care to do now, would be required to extend this to
locale nodes.

Only optimizations that are determined in pass1 of the regex compilation
are eligible for this, as once the space is calculated, it is reserved
before pass2 begins.  There are now two sections where optimization is
done in this routine.  The final section is after all the data is
examined and processed, and we know exactly what is to be in the ANYOF
node.  Currently, most of this calculation processing is skipped in pass
1.  We could do everything in both passes, greatly slowing down the
first, in order to figure out the exact space requirements.

But instead, I've chosen to add a separate optimization section that
looks at only the optimizations that are easily computable in the
current first pass, and to apply those early, in time for the shrinking
to occur.  This commit adds that shrinking.

Locale nodes can't be shrunk because the code currently writes into
their larger buffer before this decision to optimize is made.  To
illustrate, say that the node is at the end of the regex, and the data
is written at x+20, within a generic locale ANYOF node's space.  Pass 1
doesn't write anything, but calculates the space needed.  At the point
that this commit addresses, we would shrink the amount of space to be
allocated to be allocated.  Then we carve out space for the regex from
the heap.  That x+20 could be pointing to something entirely different,
which Pass 2 would destroy.  This can be avoided by storing the stuff
that would be written into a temporary until the optimization decision
has been made.  But there is extra work involved in doing this, that I
don't think is worth it at this time.

The same problem doesn't occur in non-locale situations, even though the
flags field of the node is written before the optimization decision.
This is because every node has the space for a flags field, so it just
gets overwritten as necessary when the optimization is done.
regcomp.c