289 Commits

Author SHA1 Message Date
bbrtj
b6e54476dc Fix Perl_av_store off by one error in key comparison 2025-12-22 06:35:17 -07:00
bbrtj
55631dd1f8 Refactor Perl_av_fetch: remove goto, reduce the number of branches 2025-12-14 10:39:03 +00:00
Richard Leach
153633ed5f Perl_av_make - use newSVsv_flags rather than newSV + sv_setsv_flags
Besides using the just-introduced faster path for SV copying, this
allows the check for SV_GMAGIC to be pushed into the called function
without having to worry about SV leaks.

Two additional micro-optimizations are also in this commit:
* A pointer to xav_fill is cached for use in the loop. This can
  be used directly to update AvFILLp(av), rather than having to
  get there from av's SV* each time.

* The value of the loop iterator, i, is directly written into
  xav_fill, rather than getting the value in that slot,
  incrementing it (to get the same value as i), and writing it back.
2025-08-23 17:44:29 +01:00
Karl Williamson
2d8768c62d Remove redundant assert() statements
These assertions have been redundant since
2463f19365f941f68e9d5eed2f787341df8ccdef, July 2024.
2025-08-05 19:34:36 -06:00
Dagfinn Ilmari Mannsåker
30aeaad51e Stop calling Perl_*warn*() manually in core
Except reg*.[ch], which are also compiled "outside" core for re.pm
2025-03-19 06:37:08 +01:00
Leon Timmermans
453b1c0d2b Use croak_no_modify directly
There never was any good reason to call it by its long name.
2025-03-18 04:16:51 +01:00
Leon Timmermans
06c3a62f12 Dont call Perl_croak manually in core
Just call croak instead, we've been able to do that for vararg functions
since d933027ef0a56c99aee8cc3c88ff4f9981ac9fc2
2025-03-18 04:16:51 +01:00
Karl Williamson
c3579230a9 perlapi: Fix av_push pod.
Commit 247d8ed1108268e9e56dfe822f911e9c4f53d5fb wrongly used 'apidoc'
when it should have used 'apidoc_item'
2024-06-22 14:51:53 -06:00
Karl Williamson
247d8ed110 perlapi: Combine av_push(), av_push_simple() entries 2024-06-22 14:05:17 -06:00
Karl Williamson
5f29d4af0d perlapi: Combine all av_len synonyms into one entry 2024-06-16 18:46:36 -06:00
David Mitchell
4f91780c40 make shift(@a) leave old pointer
Generally shifting is done by adjusting the start position of the
array, so that AvALLOC() and AvARRAY() no longer align. Previously if
the array was AvREAL(), perl NULL-ed out the old pointer at the same
time, i.e. doing the equivalent of AvARRAY(av)[-1] = NULL.

This commit changes it so that on PERL_RC_STACK builds, perl instead
keeps the old pointer there on AvREAL() arrays too, even if it now
points to a freed SV; and instead makes av_clear() and av_unshift()
responsible for NULL-ing out the slot only when actually reclaiming any
unused slots between AvALLOC() and AvARRAY().

The reason for this is because of the mechanism whereby @DB::args is
sometimes populated by caller(), as used by Carp.pm to display function
arguments in stack traces etc. For the common idiom of

    sub f {
        my $self = shift;
        ....;
    }

then previously, since @_ wasn't AvREAL(), the old pointer in @_ to
argument 0 was kept around and thus the hidden pointer value was still
available for caller() to add to @DB::args.

But since the next commit will change @_ to be AvREAL(), this will no
longer work.  Thus to keep the ability to debug stack traces etc (via
the awful @DB::args hack), we make shift keep the pointer even for the
AvREAL() case.
2023-08-16 17:16:59 +01:00
David Mitchell
765f7ac25b Add av_remove_offset() core-only function
This function abstracts away removing any AvARRAY(av) - AvALLOC(av)
offset from an array (previously added by av_shift()).

Also use Zero() rather than a loop to NULL out any elements in the
offset area.
2023-08-16 17:16:58 +01:00
Richard Leach
9e298ab597 Perl_av_extend_guts: Zero() trailing elements after unshift & resize
Since 399fef93c9,
trailing elements in an array that has been unshifted and resized
might not be properly Zero() initialized. This is because of faulty
arithmetic when calculating `to_null`, the number of elements to
initialize, when the array was only partially shifted.

This commit corrects the arithmetic, adds comments arount the
calculation of `to_null`, and adds a test based upon the case
provided in GH #21235.

