summaryrefslogtreecommitdiff
path: root/t/perf
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2017-12-04 11:50:53 +0000
committerDavid Mitchell <davem@iabyn.com>2017-12-04 12:36:25 +0000
commitbcc30fd0276e8f6d4ac27d6f4c719b70a266b1fc (patch)
treeb1c021234c186d26b557128c4f1dc701615fdb46 /t/perf
parent56e48c10762ae388167c2f2449eea8553b396093 (diff)
downloadperl-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.t31
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,
+ });