This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
make "for my $lex {}" faster under ITHREADS
authorDavid Mitchell <davem@iabyn.com>
Mon, 29 Jun 2015 11:33:35 +0000 (12:33 +0100)
committerDavid Mitchell <davem@iabyn.com>
Wed, 3 Feb 2016 08:59:33 +0000 (08:59 +0000)
commitb52de9641f23b23bce1ec76375ae19bd7202b24a
treeb9965be6731cd65c58d4c2665cca0ec2cd16c644
parent41f96e1a89a5842483b2a12424693a876f5b57c0
make "for my $lex {}" faster under ITHREADS

Normally at the start of a 'for' iteration (pp_enteriter), we store the
address of the GV or the address of the pad slot of the iteration variable
in the CX struct, so we can quickly access and update it in pp_iter.  For
the ITHREADS case however, the pad may change if the thread is cloned, so
instead the address of PL_comppad was stored, and then updated during
cloning. This meant that on each iter, we would have to retrieve the saved
PL_comppad address from the ctx struct, retrieve the targ from the saved
my_op, and do a (perlish) array indexing.

Thuis commit makes this faster by, for the ITHREADS case, storing both
PL_comppad and svp = &PLcurpad[targ]. In pp_iter(), we're fast by directly
accessing *svp; while storing PL_comppad allows us to update both it and
svp during thread cloning.

This requires one extra pointer in the block_loop part of the context
union under threads, but this is already smaller than some other parts of
the union, so has no effect.

Note that the oldcomppad field was formerly part of the itervar_u union,
but is now a separate field within the larger block_loop struct (but only
on threaded builds).

Note also that the tests I've added I retrieved from an old WIP private
branch that contained a forerunner of this commit, so they may not be
entirely relevant to the current form of this commit. But extra tests
can never hurt, so I've included them.
cop.h
ext/XS-APItest/t/clone-with-stack.t
pp_ctl.c
sv.c
t/op/for.t
t/perf/benchmarks