summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2017-07-23 16:31:38 +0100
committerDavid Mitchell <davem@iabyn.com>2017-07-27 11:30:25 +0100
commit6f2dc9a6b978e866e22c46235932d018da8262ba (patch)
treeaaea4ac92d8aa676e597ecbf13aff28c3a58f65d /lib
parent8dc9003ff3914e78971f561eaece965e9ceeb49e (diff)
downloadperl-6f2dc9a6b978e866e22c46235932d018da8262ba.tar.gz
make scalar(keys(%lexical)) less slow.
A recent commit in this branch made OP_PADHV / OP_RV2HV in void/scalar context, followed by OP_KEYS, optimise away the OP_KEYS op and set the OPpPADHV_ISKEYS or OPpRV2HV_ISKEYS flag on the OP_PADHV / OP_RV2HV op. However, in scalar but non-boolean context with OP_PADHV, this actually makes it slower, because the OP_KEYS op has a target, while the OP_PADHV op doesn't, thus it has to create a new mortal each time to return the integer value. This commit fixes that by, in the case of scalar padhv, retaining the OP_KEYS node (although still not keeping it in the execution path), then at runtime using that op's otherwise unused target. This only works on PERL_OP_PARENT builds (now the default) as the OP_KEYS is the parent of the OP_PADHV, so would be hard to find at runtime otherwise. This commit also fixes pp_padhv/pp_rv2hv in void context - formerly it was needlessly pushing a scalar-valued count like scalar context.
Diffstat (limited to 'lib')
-rw-r--r--lib/B/Deparse.pm8
1 files changed, 7 insertions, 1 deletions
diff --git a/lib/B/Deparse.pm b/lib/B/Deparse.pm
index f214081a7b..fe4e24960d 100644
--- a/lib/B/Deparse.pm
+++ b/lib/B/Deparse.pm
@@ -4115,7 +4115,13 @@ sub pp_padav { pp_padsv(@_) }
sub pp_padhv {
my $op = $_[1];
- (($op->private & OPpPADHV_ISKEYS) ? 'keys ' : '') . pp_padsv(@_);
+ my $keys = '';
+ # with OPpPADHV_ISKEYS the keys op is optimised away, except
+ # in scalar context the old op is kept (but not executed) so its targ
+ # can be used.
+ $keys = 'keys ' if ( ($op->private & OPpPADHV_ISKEYS)
+ && !(($op->flags & OPf_WANT) == OPf_WANT_SCALAR));
+ $keys . pp_padsv(@_);
}
sub gv_or_padgv {