Skip to content

Commit 573e4fd

Browse files
committed
S_invlist_trim - don't SvPV_renew where no change is likely
Currently, `S_invlist_trim` always calls `SvPV_renew(invlist, <size>)`, which is a macro wrapping a call to `safesysrealloc()`. However, `SvLEN(invlist)` is often already exactly the desired size, or it is larger by less than the size of a pointer. With this commit, the new `expected_size` macro is used to reduce the number of cases in which S_invlist_trim will try to shrink a buffer but no shrinkage is likely to occur. (For example, if the desired size is less than the minimum actual allocation size.)
1 parent 4a38ddc commit 573e4fd

File tree

1 file changed

+21
-3
lines changed

1 file changed

+21
-3
lines changed

regcomp_invlist.c

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -246,14 +246,32 @@ S_invlist_trim(SV* invlist)
246246
/* Free the not currently-being-used space in an inversion list */
247247

248248
/* But don't free up the space needed for the 0 UV that is always at the
249-
* beginning of the list, nor the trailing NUL */
250-
const UV min_size = TO_INTERNAL_SIZE(1) + 1;
249+
* beginning of the list, nor the trailing NUL. The smallest possible
250+
* allocation size may or may not be larger than this, depending upon
251+
* the malloc implementation in use. */
252+
253+
const STRLEN min_size = MAX(PERL_STRLEN_NEW_MIN, TO_INTERNAL_SIZE(1) + 1);
251254

252255
PERL_ARGS_ASSERT_INVLIST_TRIM;
253256

254257
assert(is_invlist(invlist));
255258

256-
SvPV_renew(invlist, MAX(min_size, SvCUR(invlist) + 1));
259+
/* Notes:
260+
* SvCUR(invlist) can be 0, often is min_size or larger
261+
*
262+
* It's very common for SvLEN(invlist) to be equal to:
263+
* (TO_INTERNAL_SIZE(1) + 1)
264+
* ...or the minimum allocation size if larger
265+
* SvCUR(invlist) + 2
266+
* SvCUR(invlist) + "a few"
267+
*/
268+
269+
const STRLEN realistic_size = expected_size(
270+
MAX( min_size, SvCUR(invlist) + 1) );
271+
272+
if ( SvLEN(invlist) > realistic_size ) {
273+
SvPV_renew(invlist, realistic_size);
274+
}
257275
}
258276

259277
PERL_STATIC_INLINE void

0 commit comments

Comments
 (0)