This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
pp_leavesub(): call FREETMPS and optimise
authorDavid Mitchell <davem@iabyn.com>
Sun, 8 Nov 2015 15:16:09 +0000 (15:16 +0000)
committerDavid Mitchell <davem@iabyn.com>
Wed, 3 Feb 2016 09:18:33 +0000 (09:18 +0000)
commitf7a874b868f5a21432be489ac4efc417525c52f6
tree5bb30e2ab00cdb76003235762e7ea2c3fe11c2c2
parent82fce3d0db4e7411638fbe6cc1575a02021a5726
pp_leavesub(): call FREETMPS and optimise

Currently pp_leavesub() doesn't call FREETMPS. Presumably this is due to
the danger of freeing temps that need to exist beyond the return, such
as the mortal copies we make of return args, or return args that are
already temps.

The down side of this is that temps aren't freed until the next nextstate
is executed following the function call. If the function isn't near a
statement boundary, then it may be a while before temps are freed; e.g.
in f(g()), when g() returns, its temps continue to exist during the call
to f(). For recursive subs it gets worse, although there is a specific
hack already in pp_leavesub() that says in scalar context if CvDEPTH > 1,
then temporarily RC++ the single return value then do a FREETMPS. This
can in theory leak if something dies during the FREETMPS.

This commit provides a more general solution. During the course of
processing (usually mortal copying) the return args, it divides the
current temps stack frame into two halves, with the temps that need
keeping migrating to the bottom half. It then does a FREETMPS equivalent
only of the top half.

This is actually more efficient than it sounds; but in addition, the code
has been heavily optimised: in particular the call to sv_mortalcopy()
has been unrolled and inlined, and within that code common cases (such as
IV, RV) handled directly, and the mortal stack is only checked/extended
once, rather than for every arg.

Also, the arg adjust / freetmps code has been moved out of pp_leavesub()
and into a separate static function.
pp_hot.c
t/op/sub.t
t/perf/benchmarks