summaryrefslogtreecommitdiff
path: root/sv.c
Commit message (Collapse)AuthorAgeFilesLines
* Return the "hv with aux" PVHV bodies to the correct arenaNicholas Clark2021-12-181-18/+22
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Move the assignments to SvFLAGS(sv) after the check for SvOOK(), and use arena_index for the array index to PL_body_roots. Without both fixes, del_body() would always be called with &PL_body_roots[SVt_PVHV], which is wrong if the body was allocated from &PL_body_roots[HVAUX_ARENA_ROOT_IX]. PVHV body handling was changed recently by commit 94ee6ed79dbca73d: Split the XPVHV body into two variants "normal" and "with aux" Default to the smaller body, and switch to the larger body if we need to allocate a C<struct xpvhv_aux> (eg need an iterator). This restores the previous small size optimisation for hashes used as objects. as part of changing where memory for C<struct xpvhv_aux> is allocated. The new implementation uses two sizes of "bodies" for PVHVs - the default body is unchanged, but when a hash needs a C<struct xpvhv_aux>, it now swaps out the default body for a larger body with space for the struct. (Previously it would reallocate the memory used for HvARRAY() to make space for the struct there - an approach which requires more tracking of changed pointers.) That commit was subtly buggy in that on hash deallocation it didn't *return* hash bodies to the correct arena. As-was, it would return both sizes of hash body to the arena for the default (smaller) body. This was due to a combination of two subtle bugs 1) the explicit reset of all SvFLAGS to SVf_BREAK would implicitly clear SVf_OOK. That flag bit set is needed to signal the different body size 2) The code must call del_body() with &PL_body_roots[arena_index], not &PL_body_roots[type] type is SVt_PVHV for both body sizes. arena_index is SVt_PVHV for the smaller (default) bodies, and HVAUX_ARENA_ROOT_IX for the larger bodies. There were no memory errors or leaks (that would have been detectable by tools such as ASAN or valgrind), but the bug meant that larger hash bodies would never get re-used. So for code that was steady-state creating and destroying hashes with iterators (or similar), instead of those bodies being recycled via their correct arena, the interpreter would need to continuously allocate new memory for that arena, whilst accumulating ever more unused "smaller" bodies in the other arena. I didn't spot this bug whilst reviewing commit 8461dd8ad90b2bce: don't overwrite the faked up type details for hv-with-aux CID 340472 which is in the same area of the code, but fixes a related problem. Curiously when reporting CID 340738: Assigning value "SVt_IV" to "arena_index" here, but that stored value is overwritten before it can be used Coverity also didn't spot that the code in question was unconditionally unreachable, and warn about that, or modify its warning to note that. (For the code prior to this commit SvOOK(sv) at that point could only ever be false. This is obscured thanks to macros, but all these macros are unconditionally defined to the same values, so static analysis should be able to infer that they are actually constant, and reason accordingly. To be fair, this is *hard*. But not impossible. Hence I infer that static analysis tools still have room for improvement, and can make "mistakes".) Ironically, defining PURIFY would hide this bug, because that disables the use of arenas, instead allocating all bodies explicitly with malloc() and releasing them with free(), and free() doesn't need to know the size of the memory block, hence it wouldn't matter that the code had that size wrong.
* fix pod error in sv.c. Closes #19249Richard Leach2021-11-301-1/+1
|
* sv.c: use Perl_sv_grow_fresh & Perl_sv_setvpn_freshRichard Leach2021-11-011-4/+8
|
* sv.c: add Perl_sv_grow_fresh & Perl_sv_setvpn_freshRichard Leach2021-11-011-0/+84
|
* don't overwrite the faked up type details for hv-with-auxTony Cook2021-10-191-1/+1
| | | | CID 340472
* Split the XPVHV body into two variants "normal" and "with aux"Nicholas Clark2021-10-111-4/+70
| | | | | | | | Default to the smaller body, and switch to the larger body if we need to allocate a C<struct xpvhv_aux> (eg need an iterator). This restores the previous small size optimisation for hashes used as objects.
* Change S_new_body to static inline, and use it instead of a macroNicholas Clark2021-10-111-19/+22
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Rename the macro new_body_inline() to new_body_from_arena(). The macro existed to provide an inline implementation for hot code paths, with a small function for the others. Now that we have proper inline functions, change the function to be inlined, and use it instead of the macro. There is no change to the code generated for the hot paths. This makes the source simpler. Yes, this will also inline the function in a couple of other places, but these days optimising compilers often do that anyway for small functions. Even if they aren't for this function (as was), the size of the function itself is comparable with the calling overheads, so it's not a massive penalty. Two if blocks now need to be placed inside #ifndef PURIFY/#endif guards because they now use the function S_new_body(), which is not defined with PURIFY. The code is actually unreachable - defining PURIFY causes all values for new_type_details->arena to be forced to 0 - hence the if was never true under PURIFY. Hence it could have been guarded the same way previously, but for (maybe false) improved readability was not. Previously there wasn't a compilation failure because the unreachable code was using a macro, not a static function, and the macro was always defined, even when not used. Really the macro's definition should have been inside #ifndef PURIFY, so fix this oversight - it is now only defined if it is needed. Retain the macro (with a new name), and split the parameters to the macro. This will make the next commit simpler.
* Move variables in Perl_sv_clear() to a tighter scope.Nicholas Clark2021-10-111-5/+3
| | | | | These three variables don't hold their values between iterations of the while loop, so can be declared within it, to make this obvious.
* Rename HE_SVSLOT to HE_ARENA_ROOT_IXNicholas Clark2021-10-111-4/+24
| | | | | | The longer name more accurately reflects what the constant refers to. Correct the comments describing how some arena roots are re-used.
* Inline the xhv_aux struct in the main hash bodyNicholas Clark2021-10-111-2/+1
| | | | | For now, memory for this structure is always allocated, even though it isn't always flagged as being present.
* Add comments describing how PVLVs store REGEXPs by referenceNicholas Clark2021-09-261-4/+23
|
* Avoid leaking a scalar body after REGEXP to PVLV assignmentNicholas Clark2021-09-231-6/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | PVLV scalars are used to implement various obscure features of perl, such as elements in tied hashes and hash lookups used as function parameters. To make these work, PVLVs must be capable of holding all scalar types. First class REGEXPs are larger than PVLVs, hence there is special case code to attach REGEXP bodies to PVLVs, for code that both dereferences a regex object and then assigns that value to a PVLV scalar. This was first implemented in Oct 2012 by commit 8d919b0a35f2b57a: Allow regexp-to-pvlv assignment and improved in July 2017 with commit df6b4bd56551f2d3: It turns out that the implementation would leak a scalar body, for the "normal" use case (of this obscure feature). This wasn't noticed for two reasons 1) bodies are allocated from arenas, and arenas are correctly freed during full destruction. 2) the body is not leaked if the the PVLV scalar is then modified The regression tests added by commit 8d919b0a35f2b57a were also testing the corner case of concatenating to one of these values - ie that sv_force_normal_flags() handled unwinding the special cases correctly. To avoid code duplication, the tests added by that commit caused all PVLV scalars to be passed to sv_force_normal_flags(), so didn't actually test regular destruction of such scalars. The tests added in Aug 2017 by commit 622c613e12cef84c: PVLV-as-REGEXP: avoid PVX double free With v5.27.2-30-gdf6b4bd, I changed the way that PVLVs store a regexp value (by making the xpv_len field point to a regexp struct). There was a bug in this, which caused the PVX buffer to be double freed. Several REGEXP SVs can share a PVX buffer. Only one of them will have a non-zero xpv_len field, and that SV gets to free the buffer. After the commit above, the non-zero xpv_len was triggering an extra free. This was showing up in smokes as failures in re/recompile.t when invoked with PERL_DESTRUCT_LEVEL=2 (which t/TEST does). were actually the first to expose this bug, even though it had been present since 2012. The bug is only visible with a full leak test (eg valgrind --leak-check=full or an ASAN build) with -DPURIFY (to disable arenas), hence why it hasn't been noticed.
* Don't try to Sv[PI]V() on an undef index SV in find_uninit_var()Tony Cook2021-09-221-3/+4
| | | | | | | | | | | | | | | | | | | When trying to evaluate: $x{$y} or $x[$y] where both the index and the hash or array entry was undefined, when trying to report the entry as uninitialised, find_uninit_var() would try to get the string or numeric value of the index, recursively trying to produce a warning. This would end up overflowing the stack, producing a segmentation fault. Fixes #19147.
* Fix a leak when copying a STATIC COW SV to a stringified SVNicholas Clark2021-09-111-0/+3
| | | | | | | | | | | | | | | | | | | | This is minor a a regression introduced by commit 914bb57489325d34: Define a third kind of COW state; STATIC ... sv_setsv_flags() and sv_setsv_cow() will preserve this state There was a small omission in the copy code - it didn't handle the case where the destination SV owned a string buffer already. This is actually relatively rare - triggering it requires a scalar in code path that is assigned both strings and booleans. Minimal test case is: my $got = 1; $got .= ""; $got = ref ""; cut down from &is in t/comp/parser.t
* Define a third kind of COW state; STATICPaul "LeoNerd" Evans2021-09-101-11/+30
| | | | | | | | | | | | | | | | | | | | Previously, when IsCOW flag was set there were two cases: SvLEN()==0: PV is really a shared HEK SvLEN()!=0: PV is a COW structure with 1..256 refcount stored in its extra final byte This change adds a third state: SvLEN()==0 && SvFLAGS() & SVppv_STATIC: PV is a shared static const pointer and must not be modified sv_setsv_flags() and sv_setsv_cow() will preserve this state sv_uncow() will copy it out to a regular string buffer sv_dup() will preserve the static pointer into cloned threads
* Indentation fix in sv_gets() (whitespace only)Hugo van der Sanden2021-09-101-2/+2
| | | | gcc-11.2 correctly complains about this. [-Wmisleading-indentation]
* Use HvTOTALKEYS() in place of HvARRAY() in various boolean testsNicholas Clark2021-09-031-2/+2
| | | | | This is a better choice for an "is it empty?" optimisation, as HvARRAY() can be non-NULL even when there actually are no keys.
* Convert some existing uses of SvRV_set() to use the new sv_setrv* family of ↵Paul "LeoNerd" Evans2021-08-251-3/+2
| | | | functions
* Add _mg() versions of the sv_setrv* familyPaul "LeoNerd" Evans2021-08-251-0/+26
|
* Add sv_setrv_inc()Paul "LeoNerd" Evans2021-08-251-0/+16
|
* Add sv_setrv_noinc()Paul "LeoNerd" Evans2021-08-251-0/+23
|
* Create `defer` syntax and `OP_PUSHDEFER` opcodePaul "LeoNerd" Evans2021-08-251-0/+1
| | | | | | | | | | | | | | | Adds syntax `defer { BLOCK }` to create a deferred block; code that is deferred until the scope exits. This syntax is guarded by use feature 'defer'; Adds a new opcode, `OP_PUSHDEFER`, which is a LOGOP whose `op_other` field gives the start of an optree to be deferred until scope exit. That op pointer will be stored on the save stack and invoked as part of scope unwind. Included is support for `B::Deparse` to deparse the optree back into syntax.
* sv.c: Removed a redundant SvNV_nomg call in sv_vcatpvfn_flags.TAKAI Kousuke2021-08-231-1/+1
| | | | | SvNV_nomg(argsv) is redundant here because its NV is already loaded to the local variable "nv".
* Delete Perl_ptr_table_clear, marked as deprecated since v5.14.0Nicholas Clark2021-08-211-26/+0
|
* sv_vcatpvfn(): Simplify print formatKarl Williamson2021-07-301-2/+1
| | | | | | | The print took a character, cast it to UV and then printed it as an octal UV. But why not just print it as an unsigned octal character? The code that did this was part of a sweeping commit of a bunch of things, so no explanation there.
* sv.c: Save a '&' instr by casting to U8Karl Williamson2021-07-301-1/+1
|
* Simplify some logic in S_find_hash_subscript().Nicholas Clark2021-07-261-10/+5
| | | | | | | | | | | | | | | | | | | | | | | The code is looping to look for the hash key whose value is the SV at the address given in val. Previously the code in the loop would ignore hash entries which were &PL_sv_undef or &PL_sv_placeholder. Given that this check was *after* the equality check for val, but the the only way for the function to return success ("found") was to continue beyond this check. Hence, as-written it meant that the function would always return NULL ("not found") if val had either of these values, but would loop through the entire hash *first* before doing so. Hence move the check before the loop, to generate the same result, but with less work. Also, HeKEY(entry) can never be NULL, so this check was dead code and can be removed. (The C compiler probably already spotted this) Also, the code had special-case handling for HEf_SVKEY. What it used to do was actually identical to what sv_2mortal(newSVhek(...)) does, so just use that for everything. (Hashes themselves should never contain keys with this special flag length - it's only used in MAGIC structures, and for HE structures created while iterating tied hashes.)
* Fix syntax error wwhen NAN_COMPARE_BROKENKarl Williamson2021-07-061-1/+1
| | | | http://nntp.perl.org/group/perl.perl5.porters/26082
* replace all instances of PERL_IMPLICIT_CONTEXT with MULTIPLICITYTomasz Konojacki2021-06-091-3/+3
| | | | | | | | | | | | Since the removal of PERL_OBJECT (acfe0abcedaf592fb4b9cb69ce3468308ae99d91) PERL_IMPLICIT_CONTEXT and MULTIPLICITY have been synonymous and they're being used interchangeably. To simplify the code, this commit replaces all instances of PERL_IMPLICIT_CONTEXT with MULTIPLICITY. PERL_IMPLICIT_CONTEXT will stay defined for compatibility with XS modules.
* Base *.[ch] files: Replace leading tabs with blanksMichael G Schwern2021-05-311-5648/+5648
| | | | | | | This is a rebasing by @khw of part of GH #18792, which I needed to get in now to proceed with other commits. It also strips trailing white space from the affected files.
* Do not cache utf8 offsets for non-canonical lengthsLeon Timmermans2021-05-241-4/+11
| | | | In particular, if the length is beyond the end, it should not be stored as the end.
* perlapi: Rmv repeated wordKarl Williamson2021-05-201-1/+1
|
* Support %#p format (#18709)Dominic Hamon2021-04-101-2/+1
| | | | | | | | | | | * Support %#p form of %..p Fix #18289 * Better testing * Add myself to AUTHORS * Add a comment
* Silence one build-time warningJames E Keenan2021-03-311-1/+1
| | | | | | Observed in clang 9 and 10. Partial solution for https://github.com/Perl/perl5/issues/17015
* quadmath: handle long doubles supplied via va_args in sv_vcatpvfn_flags()Tony Cook2021-03-301-11/+17
| | | | | | | | | | | | | | | | All of perl's printf() style processing meets up in sv_vcatpvfn_flags() which had three problems when dealing with long double parameters. 1) both the long double (L and q) and __float128 flags (Q) were converted to the internal long double flag 2) the internal long double flag was then always treated as a __float128 parameter. 3) the non-Q format string was then passed to my_snprintf(), which throws an exception on non-Q floating point formats, which meant that C/XS code printing doubles or long doubles in a quadmath built would throw an exception.
* sv.c: White space onlyKarl Williamson2021-02-111-1/+1
|
* Avoid some compiler warnings with -DNO_LOCALEKarl Williamson2021-02-041-0/+2
|
* Remove trailing semicolon from ALIGNED_TYPE definitionCraig A. Berry2021-01-031-1/+1
| | | | | | | | | | Every use of it already has its own semicolon, and duplicating it can lead to warnings like this: ALIGNED_TYPE(XPVGV); ...................^ %CC-I-EXTRASEMI, Extraneous semicolon. at line number 894 in file D0:[craig.blead]sv.c;1
* sv.c: Delete irrelevant preprocessor conditionalsTAKAI Kousuke2020-12-291-2/+2
| | | | | 66435b24ea changed Perl_isnan to Perl_isinfnan, but I forgot to update corresponding preprocessor conditionals.
* sv.c: Suppress imprecision warnings on Inf.TAKAI Kousuke2020-12-291-4/+8
| | | | | This commit will partially revert the effect of the commit c33ee94ba2086d48e3750cfdeb51402b61bb1ac7. [GH #18388]
* sv.c: more imprecision warnings on increment/decrementTAKAI Kousuke2020-12-291-6/+16
| | | | | | | | | Previously, imprecision warnings on increment (Lost precision when incrementing %f by 1) were only issued on positive finite values, and, on decrement, only issued on negative finite values. This commit extends this warnings on both sign and infinite values. This fixes GH #18333.
* perlapi: Turn reference to SvSHARED_HASH into a linkKarl Williamson2020-12-271-1/+1
|
* sv.c - suppress bogus -Wformat-overflow warnings (Issue 18170)sisyphus2020-12-271-3/+8
|
* perlapi: Document newSVsv_flagsKarl Williamson2020-12-201-3/+5
|
* embed.fnc: Mark sv_2uv, etc. as Core onlyKarl Williamson2020-12-201-2/+2
| | | | | There are documented macros that one is supposed to use instead for this functionality.
* Fix broken PERL_MEM_LOG under threadsKarl Williamson2020-12-191-0/+4
| | | | | | | | | | | | | This fixes GH #18341 There are problems with getenv() on threaded perls wchich can lead to incorrect results when compiled with PERL_MEM_LOG. Commit 0b83dfe6dd9b0bda197566adec923f16b9a693cd fixed this for some platforms, but as Tony Cook, pointed out there may be standards-compliant platforms that that didn't fix. The detailed comments outline the issues and (complicated) full solution.
* perlapi: 'ie' should be 'i.e.', and italicizedKarl Williamson2020-12-141-1/+1
|
* Implement SAVEt_STRLEN_SMALLPaul "LeoNerd" Evans2020-12-091-0/+1
| | | | | | | Most uses of SAVEt_STRLEN actually store small values; often zero. Rather than using an entire U64-sized element for these values, it saves space to use the same "SMALL" mechanism as other numerical values, like SAVEt_INT_SMALL.
* Evaluate arg once in all forms of SvTRUEKarl Williamson2020-12-061-1/+1
| | | | 5.32 did this for one form; now all do.
* Slience compiler warnings for NV, [IU]V compareKarl Williamson2020-11-221-2/+2
| | | | | | | | | | | | | | These were occurring on FreeBSD smokes. warning: implicit conversion from 'IV' (aka 'long') to 'double' changes value from 9223372036854775807 to 9223372036854775808 [-Wimplicit-int-float-conversion] 9223372036854775807 is IV_MAX. What needed to be done here was to use the NV containing IV_MAX+1, a value that already exists in perl.h In other instances, simply casting to an NV before doing the comparison with the NV was what was needed. This fixes #18328