summaryrefslogtreecommitdiff
path: root/opcode.h
Commit message (Collapse)AuthorAgeFilesLines
* eliminate OPpRUNTIME private PMOP flagDavid Mitchell2016-11-141-193/+189
| | | | | | This flag was added in 5.004 and even then it didn't seem to be used for anything. It gets set and unset in various places, but is never tested. I'm not even sure what it was intended for.
* Better optimise my/local @a = split()David Mitchell2016-10-041-66/+66
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | There are currently two optimisations for when the results of a split are assigned to an array. For the first, @array = split(...); the aassign and padav/rv2av are optimised away, and pp_split() directly assigns to the array attached to the split op (via op_pmtargetoff or op_pmtargetgv). For the second, my @array = split(...); local @array = split(...); @{$expr} = split(...); The aassign is optimised away, but the padav/rv2av is kept as an additional arg to split. pp_split itself then uses the first arg popped off the stack as the array (This was introduced by FC with v5.21.4-409-gef7999f). This commit moves these two: my @array = split(...); local @array = split(...); from the second case to the first case, by simply setting OPpLVAL_INTRO on the OP_SPLIT, and making pp_split() do SAVECLEARSV() or save_ary() as appropriate. This makes my @a = split(...) a few percent faster.
* make OP_SPLIT a PMOP, and eliminate OP_PUSHREDavid Mitchell2016-10-041-213/+210
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Most ops that execute a regex, such as match and subst, are of type PMOP. A PMOP allows the actual regex to be attached directly to that op, due to its extra fields. OP_SPLIT is different; it is just a plain LISTOP, but it always has an OP_PUSHRE as its first child, which *is* a PMOP and which has the regex attached. At runtime, pp_pushre()'s only job is to push itself (i.e. the current PL_op) onto the stack. Later pp_split() pops this to get access to the regex it wants to execute. This is a bit unpleasant, because we're pushing an OP* onto the stack, which is supposed to be an array of SV*'s. As a bit of a hack, on DEBUGGING builds we push a PVLV with the PL_op address embedded instead, but this still isn't very satisfactory. Now that regexes are first-class SVs, we could push a REGEXP onto the stack rather than PL_op. However, there is an optimisation of @array = split which eliminates the assign and embeds the array's GV/padix directly in the PUSHRE op. So split still needs access to that op. But the pushre op will always be splitop->op_first anyway, so one possibility is to just skip executing the pushre altogether, and make pp_split just directly access op_first instead to get the regex and @array info. But if we're doing that, then why not just go the full hog and make OP_SPLIT into a PMOP, and eliminate the OP_PUSHRE op entirely: with the data that was spread across the two ops now combined into just the one split op. That is exactly what this commit does. For a simple compile-time pattern like split(/foo/, $s, 1), the optree looks like: before: <@> split[t2] lK </> pushre(/"foo"/) s/RTIME <0> padsv[$s:1,2] s <$> const(IV 1) s after: </> split(/"foo"/)[t2] lK/RTIME <0> padsv[$s:1,2] s <$> const[IV 1] s while for a run-time expression like split(/$pat/, $s, 1), before: <@> split[t3] lK </> pushre() sK/RTIME <|> regcomp(other->8) sK <0> padsv[$pat:2,3] s <0> padsv[$s:1,3] s <$> const(IV 1)s after: </> split()[t3] lK/RTIME <|> regcomp(other->8) sK <0> padsv[$pat:2,3] s <0> padsv[$s:1,3] s <$> const[IV 1] s This makes the code faster and simpler. At the same time, two new private flags have been added for OP_SPLIT - OPpSPLIT_ASSIGN and OPpSPLIT_LEX - which make it explicit that the assign op has been optimised away, and if so, whether the array is lexical. Also, deparsing of split has been improved, to the extent that perl TEST -deparse op/split.t now passes. Also, a couple of panic messages in pp_split() have been replaced with asserts().
* sassign is wrongly declared as BASEOP, not BINOP.Reini Urban2016-09-291-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | [ DAPM: To clarify: OP_SASSIGN is always allocated as a BINOP (or occasionally as a UNOP - see the next commit), but is listed as a BASEOP in regen/opcodes. Because of this, various bits of code that rely on e.g. PL_opargs[] have to be special-cased for OP_SASSIGN. This commit changes the entry in regen/opcodes to list it as BINOP, and removes the special-casing. I've also added a temporary workaround marked by XXX to make the commit work under PERL_OP_PARENT, which is the default now. This will be removed in a couple if commits' time. ] This was wrong from the very beginning: added with 79072805bf lwall perl 5.0 alpha 2 1993 with class s, not 0, but missing the 2 S S args, which are present in aassign. Changed to BASEOP with db173bac9b6de7d by mbeattie in 1997. The '# sassign is special-cased for op class' comment is suspicious. Fix it in ck_sassign also, it is created as BINOP in newASSIGNOP. In 202206897 dapm 2014 complained about it also. Remove some special cases where it should be a BINOP but was not.
* padrange, aelemfast: use label for private bitsDavid Mitchell2016-09-271-3/+5
| | | | | | | | | | | | | | | | | | | | Change the output of Concise etc: $ perl -MO=Concise -e'my (@a,$b,$c); $a[5];' from: 3 <0> padrange[@a:1,2; $b:1,2; $c:1,2] vM/LVINTRO,3 ... 5 <0> aelemfast_lex[@a:1,2] sR/5 to: 3 <0> padrange[@a:1,2; $b:1,2; $c:1,2] vM/LVINTRO,range=3 ... 5 <0> aelemfast_lex[@a:1,2] sR/key=5 See http://nntp.perl.org/group/perl.perl5.porters/220208.
* OP_AVHVSWITCH: make op_private bits 0..1 symbolicDavid Mitchell2016-09-271-2/+4
| | | | | Add OPpAVHVSWITCH_MASK and make Concise etc display the offset as /offset=2 rather than /2.
* add OP_ARGELEM, OP_ARGDEFELEM, OP_ARGCHECK opsDavid Mitchell2016-08-031-59/+86
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Currently subroutine signature parsing emits many small discrete ops to implement arg handling. This commit replaces them with a couple of ops per signature element, plus an initial signature check op. These new ops are added to the OP tree during parsing, so will be visible to hooks called up to and including peephole optimisation. It is intended soon that the peephole optimiser will take these per-element ops, and replace them with a single OP_SIGNATURE op which handles the whole signature in a single go. So normally these ops wont actually get executed much. But adding these intermediate-level ops gives three advantages: 1) it allows the parser to efficiently generate subtrees containing individual signature elements, which can't be done if only OP_SIGNATURE or discrete ops are available; 2) prior to optimisation, it provides a simple and straightforward representation of the signature; 3) hooks can mess with the signature OP subtree in ways that make it no longer possible to optimise into an OP_SIGNATURE, but which can still be executed, deparsed etc (if less efficiently). This code: use feature "signatures"; sub f($a, $, $b = 1, @c) {$a} under 'perl -MO=Concise,f' now gives: d <1> leavesub[1 ref] K/REFC,1 ->(end) - <@> lineseq KP ->d 1 <;> nextstate(main 84 foo:6) v:%,469762048 ->2 2 <+> argcheck(3,1,@) v ->3 3 <;> nextstate(main 81 foo:6) v:%,469762048 ->4 4 <+> argelem(0)[$a:81,84] v/SV ->5 5 <;> nextstate(main 82 foo:6) v:%,469762048 ->6 8 <+> argelem(2)[$b:82,84] vKS/SV ->9 6 <|> argdefelem(other->7)[2] sK ->8 7 <$> const(IV 1) s ->8 9 <;> nextstate(main 83 foo:6) v:%,469762048 ->a a <+> argelem(3)[@c:83,84] v/AV ->b - <;> ex-nextstate(main 84 foo:6) v:%,469762048 ->b b <;> nextstate(main 84 foo:6) v:%,469762048 ->c c <0> padsv[$a:81,84] s ->d The argcheck(3,1,@) op knows the number of positional params (3), the number of optional params (1), and whether it has an array / hash slurpy element at the end. This op is responsible for checking that @_ contains the right number of args. A simple argelem(0)[$a] op does the equivalent of 'my $a = $_[0]'. Similarly, argelem(3)[@c] is equivalent to 'my @c = @_[3..$#_]'. If it has a child, it gets its arg from the stack rather than using $_[N]. Currently the only used child is the logop argdefelem. argdefelem(other->7)[2] is equivalent to '@_ > 2 ? $_[2] : other'. [ These ops currently assume that the lexical var being introduced is undef/empty and non-magival etc. This is an incorrect assumption and is fixed in a few commits' time ]
* Another op description correction: & -> &.Father Chrysostomos2016-05-201-3/+3
| | | | | The string bitwise ops have dots in them, which should be included in the op descriptions.
* Correct ‘bitiwse’ in two op descriptionsFather Chrysostomos2016-05-201-2/+2
| | | | Oops!
* Allow assignment to &CORE::keys()Father Chrysostomos2016-05-201-22/+24
|
* Add avhvswitch opFather Chrysostomos2016-05-201-1/+8
| | | | | &CORE::keys() et al. will use this to switch between keys and akeys depending on the argument type.
* regen/opcodes: Re-order aeach, akeys, and avaluesFather Chrysostomos2016-05-201-7/+7
| | | | | In a forthcoming commit, I will need them to be in the same order as the corresponding hash functions.
* [perl #128187] Forbid keys @_ in assigned lv subFather Chrysostomos2016-05-201-4/+4
| | | | | This is a continuation of this commit’s great grandparent, extending the error to arrays.
* split CXt_LOOP_FOR into CXt_LOOP_LIST,CXt_LOOP_ARYDavid Mitchell2016-02-031-3/+3
| | | | | | | | | | | | | | | Create a new context type so that "for (1,2,3)" and "for (@ary)" are now two separate types. For the list type, we store the index of the base stack element in the state union rather than having an array pointer. Currently this is just the same as blk_resetsp, but this will shortly allow us to eliminate the resetsp field from the struct block_loop - which is currently the largest sub-struct within the block union. Having two separate types also allows the two cases to be handled directly in the main switch in the hot pp_iter code, rather than having extra conditionals.
* split pp_postdec() from pp_postinc() and improveDavid Mitchell2015-11-101-4/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | pp_postinc() handles both $x++ and $x-- (and the integer variants pp_i_postinc/dec). Split it into two separate functions, as handling both inc and dec in the same function requires 3 extra conditionals. At the same time make the code more efficient. As currently written it: 1) checked for "bad" SVs (such as read-only) and croaked; 2) did a sv_setsv(TARG, TOPs) to return a copy of the original value; 2) checked for a IOK-only SV and if so, directly incremented the IVX slot; 3) else called out to sv_inc/dec() to handle the more complex cases. This commit combines the checks in (1) and (3) into one single big check of flags, and for the simple integer case, skips 2) and does a more efficient SETi() instead. For the non-simple case, both pp_postinc() and pp_postdec() now call a common static function to handle everything else. Porting/bench.pl shows the following raw numbers for '$y = $x++' ($x and $y lexical and holding integers): before after ------ ----- Ir 306.0 223.0 Dr 106.0 82.0 Dw 51.0 44.0 COND 48.0 33.0 IND 8.0 6.0 COND_m 1.9 0.0 IND_m 4.0 4.0
* split pp_predec() from pp_preinc() and improveDavid Mitchell2015-11-101-4/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | pp_preinc() handles both ++$x and --$x (and the integer variants pp_i_preinc/dec). Split it into two separate functions, as handling both inc and dec in the same function requires 3 extra conditionals. At the same time make the code more efficient. As currently written it: 1) checked for "bad" SVs (such as read-only) and croaked; 2) checked for a IOK-only SV and directly incremented the IVX slot; 3) else called out to sv_inc() to handle the more complex cases. This commit combines the checks in (1) and (2) into one single big check of flags, and anything "bad" simply skips the IOK-only code and calls sv_dec(), which can do its own checking of read-only etc and croak if necessary. Porting/bench.pl shows the following raw numbers for ++$x ($x lexical and holding an integer): before after -------- -------- Ir 77.0 56.0 Dr 30.0 24.0 Dw 10.0 10.0 COND 12.0 9.0 IND 2.0 2.0 COND_m -0.1 0.0 IND_m 2.0 2.0 Even having split the function into two, the combined size of the two new functions is smaller than the single previous function.
* Match ops no longer need OPpTARGET_MYFather Chrysostomos2015-09-291-228/+228
| | | | Actually, I don’t think they have needed it for a while.
* Remove OPpGREP_LEXFather Chrysostomos2015-09-291-122/+119
| | | | It is no longer used.
* re-implement OPpASSIGN_COMMON mechanismDavid Mitchell2015-08-171-207/+211
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This commit almost completely replaces the current mechanism for detecting and handing common vars in list assignment, e.g. ($a,$b) = ($b,$a); In general outline: it creates more false positives at compile-time than before, but also no longer misses some false negatives. In compensation, it considerably reduces the run-time cost of handling potential and real commonality. It does this firstly by splitting the OPpASSIGN_COMMON flag into 3 separate flags: OPpASSIGN_COMMON_AGG OPpASSIGN_COMMON_RC1 OPpASSIGN_COMMON_SCALAR which indicate different classes of commonality that can be handled in different ways at runtime. Most importantly, it distinguishes between two basic cases. Firstly, common scalars (OPpASSIGN_COMMON_SCALAR), e.g. ($x,....) = (....,$x,...) where $x is modified and then sometime later its value is used again, but that value has changed in the meantime. In this case, we need replace such vars on the RHS with mortal copies before processing the assign. The second case is an aggregate on the LHS (OPpASSIGN_COMMON_AGG), e.g. (...,@a) = (...., $a[0],...) In this case, the issue is instead that when @a is cleared, it may free items on the RHS (due to the stack not being ref counted). What is required here is that rather than making of a copy of each RHS element and storing it in the array as we progress, we make *all* the copies *before* clearing the array, but mortalise them in case we die in the meantime. We can further distinguish two scalar cases; sometimes it's possible to confirm non-commonality at run-time merely by checking that all the LHS scalars have a reference count of 1. If this is possible, we set the OPpASSIGN_COMMON_RC1 flag rather than the OPpASSIGN_COMMON_SCALAR flag. The major improvement in the run-time performance in the OPpASSIGN_COMMON_SCALAR case (or OPpASSIGN_COMMON_RC1 if rc>1 scalars are detected), is to use a mark-and-sweep scan of the two lists using the SVf_BREAK flag, to determine which elements are common, and only make mortal copies of those elements. This has a very big effect on run-time performance; for example in the classic ($a,$b) = ($b,$a); it would formerly make temp copies of both $a and $b; now it only copies $a. In more detail, the mark and sweep mechanism in pp_aassign works by looping through each LHS and RHS SV pair in parallel. It temporarily marks each LHS SV with the SVf_BREAK flag, then makes a copy of each RHS element only if it has the SVf_BREAK flag set. When the scan is finished, the flag is unset on all LHS elements. One major change in compile-time flagging is that package scalar vars are now treated as if they could always be aliased. So we don't bother any more to do the compile-time PL_generation checking on package vars (we still do it on lexical vars). We also no longer make use of the run-time PL_sawalias mechanism for detecting aliased package vars (and indeed the next commit but one will remove that mechanism). This means that more list assignment expressions which feature package vars will now need to do a runtime mark-and-sweep (or where appropriate, RC1) test. In compensation, we no longer need to test for aliasing and set PL_sawalias in pp_gvsv and pp_gv, nor reset PL_sawalias in every pp_nextstate. Part of the reasoning behind this is that it's nearly impossible to detect all possible package var aliasing; for example PL_sawalias would fail to detect XS code doing GvSV(gv) = sv. Note that we now scan the two children of the OP_AASSIGN separately, and in particular we mark lexicals with PL_generation only on the LHS and test only on the RHS. So something like ($x,$y) = ($default, $default) will no longer be regarded as having common vars. In terms of performance, running Porting/perlbench.pl on the new expr::aassign:: tests in t/perf/benchmarks show that the biggest slowdown is around 13% more instruction reads and 20% more conditional branches in this: setup => 'my ($v1,$v2,$v3) = 1..3; ($x,$y,$z) = 1..3;', code => '($x,$y,$z) = ($v1,$v2,$v3)', where this is now a false positive due to the presence of package variables. The biggest speedup is 50% less instruction reads and conditional branches in this: setup => '@_ = 1..3; my ($x,$y,$z)', code => '($x,$y,$z) = @_', because formerly the presence of @_ pessimised things if the LHS wasn't a my declaration (it's still pessimised, but the runtime's faster now). Conversely, we pessimise the 'my' variant too now: setup => '@_ = 1..3;', code => 'my ($x,$y,$z) = @_', this gives 5% more instruction reads and 11% more conditional branches now. But see the next commit, which will cheat for that particular construct.
* Delete experimental autoderef featureAaron Crane2015-07-131-25/+2
|
* [perl #123790] Disable targlex for some opsFather Chrysostomos2015-03-261-131/+131
| | | | | | | | | | | The targlex optimisation (which makes the op write directly to the lexical in $lexical = some op, skipping the assignment) does not take typeglob assignment into account. Since this optimisation has been enabled for some ops in 5.21.x, we actually have a regression. So this commit disables the optimisation once more for ops that did not have it on in 5.20. This is a temporary fix, until we find a better overall fix. Other ops that still have the optimisation are buggy, but no more buggy than in 5.20.
* [perl #123848] Allow OPpTARGET_MY on qrFather Chrysostomos2015-03-011-157/+156
| | | | | | | | // in the scope of lexical $_ gets the OPpTARGET_MY flag set. If it is used as an operand to smartmatch, it gets converted to a qr op. There is no need to turn off the flag, since it is harmless at run time. But we need to allow the flag on this op type to avoid asser- tion failures when it is freed.
* [perl #123763] pushre needs to permit OPpTARGET_MYHugo van der Sanden2015-02-281-81/+81
| | | | | | | | | | | | This case fails an assertion: my($_);0=split because a pushre op is not expected to have that flag. A pushre op starts out as a match op (which may indeed have the flag set), as is subsequently converted to a pushre op. [The commit message was written by the committer.]
* [perl #123753] Fix assertion failure with map+mapFather Chrysostomos2015-02-061-64/+63
| | | | | | | | ck_grep calls ck_fun, which sets the lower private bits to indicate the number of operands. ck_grep usually undoes that, by clobbering op_private completetly. If an error has occurred, it doesn’t, so we may fail an assertion if the lower bits are not expected to be set on mapstart and grepstart.
* Warning about experimental bitopsFather Chrysostomos2015-01-311-1/+1
|
* Add string- and number-specific bitop typesFather Chrysostomos2015-01-311-3/+61
| | | | | and also implement the pp functions, though nothing compiles to these ops yet.
* Add :const anon sub attributeFather Chrysostomos2015-01-191-1/+8
|
* complement can have OPpTARGET_MYFather Chrysostomos2015-01-051-5/+5
| | | | | | | It always reads its argument out the outset and always returns its target, so there is no reason its target cannot be a lexical. (The OPpTARGET_MY optimisation makes $lexical = <some op> have the op write directly to the lexical; the assignment gets optimised away.)
* Enable OPpTARGET_MY optimisation for cmp/<=>Father Chrysostomos2014-12-291-8/+8
| | | | | | | | | We can only do it for <=> under ‘use integer’. The non-integer <=> will push undef on to the stack. Enabling the optimisation for it would cause \($lexical = $x <=> "nan") to leave $lexical with its previous value and return a reference to &PL_sv_undef.
* [perl #123514] Make prototype() imply $_Father Chrysostomos2014-12-281-2/+2
| | | | | | | Previously it would read and replace the previous item on the stack: $ ./perl -le 'print "CORE::undef", prototype' ;\[$@%&*]
* op.c: Skip allocating entersub targ for Perl subFather Chrysostomos2014-12-211-1/+1
| | | | | | The target of entersub ops is only used by XSUBs to return things. Pure-Perl subs don’t use the target. (And if a pure-Perl sub is later replaced with an XS one, dXSTARG already has a workaround.)
* gelem and refassign can have OA_RETSCALARFather Chrysostomos2014-12-071-2/+2
| | | | | | | They only ever return scalars, but were not flagged that way. This change allows \*foo{THING} and \(\$x=\$y) to use srefgen, a faster version of refgen that handles only one item.
* Give require the OA_RETSCALAR flagFather Chrysostomos2014-12-071-1/+1
| | | | This way there is no need to call scalar() on the op separately.
* Add OP_MULTIDEREFDavid Mitchell2014-12-071-125/+137
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This op is an optimisation for any series of one or more array or hash lookups and dereferences, where the key/index is a simple constant or package/lexical variable. If the first-level lookup is of a simple array/hash variable or scalar ref, then that is included in the op too. So all of the following are replaced with a single op: $h{foo} $a[$i] $a[5][$k][$i] $r->{$k} local $a[0][$i] exists $a[$i]{$k} delete $h{foo} while these aren't: $a[0] already handled by OP_AELEMFAST $a[$x+1] not a simple index and these are partially replaced: (expr)->[0]{$k} the bit following (expr) is replaced $h{foo}[$x+1][0] the first and third lookups are each done with a multideref op, while the $x+1 expression and middle lookup are done by existing add, aelem etc ops. Up until now, aggregate dereferencing has been very heavyweight in ops; for example, $r->[0]{$x} is compiled as: gv[*r] s rv2sv sKM/DREFAV,1 rv2av[t2] sKR/1 const[IV 0] s aelem sKM/DREFHV,2 rv2hv sKR/1 gvsv[*x] s helem vK/2 When executing this, in addition to the actual calls to av_fetch() and hv_fetch(), there is a lot of overhead of pushing SVs on and off the stack, and calling lots of little pp() functions from the runops loop (each with its potential indirect branch miss). The multideref op avoids that by running all the code in a loop in a switch statement. It makes use of the new UNOP_AUX type to hold an array of typedef union { PADOFFSET pad_offset; SV *sv; IV iv; UV uv; } UNOP_AUX_item; In something like $a[7][$i]{foo}, the GVs or pad offsets for @a and $i are stored as items in the array, along with a pointer to a const SV holding 'foo', and the UV 7 is stored directly. Along with this, some UVs are used to store a sequence of actions (several actions are squeezed into a single UV). Then the main body of pp_multideref is a big while loop round a switch, which reads actions and values from the AUX array. The two big branches in the switch are ones that are affectively unrolled (/DREFAV, rv2av, aelem) and (/DREFHV, rv2hv, helem) triplets. The other branches are various entry points that handle retrieving the different types of initial value; for example 'my %h; $h{foo}' needs to get %h from the pad, while '(expr)->{foo}' needs to pop expr off the stack. Note that there is a slight complication with /DEREF; in the example above of $r->[0]{$x}, the aelem op is actually aelem sKM/DREFHV,2 which means that the aelem, after having retrieved a (possibly undef) value from the array, is responsible for autovivifying it into a hash, ready for the next op. Similarly, the rv2sv that retrieves $r from the typeglob is responsible for autovivifying it into an AV. This action of doing the next op's work for it complicates matters somewhat. Within pp_multideref, the autovivification action is instead included as the first step of the current action. In terms of benchmarking with Porting/bench.pl, a simple lexical $a[$i][$j] shows a reduction of approx 40% in numbers of instructions executed, while $r->[0][0][0] uses 54% fewer. The speed-up for hash accesses is relatively more modest, since the actual hash lookup (i.e. hv_fetch()) is more expensive than an array lookup. A lexical $h{foo} uses 10% fewer, while $r->{foo}{bar}{baz} uses 34% fewer instructions. Overall, bench.pl --tests='/expr::(array|hash)/' ... gives: PRE POST ------ ------ Ir 100.00 145.00 Dr 100.00 165.30 Dw 100.00 175.74 COND 100.00 132.02 IND 100.00 171.11 COND_m 100.00 127.65 IND_m 100.00 203.90 with cache misses unchanged at 100%. In general, the more lookups done, the bigger the proportionate saving.
* Speed up method calls like $o->Other::method() and $o->Other::SUPER::method().syber2014-12-021-1/+15
| | | | | | | | | | | | | | | It was done by adding new OP_METHOD_REDIR and OP_METHOD_REDIR_SUPER optypes. Class name to redirect is saved into METHOP as a shared hash string. Method name is changed (class name removed) an saved into op_meth_sv as a shared string hash. So there is no need now to scan for '::' and calculate class and method names at runtime (in gv_fetchmethod_*) and searching cache HV without precomputed hash. B::* modules are changed to support new op types. method_redir is now printed by Concise like (for threaded perl) $obj->AAA::meth 5 <.> method_redir[PACKAGE "AAA", PV "meth"] ->6
* speedup for SUPER::method() calls.syber2014-11-281-1/+8
| | | | | | | | | | | | | | | In ck_method: Scan for '/::. If found SUPER::, create OP_METHOD_SUPER op with precomputed hash value for method name. In B::*, added support for method_super In pp_hot.c, pp_method_*: S_method_common removed, code related to getting stash is moved to S_opmethod_stash, other code is moved to pp_method_* functions. As a result, SUPER::func() calls speeded up by 50%.
* rename [] from "anonymous list" to "anonymous array"Lukas Mai2014-11-111-1/+1
|
* Don’t allow OPpTARGET_MY with integer negationFather Chrysostomos2014-11-101-5/+5
| | | | | | | | | $ ./perl -Ilib -le 'use integer; my $a = "fake"; $a = -$a; print "[$a]"' [--] As of 1c2b3fd6f1, negation under ‘use integer’ can do string negation, which modifies the return value before reading the argument. So, like regular non-integer negation, it must forego this optimisation.
* Don’t allow OPpTARGET_MY on postdec/incFather Chrysostomos2014-11-091-14/+14
| | | | | | | | | | | | | | | | I was wrong in 9e319cc4f. postfix ++/-- writes to its return value before reading its argument. If we optimise away the scalar assignment in $a = $b++; (that’s what OPpTARGET_MY does), then $a gets written to before $b is read. If $a and $b are the same, we get the wrong answer. This bug has been present under ‘use integer’ since 5.6.0. I accidentally extended it to non-integer ++/-- in 9e319cc4f. (It’s not likely that someone will write $a = $b++, but it could hap- pen inadvertently in more complex code.)
* Shrink PL_op_private_bitdefsFather Chrysostomos2014-11-081-673/+393
| | | | | | | | | | | It doesn’t matter whether things in this table are ordered by opcode, because the indices into it are stored in PL_op_private_bitdef_ix. If we have multiple ops with exactly the same private flags, we don’t need multiple entries in PL_op_private_bitdefs. One practical advantage is that patches are less likely to conflict, which will make rebasing easier. (I hope.)
* values and each are OA_DANGEROUSFather Chrysostomos2014-11-081-6/+6
| | | | | | | | | | | | | | OA_DANGEROUS indicates that temporary copies may need to be made in list assignment, to handle things like: ($a, $b) = ($b, $a); In other words, an op type is flagged with OA_DANGEROUS if its return values could occur elsewhere on the stack. values and each can both return scalars that are referenced elsewhere, causing list assignment to behave erratically if temporary copies are not made.
* kill is not OA_DANGEROUSFather Chrysostomos2014-11-081-1/+1
| | | | | | | | | | | | | OA_DANGEROUS indicates that temporary copies may need to be made in list assignment, to handle things like: ($a, $b) = ($b, $a); In other words, an op type is flagged with OA_DANGEROUS if its return values could occur elsewhere on the stack. kill only ever returns a target unused elsewhere, so it does not necessitate temp copies in list assignment.
* exec is not OA_DANGEROUSFather Chrysostomos2014-11-081-1/+1
| | | | | | | | | | | | | OA_DANGEROUS indicates that temporary copies may need to be made in list assignment, to handle things like: ($a, $b) = ($b, $a); In other words, an op type is flagged with OA_DANGEROUS if its return values could occur elsewhere on the stack. When exec fails, it only ever returns a target unused elsewhere, so it does not necessitate temp copies in list assignment.
* enterwrite is not OA_DANGEROUSFather Chrysostomos2014-11-081-1/+1
| | | | | | | | | | | | | OA_DANGEROUS indicates that temporary copies may need to be made in list assignment, to handle things like: ($a, $b) = ($b, $a); In other words, an op type is flagged with OA_DANGEROUS if its return values could occur elsewhere on the stack. ‘write’ only ever returns a read-only true or false, so temp copies are not necessary for its sake.
* tied is OA_DANGEROUSFather Chrysostomos2014-11-081-1/+1
| | | | | | | | | | | | | | | | | | | | | | OA_DANGEROUS indicates that temporary copies may need to be made in list assignment, to handle things like: ($a, $b) = ($b, $a); In other words, an op type is flagged with OA_DANGEROUS if its return values could occur elsewhere on the stack. tied returns the same scalar that the tied variables uses to hold a reference to the object (so weaken(tied(...)) works). tie uses the very scalar that TIESCALAR (or TIEWHATEVER) returns and attaches it to the tied variable by magic. That returned scalar could be referenced elsewhere. That means ($a, $b) = ($c, tied $d) could have common vars on either side, if the tie constructor for $d happened to return $a or $b. (Normally it would have to be an XSUB or an lvalue sub for its return value not to have been copied.)
* Remove OA_DANGEROUS from exitFather Chrysostomos2014-11-081-1/+1
| | | | | | | | | | | | | OA_DANGEROUS indicates that temporary copies may need to be made in list assignment, to handle things like: ($a, $b) = ($b, $a); In other words, an op type is flagged with OA_DANGEROUS if its return values could occur elsewhere on the stack. exit usually doesn’t return. When it fails, it returns a read-only undef, so we don’t need temp copies for its sake.
* Remove OA_DANGEROUS from loopctl-type opsFather Chrysostomos2014-11-081-5/+5
| | | | | | | | | | | | | | | | OA_DANGEROUS indicates that temporary copies may need to be made in list assignment, to handle things like: ($a, $b) = ($b, $a); In other words, an op type is flagged with OA_DANGEROUS if its return values could occur elsewhere on the stack. These operators never return, so they shouldn’t necessitate temp copies. (This could probably apply to dump, too, but I don’t fully under- stand dump.)
* Remove OA_DANGEROUS from dieFather Chrysostomos2014-11-081-1/+1
| | | | | | | | | | | | OA_DANGEROUS indicates that temporary copies may need to be made in list assignment, to handle things like: ($a, $b) = ($b, $a); In other words, an op type is flagged with OA_DANGEROUS if its return values could occur elsewhere on the stack. die never returns, so it shouldn’t necessitate temp copies.
* Remove OA_DANGEROUS from cond_exprFather Chrysostomos2014-11-081-1/+1
| | | | | | | | | | | | | | OA_DANGEROUS indicates that temporary copies may need to be made in list assignment, to handle things like: ($a, $b) = ($b, $a); In other words, an op type is flagged with OA_DANGEROUS if its return values could occur elsewhere on the stack. ?: always returns one of its arguments. Since aassign_common_vars, which does the danger check, also checks the kids of the cond_expr op, it is not necessary for cond_expr to be flagged this way.
* Remove OA_DANGEROUS from grep and mapFather Chrysostomos2014-11-081-4/+4
| | | | | | | | | | | | | | | OA_DANGEROUS indicates that temporary copies may need to be made in list assignment, to handle things like: ($a, $b) = ($b, $a); In other words, an op type is flagged with OA_DANGEROUS if its return values could occur elsewhere on the stack. grep returns its arguments, while map returns the results of its first expression. Since aassign_common_vars, which does the danger check, will also check the kids of the mapstart/grepstart ops, it is not nec- essary for grep and map themselves to be flagged this way.