The test added segfaults more reliably for me - almost every time -
than the originally supplied case. However, since it relies upon
uninitialized memory, it's probably still not deterministic and
somewhat dependent upon the choice of memory allocator.

Closes #21235
2023-07-20 22:57:28 +01:00
Yves Orton
829184bb49 av.c - av_store() do the refcount dance around magic av's
The api for av_store() says it is the callers responsibility to call
SvREFCNT_inc() on the stored item after the store is successful.

However inside of av_store() we store the item in the C level array before we
trigger magic. To a certain extent this is required because mg_set(av) needs
to be able to see the newly stored item.

But if the mg_set() or other magic associated with the av_store() operation
fails, we would end up with a double free situation, as we will long jump up
the stack above and out of the call to av_store(), freeing the mortal as we go
(via Perl_croak()), but leaving the reference to the now freed pointer in the
array. When the next SV is allocated the reference will be reused, and then we
are in a double free scenario.

I see comments in pp_aassign talking about defusing the temps stack for the
parameters it is passing in, and things like this, which at first looked
related. But that commentary doesn't seem that relevant to me, as this bug
could happen any time a scalar owned by one data structure was copied into an
array with set magic which could die. Eg, I can easily imagine XS code that
expected code like this (assume it handles magic properly) to work:

    SV **svp = av_fetch(av1,0,1);
    if (av_store(av2,0,*svp))
        SvREFCNT_inc(*svp);

but if av2 has set magic and it dies the end result will be that both av1 and
av2 contain a visible reference to *svp, but its refcount will be 1. So I think
this is a bug regardless of what pp_aassign does.

This fixes https://github.com/Perl/perl5/issues/20675
2023-01-09 11:19:39 +01:00
James E Keenan
0c6362adf0 Correct typos as per GH 20435
In GH 20435 many typos in our C code were corrected.  However, this pull
request was not applied to blead and developed merge conflicts.  I
extracted diffs for the individual modified files and applied them with
'git apply', excepting four files where patch conflicts were reported.
Those files were:

        handy.h
        locale.c
        regcomp.c
        toke.c

We can handle these in a subsequent commit. Also, had to run these two
programs to keep 'make test_porting' happy:

        $ ./perl -Ilib regen/uconfig_h.pl
        $ ./perl -Ilib regen/regcomp.pl regnodes.h
2022-12-29 09:39:58 -05:00
Richard Leach
dbf3614df9 Extract minimum PV buffer/AV element size to common definitions
In a nutshell, for a long time the minimum PV length (hardcoded
in Perl_sv_grow) has been 10 bytes and the minimum AV array size
(hardcoded in av_extend_guts) has been 4 elements.

These numbers have been used elsewhere for consistency (e.g.
Perl_sv_grow_fresh) in the past couple of development cycles.
Having a standard definition, rather than hardcoding in multiple
places, is more maintainable. This commit therefore introduces
into perl.h:

    PERL_ARRAY_NEW_MIN_KEY
    PERL_STRLEN_NEW_MIN

(Note: Subsequent commit(s) will actually change the values.)
2022-11-21 12:40:10 +01:00
Paul "LeoNerd" Evans
1805204a90 Whitespace fix in av.c / Perl_newAVhv 2022-07-20 14:09:05 +01:00
Richard Leach
f98a2322bc newAVhv - av_push_simple for faster ret array assignments 2022-07-20 14:08:25 +01:00
Richard Leach
80c024ac46 newAVav - av_push_simple for faster ret array assignment 2022-07-20 14:08:25 +01:00
Richard Leach
3b6b0454f7 newAVav/newAVhv - use faster newAV_alloc_x(z) macros 2022-07-20 14:08:25 +01:00
Paul "LeoNerd" Evans
5f6512c99e Add newAVav() and newAVhv() 2022-07-13 23:12:23 +01:00
Richard Leach
eae3cc9643 Move av_new_alloc from av.c to inline.h
There was less benefit in doing this prior to newSV_type becoming an inline
function. Now that it is, inlining av_new_alloc can help compilers eliminate
redundant setting of AvMAX/AvFILLp and unnecessary branches of any following
inlined calls to av_store_simple.
2022-06-08 09:41:44 -06:00
Karl Williamson
e815fc9e52 perlapi: Clean up some AV documentation
The consolidation of newAV with newAV_alloc_xz? included nonsensical
juxtapositions.  This cleans that up, adds a bit of markup, moves the
function implementing the newAV_alloc ones to internal, as there are no
CPAN uses, and we prefer the macro interface.
2022-05-20 14:32:29 -06:00
Richard Leach
7ea8b04b5a Perl_newSV_type_mortal - new inline function introduced and used
There's no efficient way to create a mortal SV of any type other than
SVt_NULL (via sv_newmortal). The options are either to do:

