summaryrefslogtreecommitdiff
path: root/pp_hot.c
Commit message (Collapse)AuthorAgeFilesLines
* Revert "pp_helem: Remove branch seemingly untaken (v2)"Steffen Mueller2015-04-081-1/+2
| | | | | | | | | | | | | | This reverts commit d9dc8e0c5019810bfa3840ecadb302a2f01e01ae because it breaks autovivification.pm. Vincent writes in a mail to p5p: > This is a friendly notification that this change, while > being correct as far as I can tell, has broken > autovivification.pm (the CPAN module) quite heavily. [...] > fixing the module to make it work with blead will probably > require a complete rewrite So clearly, this change isn't worth having.
* [perl #123790] Assert fail with *x=<y>Father Chrysostomos2015-03-251-2/+1
| | | | | | | | | When assigning undef to its target, readline needs to take into account that it might be a typeglob. sv_setsv knows how handle this, but SvOK_off is simply wrong. This fixes this particular crash, but other issues in the ticket are as yet unresolved.
* Replace common Emacs file-local variables with dir-localsDagfinn Ilmari Mannsåker2015-03-221-6/+0
| | | | | | | | | | | | | | | | An empty cpan/.dir-locals.el stops Emacs using the core defaults for code imported from CPAN. Committer's work: To keep t/porting/cmp_version.t and t/porting/utils.t happy, $VERSION needed to be incremented in many files, including throughout dist/PathTools. perldelta entry for module updates. Add two Emacs control files to MANIFEST; re-sort MANIFEST. For: RT #124119.
* pp_helem: Remove branch seemingly untaken (v2)Steffen Mueller2015-03-151-2/+1
| | | | | | | | | | | An HV* that is not an SVt_PVHV? Maybe I don't have sufficient fantasy. This branch goes back to 1994, so things have changed ... a bit since then. This is the second attempt at doing this small change since last time, I was dumb enough to get the condition in the assert inverted. m( Thanks to Brett for pointing that out nicely!
* Improve comments at head of pp_signature()David Mitchell2015-03-111-6/+6
|
* pp_hot.c: Note that amagic_call calls pp_pushmarkFather Chrysostomos2015-01-311-1/+2
|
* avoid C labels in column 0David Mitchell2015-01-211-2/+2
| | | | | | | | | Generally the guideline is to outdent C labels (e.g. 'foo:') 2 columns from the surrounding code. If the label starts at column zero, then it means that diffs, such as those generated by git, display the label rather than the function name at the head of a diff block: which makes diffs harder to peruse.
* Revert "refactor gv_add_by_type"Matthew Horsfall2015-01-201-2/+4
| | | | | | | This reverts commit 819b139db33e2022424694e381422766903d4f65. This could be repapplied for 5.23.1, with modifications or additional patches to solve the breakage discussed in RT 123580.
* refactor gv_add_by_typeDaniel Dragan2015-01-061-4/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | gv_add_by_type was added in commit d5713896ec in 5.11.0 . Improve gv_add_by_type by making it return the newly created SV*, instead of the the GV *, which the caller must deref both the GV head to get svu and then deref a slice into the GP, even though it already derefed svu and GP right before, to figure out whether to call gv_add_by_type in the first place. The original version of this patch had gv_add_by_type returning a SV ** to ensure lvalue-ness but it was discovered it wasn't needed and not smart. -rename gv_add_by_type since it was removed from public api and its proto changed -remove null check since it is impossible to pass null through GvAVn(), and unlikely with gv_AVadd, null segvs reliably crash in the rare case of a problem -instead of S_gv_init_svtype and gv_add_by_type using a tree of logic/ conditional jumps in asm, use a lookup table, GPe (e=enum or entry) enums are identical to offsets into the GP struct, all of then fit under 0xFF, if the CC and CPU arch wants, CC can load the const once into a register, then use the number for the 2nd deref, then use the number again as an arg to gv_add_by_type, the low (&~0xf) or high (<<2) 2 bits in a GPe can be used for something else in the future since GPe is pointer aligned -SVt_LAST triggers "panic: sv_upgrade to unknown type", so use that value for entries of a GP which are not SV head *s and are invalid to pass as an arg -remove the tree of logic in S_gv_init_svtype, replace with a table -S_gv_init_svtype is now tail call friendly and very small -change the GV**n to be rvalues only, assigning to GV**n is probably a memory leak -fix 1 core GV**n as lvalue use -GvSVn's unusual former definition is from commit 547f15c3f9 in 2005 and DEFSV as lvalue is gone in core as of commit 414bf5ae08 from 2008 since all the GV**n macros are now rvalues, this goes too -PTRPTR2IDX and PTRSIZELOG2 could use better names -in pp_rv2av dont declare strings like that VC linker won't dedup that, and other parts of core also have "an ARRAY", perl521.dll previously had 2 "an ARRAY" and "a HASH" strings in it due to this before VC 2003 32 perl521.dll .text 0xc8813 in machine code bytes after .text 0xc8623
* fix -IV_MIN negationsDavid Mitchell2014-12-311-4/+5
| | | | | | | | | | | Doing uv = -iv is undefined behaviour if iv happens to be IV_MIN. This occurs in several places in the perl sources. Found by -fsanitize=undefined. Here's a typical message: sv.c:2864:7: runtime error: negation of -9223372036854775808 cannot be represented in type 'IV' (aka 'long'); cast to an unsigned type to negate this value to itself
* pp_hot.c:pp_concat: Remove SvGETMAGICFather Chrysostomos2014-12-271-3/+0
| | | | | | | If the operand is magical, try_amagic_bin will already have copied the operand if both left and right were the same, so left == right will no longer be true by the time this path is reached. This has been the case since v5.13.11-400-g75ea7a1.
* pp_hot.c:pp_concat: Remove PUTBACK/SPAGAINFather Chrysostomos2014-12-271-3/+0
| | | | | sv_utf8_upgrade_nomg does not reallocate the stack, as of v5.19.6-25-g7a3f960.
* [perl #103260] Fix s/// with long stringsFather Chrysostomos2014-12-231-4/+4
| | | | | | | | | | | | | | | | | This is also the subject of perl #123071. The iteration count was stored in an I32 and was overflowing. If the maximum number of iterations possible overflowed, then it would become negative, and the substitution would fail immediately with ‘Substitu- tion loop’. I tried fixing this without increasing the size of the context stack entries on 64-bit builds (by skipping the loop check for long strings), but was unable to, because we have to return the number of iterations, which was also stored as I32. If we change just that one to SSize_t, we get an I32-sized alignment hole, so we might as well make maxiters a SSize_t as well, fixing the bug that way (the more straightforward way).
* Use GIMME_V in preference to GIMMEFather Chrysostomos2014-12-191-1/+1
| | | | | | | | | GIMME_V is a simpler macro that results in smaller machine code. GIMME does not distinguish between scalar and void context. The two instances of GIMME == G_SCALAR that I changed (which used to match void context too, but no longer do) are in code paths unreachable in void context, so we don’t need to check for it.
* pp_readline: Don’t set PL_last_in_gv to &PL_sv_undefFather Chrysostomos2014-12-151-0/+4
| | | | | | | Code elsewhere assumes it is always a GV or NULL: readline "foo"; my $lastfh = "${^LAST_FH}";
* Add OP_MULTIDEREFDavid Mitchell2014-12-071-0/+436
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* Revert "Remove branch seemingly untaken"Steffen Mueller2014-12-051-1/+2
| | | | | | This reverts commit 9349a6bbb9de151e5385038b962ceff7c7278b53. It is taken. Sigh. I'm sorry.
* Remove branch seemingly untakenSteffen Mueller2014-12-051-2/+1
| | | | | | An HV* that is not an SVt_PVHV? Maybe I don't have sufficient fantasy. This branch goes back to 1994, so things have changed ... a bit since then.
* Speed up method calls like $o->Other::method() and $o->Other::SUPER::method().syber2014-12-021-22/+53
| | | | | | | | | | | | | | | 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
* define and use STATIC_ASSERT_STMT for compile-time invariantsLukas Mai2014-11-291-1/+1
|
* make more use of NOT_REACHEDLukas Mai2014-11-291-1/+1
| | | | In particular, remove all instances of 'assert(0);'.
* speedup for SUPER::method() calls.syber2014-11-281-54/+86
| | | | | | | | | | | | | | | 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%.
* Remove op_const_class; just use the name on the stacksyber2014-11-241-10/+10
| | | | | | | Instead of storing the class name in the op_const_class field of the METHOP in addition to pushing it on to the stack, just use the item on the stack. This also makes $class->method faster if $class is already a shared hash string.
* This commit speeds up class method calls when class name is constant.syber2014-11-231-4/+10
| | | | | | | | | | | | | | | | I.e. MyClass->method() and MyClass->$dynamic_method() By about 30%. It was done by saving class name (as shared COW string) in METHOP and later checking it in method_common(). If it was set, then it fetches stash via gv_stashsv using precomputed hash value instead of falling into a bunch of conditions and fetching stash without hash value.
* Make a function to get PL_encoding's valueKarl Williamson2014-11-201-2/+2
| | | | | | This is in preparation for making the retrieval more complex in future commits than it is now. This is going into mg.c because the value is magical.
* Make testing for PL_encoding into a macroKarl Williamson2014-11-201-2/+2
| | | | This is in preparation for making the test more complicated.
* Don’t check OPpTARGET_MY on match ops at run timeFather Chrysostomos2014-11-091-2/+2
| | | | | The offset in op_targ is sufficient. The next commit will take advan- tage of this.
* Remove very obsolete commentFather Chrysostomos2014-10-201-3/+1
| | | | | | | | | | | | | | | | | I chuckle every time I read this comment. And I chuckled at the time it got ignored and mangled, too. :-) 17ab7946 reworked some code without reindenting a block. And that lack of indentation was intentional and noted by this comment. 96913b52 four years later reindented the code, ignoring the comment. 486ec47a corrected the spelling mistake in the comment, rendering it incomprehensible. ‘Intenting’ was supposed to be ‘indenting’ (it was obvious to me), but got ‘corrected’ to ‘intending’. d5524600 gutted almost the entire block, moving it into a static rou- tine, so the comment is by now not even remotely relevant.
* foreach \$varFather Chrysostomos2014-10-111-0/+5
| | | | Some passing tests are still marked to-do. We need more tests still.
* Assignment to \(@array)Father Chrysostomos2014-10-111-4/+27
| | | | | | | | | | | | | | | This is a slurpy lvalue that gobbles up all the rhs elements, which are expected to be references. So \(@a)=\(@b) makes @a share the same elements as @b. We implement this by pushing a null on to the stack as a special marker that pp_aassign will recognise. I decided to change the wording for the \local(@a)=... error slightly, from what my to-do tests had. Some of the other to-do tests were badly written and had to be fixed up a bit.
* Make OP_METHOD* to be of new class METHOPsyber2014-10-031-3/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Introduce a new opcode class, METHOP, which will hold class/method related info needed at runtime to improve performance of class/object method calls, then change OP_METHOD and OP_METHOD_NAMED from being UNOP/SVOP to being METHOP. Note that because OP_METHOD is a UNOP with an op_first, while OP_METHOD_NAMED is an SVOP, the first field of the METHOP structure is a union holding either op_first or op_sv. This was seen as less messy than having to introduce two new op classes. The new op class's character is '.' Nothing has changed in functionality and/or performance by this commit. It just introduces new structure which will be extended with extra fields and used in later commits. Added METHOP constructors: - newMETHOP() for method ops with dynamic method names. The only optype for this op is OP_METHOD. - newMETHOP_named() for method ops with constant method names. Optypes for this op are: OP_METHOD_NAMED (currently) and (later) OP_METHOD_SUPER, OP_METHOD_REDIR, OP_METHOD_NEXT, OP_METHOD_NEXTCAN, OP_METHOD_MAYBENEXT (This commit includes fixups by davem)
* Introduce the double-diamond operator <<>>Rafael Garcia-Suarez2014-09-301-2/+2
| | | | | | | | | | | This operator works like <> or <ARGV>, as it reads the list of file names to open from the command-line arguments. However, it disables the magic-open feature (that forks to execute piped commands) : $ bleadperl -e 'while(<>){print}' 'echo foo |' foo $ bleadperl -e 'while(<<>>){print}' 'echo foo |' Can't open echo foo |: No such file or directory at -e line 1.
* Add flags to cv_name; allow unqualified retvalFather Chrysostomos2014-09-241-2/+2
| | | | | | | | | | One of the main purposes of cv_name was to provide a way for CPAN mod- ules easily to obtain the name of a sub. As written, it was not actually sufficient, as some modules, such as Devel::Declare, need an unqualified name. So I am breaking compatibility with 5.21.4 (which introduced cv_name, but is only a dev release) by adding a flags parameter.
* comment pp_foo aliases in pp*.cDavid Mitchell2014-09-191-0/+23
| | | | | | | | Where pp_foo() also handles OP_BAR, add a comment above the function mentioning that it also does pp_bar. This means that "grep pp_bar pp*.c" quickly locates the file/function that handles OP_BAR.
* Skip no-common-vars optimisation for aliasesFather Chrysostomos2014-09-181-1/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | The ‘no common vars’ optimisation allows perl to copy the values straight from the rhs to the lhs in a list assignment. In ($a,$b) = ($c,$d), that means $c gets assigned to $a, then $d to $b. If the same variable occurs on both sides of the expression (($a,$b)=($b,$a)), then it is necessary to make temporary copies of the variables on the rhs, before assigning them to the left. If some variables have been aliased to others, then the common vars detection can be fooled: *x = *y; $x = 3; ($x, $z) = (1, $y); That assigns 1 to $x, and then goes to assign $y to $z, but $y is the same as $x, which has just been clobbered. So 1 gets assigned instead of 3. This commit solves this by recording in each typeglob whether the sca- lar is an alias of a scalar from elsewhere. If such a glob is encountered, then the entire expression is ‘tainted’ such that list assignments will assume there might be common vars.
* Remove !IS_PADGV assertionsFather Chrysostomos2014-09-171-4/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Commit 60779a30f stopped setting PADTMP on GVs in pads, and changed many instances of if(SvPADTMP && !IS_PADGV) to if(SvPADTMP){assert(!IS_PADGV)...}. This PADTMP was leftover from the original ithreads implementation that marked these as PADTMP under the assumption that anything in a pad had to be marked PADMY or PADTMP. Since we don’t want these GVs copied the way operator targets are (PADTMP indicates the latter), we needed this !IS_PADGV check all over the place. 60779a30f was actually right in removing the flag and the !IS_PADGV check, because it should be possible for XS modules to create ops that return copiable GVs. But the assertions prevent that from working. More importantly (to me at least), this IS_PADGV doesn’t quite make sense and I am trying to eliminate it. BTW, you have to be doubly naughty, but it is possible to fail these assertions: $ ./perl -Ilib -e 'BEGIN { sub { $::{foo} = \@_; constant::_make_const(@_) }->(*bar) } \ foo' Assertion failed: (!IS_PADGV(sv)), function S_refto, file pp.c, line 576. Abort trap: 6
* Use cv_name in pp_hot.c:sub_crush_depthFather Chrysostomos2014-09-151-10/+1
| | | | | The next commit will allow lexical subs with GVs to reach this code path, so use cv_name, since it knows how to handle those.
* For lexical subs, reify CvGV from CvSTASH and CvNAME_HEKFather Chrysostomos2014-09-151-5/+5
| | | | | From now on, the presence of a name hek implies a GV. Any access to CvGV will cause that implicit GV to be reified.
* Make S_method_common use gv_stashpvn instead of copypasted cache usagesyber2014-08-201-24/+6
| | | | | | The previous commit copied the PL_stashcache handling code from S_method_common() to gv_stashpvn(), so now we can call that function directly rather than doing it ourselves.
* Remove or downgrade unnecessary dVAR.Jarkko Hietaniemi2014-06-251-40/+29
| | | | | | | | You need to configure with g++ *and* -Accflags=-DPERL_GLOBAL_STRUCT or -Accflags=-DPERL_GLOBAL_STRUCT_PRIVATE to see any difference. (g++ does not do the "post-annotation" form of "unused".) The version code has some of these issues, reported upstream.
* Adding missing SVfARG() invocationsBrian Fraser2014-06-131-2/+2
| | | | This silences a chunk of warnings under -Wformat
* Use PERL_UNUSED_RESULT.Jarkko Hietaniemi2014-06-021-23/+22
| | | | | | | (1) Enhance its description. (2) Simplify it: define only if has warn_unused_result. (3) Make it use STMT_START { ... } STMT_END to be less GNU-extensiony. (4) Redo 04783dc7 ("fix 'ignoring return value' compiler warnings") with it.
* Unify the "fall-through" lint annotation.Jarkko Hietaniemi2014-05-291-2/+2
| | | | | | | Used by linters (static checkers), and also good for human readers. Even though "FALL THROUGH" seems to be the most common, e.g BSD lint manual only knows "FALLTHROUGH" (or "FALLTHRU").
* Insert asserts to paths suspected by Coverity.Jarkko Hietaniemi2014-05-291-2/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Coverity suspects paths like this: (1) p = foo(); if (!p) p = bar(); baz(p->q); since it cannot prove that p is always non-NULL at the dereference. (2) Or simply something like: mg = mg_find(...); foo(mg->blah); Since mg_find() can fail returning NULL. Adding assert() calls before the dereferences. Testing with -DDEBUGGING. Hopefully there are regular smokes doing the same. [perl #121894] Fix for Coverity perl5 CIDs 28950,28952..28955,28964,28967,28970..28795,49921: CID ...: Dereference after null check (FORWARD_NULL) var_deref_op: Dereferencing null pointer p->q (TODO: Coverity perl5 CIDs 28962,28968,28969: the same issue, but would conflict with already in-flight changes, prepare catch-up patch later.) --- dist/Data-Dumper/Dumper.xs | 1 + dump.c | 1 + ext/Devel-Peek/Peek.xs | 1 + ext/XS-APItest/APItest.xs | 1 + mg.c | 2 ++ mro.c | 4 +++- op.c | 4 ++++ perlio.c | 1 + pp_hot.c | 5 +++-- regcomp.c | 3 +++ regexec.c | 5 ++++- universal.c | 2 +- util.c | 4 +++- 13 files changed, 28 insertions(+), 6 deletions(-) diff --git a/dist/Data-Dumper/Dumper.xs b/dist/Data-Dumper/Dumper.xs index 12c4ebd..23e0cf4 100644 --- a/dist/Data-Dumper/Dumper.xs +++ b/dist/Data-Dumper/Dumper.xs @@ -641,6 +641,7 @@ DD_dump(pTHX_ SV *val, const char *name, STRLEN namelen, SV *retval, HV *seenhv, else { sv_pattern = val; } + assert(sv_pattern); rval = SvPV(sv_pattern, rlen); rend = rval+rlen; slash = rval; diff --git a/dump.c b/dump.c index 59be3e0..c2d72fd 100644 --- a/dump.c +++ b/dump.c @@ -471,6 +471,7 @@ Perl_sv_peek(pTHX_ SV *sv) finish: while (unref--) sv_catpv(t, ")"); + /* XXX when is sv ever NULL? */ if (TAINTING_get && SvTAINTED(sv)) sv_catpv(t, " [tainted]"); return SvPV_nolen(t); diff --git a/ext/Devel-Peek/Peek.xs b/ext/Devel-Peek/Peek.xs index 679efa5..b20fa94 100644 --- a/ext/Devel-Peek/Peek.xs +++ b/ext/Devel-Peek/Peek.xs @@ -450,6 +450,7 @@ PPCODE: BOOT: { CV * const cv = get_cvn_flags("Devel::Peek::Dump", 17, 0); + assert(cv); cv_set_call_checker(cv, S_ck_dump, (SV *)cv); XopENTRY_set(&my_xop, xop_name, "Dump"); diff --git a/ext/XS-APItest/APItest.xs b/ext/XS-APItest/APItest.xs index a51924d..18ba381 100644 --- a/ext/XS-APItest/APItest.xs +++ b/ext/XS-APItest/APItest.xs @@ -2096,6 +2096,7 @@ newCONSTSUB(stash, name, flags, sv) break; } EXTEND(SP, 2); + assert(mycv); PUSHs( CvCONST(mycv) ? &PL_sv_yes : &PL_sv_no ); PUSHs((SV*)CvGV(mycv)); diff --git a/mg.c b/mg.c index 76912bd..7f3339a 100644 --- a/mg.c +++ b/mg.c @@ -1675,6 +1675,7 @@ Perl_magic_clearisa(pTHX_ SV *sv, MAGIC *mg) same function. */ mg = mg_find(mg->mg_obj, PERL_MAGIC_isa); + assert(mg); if (SvTYPE(mg->mg_obj) == SVt_PVAV) { /* multiple stashes */ SV **svp = AvARRAY((AV *)mg->mg_obj); I32 items = AvFILLp((AV *)mg->mg_obj) + 1; @@ -3437,6 +3438,7 @@ Perl_magic_copycallchecker(pTHX_ SV *sv, MAGIC *mg, SV *nsv, sv_magic(nsv, &PL_sv_undef, mg->mg_type, NULL, 0); nmg = mg_find(nsv, mg->mg_type); + assert(nmg); if (nmg->mg_flags & MGf_REFCOUNTED) SvREFCNT_dec(nmg->mg_obj); nmg->mg_ptr = mg->mg_ptr; nmg->mg_obj = SvREFCNT_inc_simple(mg->mg_obj); diff --git a/mro.c b/mro.c index 1b37ca7..ccf4bf4 100644 --- a/mro.c +++ b/mro.c @@ -638,12 +638,14 @@ Perl_mro_isa_changed_in(pTHX_ HV* stash) hv_storehek(mroisarev, namehek, &PL_sv_yes); } - if((SV *)isa != &PL_sv_undef) + if ((SV *)isa != &PL_sv_undef) { + assert(namehek); mro_clean_isarev( isa, HEK_KEY(namehek), HEK_LEN(namehek), HvMROMETA(revstash)->isa, HEK_HASH(namehek), HEK_UTF8(namehek) ); + } } } } diff --git a/op.c b/op.c index 796cb03..79621ce 100644 --- a/op.c +++ b/op.c @@ -2907,6 +2907,7 @@ S_my_kid(pTHX_ OP *o, OP *attrs, OP **imopsp) S_cant_declare(aTHX_ o); } else if (attrs) { GV * const gv = cGVOPx_gv(cUNOPo->op_first); + assert(PL_parser); PL_parser->in_my = FALSE; PL_parser->in_my_stash = NULL; apply_attrs(GvSTASH(gv), @@ -2929,6 +2930,7 @@ S_my_kid(pTHX_ OP *o, OP *attrs, OP **imopsp) else if (attrs && type != OP_PUSHMARK) { HV *stash; + assert(PL_parser); PL_parser->in_my = FALSE; PL_parser->in_my_stash = NULL; @@ -10229,6 +10231,7 @@ Perl_ck_split(pTHX_ OP *o) op_append_elem(OP_SPLIT, o, newDEFSVOP()); kid = kid->op_sibling; + assert(kid); scalar(kid); if (!kid->op_sibling) @@ -10902,6 +10905,7 @@ Perl_cv_set_call_checker(pTHX_ CV *cv, Perl_call_checker ckfun, SV *ckobj) MAGIC *callmg; sv_magic((SV*)cv, &PL_sv_undef, PERL_MAGIC_checkcall, NULL, 0); callmg = mg_find((SV*)cv, PERL_MAGIC_checkcall); + assert(callmg); if (callmg->mg_flags & MGf_REFCOUNTED) { SvREFCNT_dec(callmg->mg_obj); callmg->mg_flags &= ~MGf_REFCOUNTED; diff --git a/perlio.c b/perlio.c index d4c43d0..e6ff9e4 100644 --- a/perlio.c +++ b/perlio.c @@ -2225,6 +2225,7 @@ PerlIOBase_dup(pTHX_ PerlIO *f, PerlIO *o, CLONE_PARAMS *param, int flags) PerlIO_funcs * const self = PerlIOBase(o)->tab; SV *arg = NULL; char buf[8]; + assert(self); PerlIO_debug("PerlIOBase_dup %s f=%p o=%p param=%p\n", self ? self->name : "(Null)", (void*)f, (void*)o, (void*)param); diff --git a/pp_hot.c b/pp_hot.c index 2cccc48..9c9d1e9 100644 --- a/pp_hot.c +++ b/pp_hot.c @@ -3078,6 +3078,7 @@ S_method_common(pTHX_ SV* meth, U32* hashp) const HE* const he = hv_fetch_ent(stash, meth, 0, *hashp); if (he) { gv = MUTABLE_GV(HeVAL(he)); + assert(stash); if (isGV(gv) && GvCV(gv) && (!GvCVGEN(gv) || GvCVGEN(gv) == (PL_sub_generation + HvMROMETA(stash)->cache_gen))) @@ -3085,9 +3086,9 @@ S_method_common(pTHX_ SV* meth, U32* hashp) } } + assert(stash || packsv); gv = gv_fetchmethod_sv_flags(stash ? stash : MUTABLE_HV(packsv), - meth, GV_AUTOLOAD | GV_CROAK); - + meth, GV_AUTOLOAD | GV_CROAK); assert(gv); return isGV(gv) ? MUTABLE_SV(GvCV(gv)) : MUTABLE_SV(gv); diff --git a/regcomp.c b/regcomp.c index eaee604..3d49827 100644 --- a/regcomp.c +++ b/regcomp.c @@ -2007,6 +2007,7 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch, }); re_trie_maxbuff = get_sv(RE_TRIE_MAXBUF_NAME, 1); + assert(re_trie_maxbuff); if (!SvIOK(re_trie_maxbuff)) { sv_setiv(re_trie_maxbuff, RE_TRIE_MAXBUF_INIT); } @@ -14920,6 +14921,7 @@ S_set_ANYOF_arg(pTHX_ RExC_state_t* const pRExC_state, av_store(av, 0, (runtime_defns) ? SvREFCNT_inc(runtime_defns) : &PL_sv_undef); if (swash) { + assert(cp_list); av_store(av, 1, swash); SvREFCNT_dec_NN(cp_list); } @@ -16609,6 +16611,7 @@ S_dumpuntil(pTHX_ const regexp *r, const regnode *start, const regnode *node, last= plast; while (PL_regkind[op] != END && (!last || node < last)) { + assert(node); /* While that wasn't END last time... */ NODE_ALIGN(node); op = OP(node); diff --git a/regexec.c b/regexec.c index 362390b..ffab4f2 100644 --- a/regexec.c +++ b/regexec.c @@ -7010,6 +7010,8 @@ no_silent: sv_commit = &PL_sv_yes; sv_yes_mark = &PL_sv_no; } + assert(sv_err); + assert(sv_mrk); sv_setsv(sv_err, sv_commit); sv_setsv(sv_mrk, sv_yes_mark); } @@ -7620,6 +7622,7 @@ Perl__get_regclass_nonbitmap_data(pTHX_ const regexp *prog, *only_utf8_locale_ptr = ary[2]; } else { + assert(only_utf8_locale_ptr); *only_utf8_locale_ptr = NULL; } @@ -7641,7 +7644,7 @@ Perl__get_regclass_nonbitmap_data(pTHX_ const regexp *prog, } else if (doinit && ((si && si != &PL_sv_undef) || (invlist && invlist != &PL_sv_undef))) { - + assert(si); sw = _core_swash_init("utf8", /* the utf8 package */ "", /* nameless */ si, diff --git a/universal.c b/universal.c index a29696d..65e02df 100644 --- a/universal.c +++ b/universal.c @@ -67,7 +67,7 @@ S_isa_lookup(pTHX_ HV *stash, const char * const name, STRLEN len, U32 flags) if (our_stash) { HEK *canon_name = HvENAME_HEK(our_stash); if (!canon_name) canon_name = HvNAME_HEK(our_stash); - + assert(canon_name); if (hv_common(isa, NULL, HEK_KEY(canon_name), HEK_LEN(canon_name), HEK_FLAGS(canon_name), HV_FETCH_ISEXISTS, NULL, HEK_HASH(canon_name))) { diff --git a/util.c b/util.c index b90abe5..cd0afb6 100644 --- a/util.c +++ b/util.c @@ -850,15 +850,17 @@ Perl_fbm_instr(pTHX_ unsigned char *big, unsigned char *bigend, SV *littlestr, U { const MAGIC *const mg = mg_find(littlestr, PERL_MAGIC_bm); - const unsigned char * const table = (const unsigned char *) mg->mg_ptr; const unsigned char *oldlittle; + assert(mg); + --littlelen; /* Last char found by table lookup */ s = big + littlelen; little += littlelen; /* last char */ oldlittle = little; if (s < bigend) { + const unsigned char * const table = (const unsigned char *) mg->mg_ptr; I32 tmp; top2: -- 1.8.5.2 (Apple Git-48)
* [perl #121854] use re 'taint' regressionDavid Mitchell2014-05-131-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Commit v5.19.8-533-g63baef5 changed the handling of locale-dependent regexes so that the pattern was considered tainted at compile-time, rather than determining it each time at run-time whenever it executed a locale-dependent node. Unfortunately due to the conflating of two flags, RXf_TAINTED and RXf_TAINTED_SEEN, it had the side effect of permanently marking a pattern as tainted once it had had a single tainted result. E.g. use re qw(taint); use Scalar::Util qw(tainted); for ($^X, "abc") { /(.*)/ or die; print "not " unless tainted("$1"); print "tainted\n"; }; which from 5.19.9 onwards output: tainted tainted but with this commit (and with 5.19.8 and earlier), it now outputs: tainted not tainted The RXf_TAINTED flag indicates that the pattern itself is tainted, e.g. $r = qr/$tainted_value/ while the RXf_TAINTED_SEEN flag means that the results of the last match are tainted, e.g. use re 'tainted'; $tainted =~ /(.*)/; # $1 is tainted Pre 63baef5, the code used to look like: at run-time: turn off RXf_TAINTED_SEEN; while (nodes to execute) { switch(node) { case BOUNDL: /* and other locale-specific ops */ turn on RXf_TAINTED_SEEN; ...; } } if (tainted || RXf_TAINTED) turn on RXf_TAINTED_SEEN; 63baef5 changed it to: at compile-time: if (pattern has locale ops) turn on RXf_TAINTED_SEEN; at run-time: while (nodes to execute) { ... } if (tainted || RXf_TAINTED) turn on RXf_TAINTED_SEEN; This commit changes it to: at compile-time; if (pattern has locale ops) turn on RXf_TAINTED; at run-time: turn off RXf_TAINTED_SEEN; while (nodes to execute) { ... } if (tainted || RXf_TAINTED) turn on RXf_TAINTED_SEEN;
* Reduce excessive stat calls in glob on VMS.Craig A. Berry2014-03-211-0/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When PERL_EXTERNAL_GLOB is defined (currently only on VMS, or on other platforms when running miniperl), each item returned from the glob operation is checked against a set of glob metacharacters, and then, if it matches any of these characters, it's checked with lstat() to see if it actually exists. Then it's passed through if it exists but skipped otherwise. Presumably this is because returning the pattern unchanged is how a shell glob indicates "no match." It appears that the lstat() is necessary because glob metacharacters are almost always valid filename characters on Unix, so it's the only way to distinguish a funny-looking but real filename from the no match case (oops -- indeterminate grammar). Since these filenames are rare on Unix, lstat() is seldom called. Enter VMS, where "external glob" is neither external, nor is it actually a glob. It is a native wildcard-matching search built into Perl with vms/vms.c's Perl_vms_start_glob(), which does return the original pattern when there is no match, but that pattern will only contain native wildcard characters, so the check for glob metacharacters is really not the right thing to be doing. Moreover, glob metacharacters such as dollar signs, brackets, and semicolons are extremely common in native VMS paths, so in many common scenarios, the lstat() to see if the file really exists gets triggered for every single file, which is expensive. This commit replaces, on VMS only, the check for glob metacharacters with a check for VMS wildcard characters. A simple glob of a Perl source tree becomes 60% faster on the first iteration and 80% faster on subsequent iterations. Thanks to Hein van den Heuvel, who reported the problem and explained that a search operation should only be looking at directory files, whereas a stat does I/O to the individual file header, resulting in a massive increase in unnecessary I/O. This closes [perl #121440].
* Change core uses of Perl_do_openn() to Perl_do_open6() or Perl_do_open_raw().Nicholas Clark2014-03-191-1/+1
| | | | | | Calls to Perl_do_openn() all have at least 2 unused arguments which clutter the code and hinder easy understanding. Perl_do_open6() and Perl_do_open_raw() each only do one job, so don't have the dead arguments.
* sprinkle LIKELY() on pp_hot.c scope.c and some *.hDavid Mitchell2014-03-121-53/+56
| | | | | | | | I've gone through pp_hot.c and scope.c and added LIKELY() or UNLIKELY() to all conditionals where I understand the code well enough to know that a particular branch is or isn't likely to be taken very often. I also processed some of the .h files which contain commonly used macros.
* make OP_AELEMFAST work with negative indicesDavid Mitchell2014-02-281-1/+5
| | | | | | | | | | Use aelemfast for literal index array access where the index is in the range -128..127, rather than 0..255. You'd expect something like $a[-1] or $a[-2] to be a lot more common than $a[100] say. In fact a quick CPAN grep shows 66 distributions matching /\$\w+\[\d{3,}\]/, but "at least" 1000 matching /\$\w+\[\-\d\]/. And most of the former appear to be table initialisations.
* don't set SvPADTMP() on PADGV'sDavid Mitchell2014-02-271-4/+11
| | | | | | | | | | | | | | | | | | | | | | | Under threaded builds, GVs for OPs are stored in the pad rather than being directly attached to the op. For some reason, all such GV's were getting the SvPADTMP flag set. There seems to be be no good reason for this, and after skipping setting the flag, all tests still pass. The advantage of not setting this flag is that there are quite a few hot places in the code that do if (SvPADTMP(sv) && !IS_PADGV(sv)) { ... I've replaced them all with if (SvPADTMP(sv)) { assert(!IS_PADGV(sv)); ... Since the IS_PADGV() macro expands to something quite heavyweight, this is quite a saving: for example this commit reduces the size of pp_entersub by 111 bytes.