This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[MERGE] make optree-walking mostly non-recursive
authorDavid Mitchell <davem@iabyn.com>
Mon, 24 Jun 2019 10:40:30 +0000 (11:40 +0100)
committerDavid Mitchell <davem@iabyn.com>
Mon, 24 Jun 2019 10:40:30 +0000 (11:40 +0100)
This branch updates many of the functions in op.c which recursively
walk an op tree during compilation.  This avoids SEGVs from stack
overflow when the op tree is deeply nested, such as
    $n == 1 ? "one" : $n == 2 ? "two" : ....
(especially in code which is auto-generated)

This is particularly noticeable where the code is compiled within a
separate thread, as threads tend to have small stacks by default.

Some functions already avoided recursion by mallocing a buffer
containing a list of ops to visit, but this could be leaked if the code
died during compilation.

Making the functions non-recursive is a lot easier now that the last
node in each OpSIBLING chain holds a pointer back to the parent node.
Where the function needs to recursively visit *every* node, its just a
case of following each child link, then every OpSIBLING link then the
parent link. Where the recursion is more selective, it becomes more
tricky. In some cases I have followed the policy that a node has N kids
and kids I..N need visiting, then start at I and iterate as usual; but
if just kids I and J  needs visiting (but not J+1..N), then do old-style
recursion on nodes I and J. These cases are hopefully rare.


No differences found