* SV* sv = sv_newmortal; sv_upgrade(sv, SVt_SOMETYPE);
  but sv_upgrade is needlessly inefficient on new SVs.

* SV* sv = sv_2mortal(newSV_type(SVt_SOMETYPE)
  but this will perform runtime checks to see if (sv) and if (SvIMMORTAL(sv),
  and for a new SV we know that those answers will always be yes and no.

This commit adds a new inline function which is basically a mortalizing
wrapper around the now-inlined newSV_type.
2022-03-07 01:08:53 +01:00
Richard Leach
8fcb24256a Inlined newSV_type(SVt_NULL) leaner than non-inlined newSV(0)
When a function outside of sv.c creates a SV via newSV(0):
 * There is a call to Perl_newSV
 * A SV head is uprooted and its flags set
 * A runtime check is made to effectively see if 0 > 0
 * The new SV* is returned

Replacing newSV(0) with newSV_type(SVt_NULL) should be more efficient,
because (assuming there are SV heads to uproot), the only step is:
 * A SV head is uprooted and its flags set
2022-03-07 01:08:53 +01:00
Karl Williamson
832a378e4a Revert "av_create_and_push/unshift_one: faster create via newAV_alloc_xz"
This reverts commit 71ca71bc8b733c80f8f8099bb4673ee629da1353.

It does not compile with C++:

g++ -c -DPERL_CORE -D_REENTRANT -D_GNU_SOURCE -Wno-deprecated -fwrapv -DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2 -ansi -O0 -ggdb3 -Wall -Werror=pointer-arith -Werror=vla -Wextra -Wwrite-strings av.c
av.c: In function ‘SV** Perl_av_create_and_unshift_one(PerlInterpreter*, AV**, SV*)’:
av.c:735:16: error: cannot convert ‘SV* const’ {aka ‘sv* const’} to ‘SV**’ {aka ‘sv**’} in return
  735 |         return val;
      |                ^~~
2021-07-31 17:38:34 -06:00
Richard Leach
71ca71bc8b av_create_and_push/unshift_one: faster create via newAV_alloc_xz 2021-07-31 15:33:28 -07:00
Richard Leach
158b05f881 av_new_alloc: revise description of size parameter 2021-07-06 19:07:13 +01:00
Richard Leach
0b1c19ab1c Add Perl_av_new_alloc() function and newAV_alloc_x/z() macros 2021-05-26 13:37:12 +01:00
Hugo van der Sanden
60eec70fe6 Add reference to av_extend_guts zeroing discussion
.. via withdrawn PR 18690.
2021-04-06 02:39:04 +01:00
Richard Leach
ce9f3c9c00 av_extend_guts: set correct ary_offset when unshifting an array (GH#18667) 2021-04-05 14:09:50 +01:00
Michael G. Schwern
1604cfb027 style: Detabify indentation of the C code maintained by the core.
This just detabifies to get rid of the mixed tab/space indentation.

Applying consistent indentation and dealing with other tabs are another issue.

Done with `expand -i`.

* vutil.* left alone, it's part of version.
* Left regen managed files alone for now.
2021-01-17 09:18:15 -07:00
Tom Hukins
bb8005f7c9 Fix documentation grammar
Replace "Frees the all the" with "Frees all the".  The original wording
was introduced in c2217cd33590ef654 and a4395ebabc8655115.
2020-11-20 17:27:45 +00:00
Karl Williamson
8922262882 autodoc.pl: Specify scn for single-purpose files
Many of the files in perl are for one thing only, and hence their
embedded documentation will be for that one thing.  By creating a hash
here of them, those files don't have to worry about what section that
documentation goes under, and so it can be completely changed without
affecting them.
2020-11-06 07:24:38 -07:00
Richard Leach
f73391e47e av_make: remove unnecessary AvFILLp assignment
av_make sets `AvFILLp(av)= -1;`, but will already have been set by `newAV()`,
via `newSV_type`'s call to `sv_upgrade`.

This PR also includes the minor cosmetic change of swapping in `newAV()` 
in place of its expansion, seemingly the only occurrence of that in core.
2020-11-04 00:27:29 +00:00
Richard Leach
399fef93c9 Perl_av_extend_guts: use Zero() rather than a while loop to set NULLs 2020-10-04 09:27:20 -06:00
Richard Leach
440c1856da Perl_av_extend_guts: tabs converted to spaces; unnecessary nesting removed 2020-10-04 09:27:20 -06:00
Karl Williamson
bd5fa06648 Remove Perl_av_top_index
I created this in 87306e0674dfe3af29804b4641347cd5ac9b0521, thinking it
was needed to preserve backward compatibility if someone were using this
instead of the macro.  But it turned out that there never was such a
function, it was inlined, and the name was S_av_top_index, so there is
no reason to create a new function that no one has ever been able to
call.  So just remove it, and let all accesses go through the macro
2020-09-29 01:08:31 -06:00
Karl Williamson
a56541ebc9 Document AvFILLp; clarify related entries 2020-09-13 21:13:58 -06:00
Karl Williamson
51b56f5c7c Reorganize perlapi
This uses a new organization of sections that I came up with.  I asked
for comments on p5p, but there were none.
2020-09-04 16:13:25 -06:00
Karl Williamson
87306e0674 Add av_count()
This returns the number of elements in an array in a clearly named
function.

av_top_index(), av_tindex() are clearly named, but are less than ideal,
and came about because no one back then thought of this one, until now
Paul Evans did.
2020-08-19 16:12:19 -06:00
Yves Orton
2b301921ff pp_sort.c: fix fencepost error in call to av_extend()
In [rt.cpan.org #39196] issue #17496 there is a report
that Tie::File produced spurious blank lines in the file
after

    @tied= sort @tied;

it turns out that this is because Tie::File treats
EXTEND similarly to STORESIZE (which is arguably not
entirely correct, but also not that weird) coupled
with an off by one error in the calls to av_extend()
in pp_sort.

This patch fixes the fencepost error, adds some comments
to av_extend() to make it clear what it is doing, and
adds a test that EXTEND is called by this code with
correct argument.
2020-01-31 15:37:45 +01:00
Karl Williamson
811f8a246e Revert "Add some defensive coding to av_store()"
This reverts commit bc62bf8519f9005df2fb29dbd3d330202b258b6b.

As Dave Mitchell said in <Perl/perl5/issues/17265/570253376@github.com>

"The docs for av_store() say that the caller is responsible for first
incrementing the ref count of the new SV before passing it to
av_store(). In the normal case of the two elements being different,
av_store() will decrement the old SV before storing the new one, and
everything is good. When the two elements are the same SV, av_store()
*still* needs to decrement the ref count, to undo the increment the
caller just did."

This should resolve GH #17265
2020-01-02 10:16:24 -07:00
Karl Williamson
bc62bf8519 Add some defensive coding to av_store()
Don't decrement the reference count of the element about to be stored
into.

Likely, this is an error in the caller, but doing this action blindly is
like shooting yourself in the foot.  The branch prediction also added
ensures this shouldn't slow things down.

See http://nntp.perl.org/group/perl.perl5.porters/254974
2019-06-27 09:36:35 -06:00
Daniel Dragan
814eedc877 rmv/de-dup static const char array "strings"
MSVC due to a bug doesn't merge identicals between .o'es or discard these
vars and their contents.

MEM_WRAP_CHECK_2 has never been used outside of core according to cpan grep
MEM_WRAP_CHECK_2 was removed on the "have PERL_MALLOC_WRAP" branch in
commit fabdb6c0879 "pre-likely cleanup" without explination, probably bc
it was unused. But MEM_WRAP_CHECK_2 was still left on the "no
PERL_MALLOC_WRAP" branch, so remove it from the "no" side for tidyness
since it was a mistake to leave it there if it was removed from the "yes"
side of the #ifdef.

Add MEM_WRAP_CHECK_s API, letter "s" means argument is string or static.
This lets us get rid of the "%s" argument passed to Perl_croak_nocontext at
a couple call sites since we fully control the next and only argument and
its guaranteed to be a string literal. This allows merging of 2
"Out of memory during array extend" c strings by linker now.

Also change the 2 op.h messages into macros which become string literals
at their call sites instead of "read char * from a global char **" which
was going on before.

VC 2003 32b perl527.dll section size before
  .text name
   DE503 virtual size
  .rdata name
   4B621 virtual size

after
  .text name
   DE503 virtual size
  .rdata name
   4B5D1 virtual size
2018-03-07 14:14:15 +11:00
Father Chrysostomos
1f1dcfb516 ‘Nonelems’ for pushing sparse array on the stack
To avoid having to create deferred elements every time a sparse array
is pushed on to the stack, store a magic scalar in the array itself,
which av_exists and refto recognise as not existing.

This means there is only a one-time cost for putting such arrays on
the stack.

It also means that deferred elements that live long enough don’t
start pointing to the wrong array entry if the array gets shifted (or
unshifted/spliced) in the mean time.  Instead, the scalar is already
in the array, so it cannot lose its place.  This fix only applies
when the array as a whole is pushed on to the stack, but it could be
extended in future commits to apply to other places where we currently
use deferred elements.
2018-02-18 16:25:42 -08:00
Zefram
4803e7f742 store AV iterator as mg_len in more cases
The iterator of an AV is an IV value attached to the AV via magic.
It may be stored in the space used by mg_len, or it may be stored in
separately allocated space referenced by mg_ptr.  The former is more
efficient, so should be preferred.  The original code for AV iterators
would use mg_len if IV was (the same size as) I32, because mg_len was of
type I32.  Since then mg_len has been increased to type SSize_t, but the
conditional about how AV iterators are stored wasn't updated to match.
As a result, on the now very common 64-bit builds we were missing out on
the opportunity to use the more efficient form of storage.  This commit
updates the condition about how AV iterators are stored, to take account
of the new type.

In principle AV iterators ought to be of type SSize_t, and thus *always*
storable as mg_len.  But Perl_av_iter_p() is in the public API with
its IV* return type, so there is a compatibility issue to address in
changing that.
2017-11-11 04:23:37 +00:00
Yves Orton
84610c522b av.c: silence compiler warning
av.c: In function ‘Perl_av_undef’:
av.c:577:35: warning: ‘orig_ix’ may be used uninitialized in this function [-Wmaybe-uninitialized]
             PL_tmps_stack[orig_ix] = &PL_sv_undef;

The warning is bogus, as we only use the orig_ix if real is true,
and if real is true we will have set orig_ix. But it doesnt cost
much to initialize it always and shut up the compiler.
2017-06-01 17:17:34 +02:00
Karl Williamson
147e38468b Change white space to avoid C++ deprecation warning
C++11 requires space between the end of a string literal and a macro, so
that a feature can unambiguously be added to the language.  Starting in
g++ 6.2, the compiler emits a warning when there isn't a space
(presumably so that future versions can support C++11).  Unfortunately
there are many such instances in the perl core.  This commit fixes
those, including those in ext/, but individual commits will be used for
the other modules, those in dist/ and cpan/.

This commit also inserts space at the end of a macro before a string
literal, even though that is not deprecated, and removes useless ""
literals following a macro (instead of inserting a blank).  The result
is easier to read, making the macro stand out, and be clearer as to the
intention.

Code and modules included with the Perl core need to be compilable using
C++.  This is so that perl can be embedded in C++ programs. (Actually,
only the hdr files need to be so compilable, but it would be hard to
test that just the hdrs are compilable.)  So we need to accommodate
changes to the C++ language.
2016-11-18 09:41:07 -07:00
David Mitchell
be98855787 speed up AV and HV clearing/undeffing
av_clear(), av_undef(), hv_clear(), hv_undef() and av_make()
all have similar guards along the lines of:

    ENTER;
    SAVEFREESV(SvREFCNT_inc_simple_NN(av));
    ... do stuff ...;
    LEAVE;

to stop the AV or HV leaking or being prematurely freed while processing
its elements (e.g. FETCH() or DESTROY() might do something to it).

Introducing an extra scope and calling leave_scope() is expensive.
Instead, use a trick I introduced in my recent pp_assign() recoding:
add the AV/HV to the temps stack, then at the end of the function,
just PL_tmpx_ix-- if nothing else has been pushed on the tmps stack in the
meantime, or replace the tmps stack slot with &PL_sv_undef otherwise
(which doesn't care how many times its ref count gets decremented).

This is efficient, and doesn't artificially extend the life of the SV
like sv_2mortal() would.

This commit makes this code around 5% faster:

    my @a;
    for my $i (1..3_000_000) {
        @a = (1,2,3);
        @a = ();
    }

and this code around 3% faster:

    my %h;
    for my $i (1..3_000_000) {
        %h = qw(a 1 b 2);
        %h = ();
    }
2016-10-26 16:21:52 +01:00