This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
RT#133131: pp_hot.c: deoptimise pp_iter() when non-standard OP_AND op_ppaddr
authorAaron Crane <arc@cpan.org>
Fri, 20 Apr 2018 15:45:04 +0000 (17:45 +0200)
committerAaron Crane <arc@cpan.org>
Sat, 21 Apr 2018 11:10:46 +0000 (13:10 +0200)
commitf75ab299e2c1f32844ff278938ff12a96931649a
tree0a4d18641b9eb744643a10add647a10fc096637f
parent143b7de3f8fd2a2799ab2ce26ffefcf9596eadaa
RT#133131: pp_hot.c: deoptimise pp_iter() when non-standard OP_AND op_ppaddr

Commit 7c114860c0fa8ade5e00a4b609d2fbd11d5a494c introduced an optimisation
in pp_iter(). Before the optimisation, pp_iter() pushed either &PL_SV_yes or
&PL_sv_no to the stack, and returned the op_next in the obvious way.

The optimisation takes advantage of the fact that the op_next of an OP_ITER
always points to an OP_AND node, so pp_iter() now directly jumps to either
the op_next or the op_other of the OP_AND as appropriate.

The commit message for the optimisation also says this:

    It's possible that some weird optree-munging XS module may break this
    assumption. For now I've just added asserts that the next op is OP_AND
    with an op_ppaddr of Perl_pp_and; if that assertion fails, it may be
    necessary to convert pp_iter()s' asserts into conditional statements.

However, Devel::Cover does change the op_ppaddr of the ops it can see, so
the assertions on op_ppaddr were being tripped when Devel::Cover was run
under a -DDEBUGGING Perl. But even if the asserts didn't trip, skipping the
OP_AND nodes would prevent Devel::Cover from determining branch coverage in
the way that it wants.

This commit converts the asserts into conditional statements, as outlined in
the commit message above, and undoes the optimisation when the op_ppaddr
doesn't match.
pp_hot.c