diff options
author | David Mitchell <davem@iabyn.com> | 2017-12-04 11:50:53 +0000 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2017-12-04 12:36:25 +0000 |
commit | bcc30fd0276e8f6d4ac27d6f4c719b70a266b1fc (patch) | |
tree | b1c021234c186d26b557128c4f1dc701615fdb46 /t/perf | |
parent | 56e48c10762ae388167c2f2449eea8553b396093 (diff) | |
download | perl-bcc30fd0276e8f6d4ac27d6f4c719b70a266b1fc.tar.gz |
multiconcat: don't fold adjacent constants
RT #132385
In something like
$overloaded . "a" . "b"
perl used to do
$overloaded->concat("a")->concat("b")
but since the introduction of OP_MULTICONCAT, started doing:
$overloaded->concat("ab")
This commit restores the old behaviour, by keeping every second adjacent
OP_CONST as an arg rather than optimising it away and adding its contents
to the constant string in the aux struct.
But note that
$overloaded .= "a" . "b"
originally, and still, constant folds.
Diffstat (limited to 't/perf')
-rw-r--r-- | t/perf/opcount.t | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/t/perf/opcount.t b/t/perf/opcount.t index 0ded6cd360..2d0ade56b0 100644 --- a/t/perf/opcount.t +++ b/t/perf/opcount.t @@ -20,7 +20,7 @@ BEGIN { use warnings; use strict; -plan 2579; +plan 2582; use B (); @@ -634,3 +634,32 @@ test_opcount(0, "state works with multiconcat", once => 1, padsv => 2, # one each for the next/once branches }); + +# multiple concats of constants preceded by at least one non-constant +# shouldn't get constant-folded so that a concat overload method is called +# for each arg. So every second constant string is left as an OP_CONST + +test_opcount(0, "multiconcat: 2 adjacent consts", + sub { my ($a, $b); $a = $b . "c" . "d" }, + { + const => 1, + multiconcat => 1, + concat => 0, + sassign => 0, + }); +test_opcount(0, "multiconcat: 3 adjacent consts", + sub { my ($a, $b); $a = $b . "c" . "d" . "e" }, + { + const => 1, + multiconcat => 1, + concat => 0, + sassign => 0, + }); +test_opcount(0, "multiconcat: 4 adjacent consts", + sub { my ($a, $b); $a = $b . "c" . "d" . "e" ."f" }, + { + const => 2, + multiconcat => 1, + concat => 0, + sassign => 0, + }); |