Branch: refs/heads/blead
  Home:   https://github.com/Perl/perl5
  Commit: f37cd5e9bc43e0d839b4007ceefca5a02c4701c6
      
https://github.com/Perl/perl5/commit/f37cd5e9bc43e0d839b4007ceefca5a02c4701c6
  Author: David Mitchell <da...@iabyn.com>
  Date:   2023-09-02 (Sat, 02 Sep 2023)

  Changed paths:
    M t/perf/benchmarks

  Log Message:
  -----------
  perf/benchmarks: add concat tests for magic vars

There are already extensive tests for various permutations of string
concatenation (mainly to exercise the pp_multiconcat() optimisation
introduced in 5.28.0)

This commit adds copies of of most of those tests, but where lexical
vars are replaced by a variable which has get magic, in this case $1.

pp_multiconcat() takes a very pessimised approach when it detects magic
vars (the possible side effects  of which rule out most of the possible
optimisations, mainly due to ordering). But it's been pointed out
(GH #21360) that this can make expressions involving such vars actually
slower than before pp_multiconcat() was introduced.

So add tests now, then subsequent commits will try to speed them up.


  Commit: 212b6b3f3b2c904f656295bc1871a735c9589ceb
      
https://github.com/Perl/perl5/commit/212b6b3f3b2c904f656295bc1871a735c9589ceb
  Author: David Mitchell <da...@iabyn.com>
  Date:   2023-09-02 (Sat, 02 Sep 2023)

  Changed paths:
    M pp_hot.c

  Log Message:
  -----------
  pp_multiconcat(): use a single TEMP for consts

In the 'fallback to traditional concat behaviour if any args are magic'
branch, the code creates an SvTEMP() SV for each constant string segment
that needs to be concatenated.

This commit makes it reuse the same TEMP for each constant segment,
rather than creating a new one each time.

The code originally reused the TEMP, but that broke things where the
method which was called for an overloaded object took a reference to one
of its args (RT #132385). My original fix was a blanket "don't reuse".
This commit makes the rule into "reuse unless the TEMP has a refcount > 1,
in which case abandon it", which shou;d make things faster.

See GH #21360.


  Commit: ea6e0ec28eeb0c56edbc0e88c5337efb1b17bda0
      
https://github.com/Perl/perl5/commit/ea6e0ec28eeb0c56edbc0e88c5337efb1b17bda0
  Author: David Mitchell <da...@iabyn.com>
  Date:   2023-09-02 (Sat, 02 Sep 2023)

  Changed paths:
    M pp_hot.c

  Log Message:
  -----------
  pp_multiconcat(): use shared-buffer const SV

In the 'fallback to traditional concat behaviour if any args are magic'
branch, the code creates a resuable SvTEMP() SV, which is temporarily
set for each constant string segment that needs to be concatenated.

Make that SV be of the kind where SvLEN(sv) == 0, which means the PV
buffer is shared and won't be freed when the SV is freed. Then just set
the SvPV pointer to point to the appropriate offset in the string
constants buffer attached to the multiconcat op. This avoids malloc()ing
and free()ing the PV buffer each time, and so should speed things up.

See GH #21360.


  Commit: e3777abb2629e5b080a66f5f2b52bd980a47c4c1
      
https://github.com/Perl/perl5/commit/e3777abb2629e5b080a66f5f2b52bd980a47c4c1
  Author: David Mitchell <da...@iabyn.com>
  Date:   2023-09-02 (Sat, 02 Sep 2023)

  Changed paths:
    M ext/B/B.pm
    M ext/B/B.xs
    M peep.c
    M perl.h
    M pp_hot.c

  Log Message:
  -----------
  pp_multiconcat(): use PADTMPs for magic stuff

In the 'fallback to traditional concat behaviour if any args are magic'
branch, the code creates up to four SvTEMP() SVs to emulate the PADTMPs
of the various OP_CONCAT, OP_CONST, etc ops it replaced.

This commit allocates up to three extra PADTMPs (indexed from the aux
array) for pp_multiconcat()'s use, to avoid having to allocate and free
SvTEMPs each time.

It also fixes the issue in GH #21360, whereby something like

    s/..../x$1/g

was allocating SvTEMPs for each /g iteration, but because it only does a
FREETMPs after the last iteration, memory usage grew and performance
suffered.

After this commit, only two places still create a mortal.
The first is in the tie/overload handling code (which emulates
Perl_try_amagic_bin) for the rare case of both args being magic and the
same SV. Before pp_multiconcat() was added, this would create a mortal
anyway.

The seconds is in the rare case where a PADTMP used to emulate the SV
of an OP_CONST is stolen (e.g. by an overload method taking a reference
to it.) In this case it is abandoned and a mortal used instead.

The idea to add extra PADTMPs, indexed from aux, was stolen from Richard
Leach.


  Commit: 7bcd18ae82e8d5258145a748ee206ff8325dbd74
      
https://github.com/Perl/perl5/commit/7bcd18ae82e8d5258145a748ee206ff8325dbd74
  Author: David Mitchell <da...@iabyn.com>
  Date:   2023-09-02 (Sat, 02 Sep 2023)

  Changed paths:
    M ext/B/B.pm
    M ext/B/B.xs
    M peep.c
    M perl.h
    M pp_hot.c
    M t/perf/benchmarks

  Log Message:
  -----------
  [MERGE] pp_multiconcat: don't make lots of mortals

In the 'fallback to traditional concat behaviour if any args are magic'
branch, the code was potentially creating lots of SvTEMPs to emulate the
PADTMPs of the various OP_CONCAT, OP_CONST, etc ops it replaced.

This branch reduces the number of temps required, and of the ones still
needed, mostly replaces them with PADTMPs so that they don't need freeing
and reallocating each time.

In particular, this fixes GH #21360, whereby something like

s/..../x$1/g

was allocating SvTEMPs for each /g iteration, but because it only did a
FREETMPs after the last iteration, memory usage grew and performance
suffered, especially under Windows.


Compare: https://github.com/Perl/perl5/compare/abc9d33b5dc5...7bcd18ae82e8

Reply via email to