Commit 0f3f00fa88 for perl
commit 0f3f00fa88d27d4c02c99c02ea20d9c58c22a4af
Author: David Mitchell <davem@iabyn.nospamdeletethisbit.com>
Date: Wed Sep 16 11:38:43 2026 +0100
regex: SLC: eliminate realloc(), poscache_size
Two commits ago, the super-linear cache was changed to be disabled when
calling an inner sub-pattern (e.g. via /(??{$sub_qr })/ ). This means
that it is no longer possible for an inner pattern to allocate the SLC,
then when control returns to the outer pattern, for a different-sized
cache to be needed (or vice-versa).
Also, the previous commit eliminated resetting reginfo->poscache_maxiter
to signal that the cache should be re-zeroed and/or resized, so we
should never be in the position of wanting to malloc() a cache but
finding it was already allocated and needing to re-zero it.
So this commit eliminates the size check and realloc(), and replaces
it with a simple assert that the cache hasn't already been allocated.
Since we never need to know the cache's old size now, this commit
also eliminates the reginfo->poscache_size field.
diff --git a/pod/perlreguts.pod b/pod/perlreguts.pod
index 9a48d47eb5..4d9dab6bdd 100644
--- a/pod/perlreguts.pod
+++ b/pod/perlreguts.pod
@@ -1390,21 +1390,19 @@ C<reginfo> struct, which is initialised at the start of a match.
A pointer to the cache is stored in C<< reginfo->info_aux.poscache >>,
which will be freed when matching ends (the aux structure is guaranteed to
-be freed even on abnormal termination), and its size is recorded in
-C<< reginfo->poscache_size >>.
+be freed even on abnormal termination).
If zero, C<< reginfo->poscache_maxiter >> indicates that the SLC countdown
has not yet been triggered (i.e. no candidate C<WHILEM> node has been
-executed yet), or that it has been subsequently disabled again. Otherwise,
-its (positive) value is used for two different purposes: what value to
-start an initial (or reset) countdown from; and the size to C<alloc()> the
-cache, in bits. Currently these values are the same, but in principle they
-needn't be.
+executed yet). Otherwise, its (positive) value is used for two different
+purposes: what value to start an initial (or reset) countdown from; and
+the size to C<alloc()> the cache, in bits. Currently these values are the
+same, but in principle they needn't be.
C<< reginfo->poscache_iter >> only has meaning if C<poscache_maxiter> is
non-zero. In that case, it represents a countdown initialised from
-C<poscache_maxiter>. If it reaches 1, the cache is malloced/realloced if
-necessary, and then zeroed. When it reaches 0, the cache is used.
+C<poscache_maxiter>. If it reaches 1, the cache is malloced if necessary,
+and then zeroed. When it reaches 0, the cache is used.
The C<CACHEsayNO> macro is used at runtime in various places as a
replacement for C<sayNO> to set a fail bit in the cache while popping the
diff --git a/regexec.c b/regexec.c
index b75af679a0..dd802ab250 100644
--- a/regexec.c
+++ b/regexec.c
@@ -9209,17 +9209,9 @@ NULL
/* initialise cache */
const STRLEN size = (reginfo->poscache_maxiter + 7)/8;
regmatch_info_aux *const aux = reginfo->info_aux;
- if (aux->poscache) {
- if (reginfo->poscache_size < size) {
- Renew(aux->poscache, size, char);
- reginfo->poscache_size = size;
- }
- Zero(aux->poscache, size, char);
- }
- else {
- reginfo->poscache_size = size;
- Newxz(aux->poscache, size, char);
- }
+ assert(!aux->poscache);
+ Newxz(aux->poscache, size, char);
+
DEBUG_EXECUTE_r( re_exec_indentf(
"%sWHILEM: Detected a super-linear match, enabling cache%s...\n",
depth, PL_colors[4], PL_colors[5])
diff --git a/regexp.h b/regexp.h
index cfb8dc68e4..ac400e305b 100644
--- a/regexp.h
+++ b/regexp.h
@@ -841,7 +841,6 @@ typedef struct {
regmatch_info_aux_eval *info_aux_eval; /* extra saved state for (?{}) */
STRLEN poscache_maxiter; /* how many whilems todo before S-L cache kicks in */
STRLEN poscache_iter; /* current countdown from _maxiter to zero */
- STRLEN poscache_size; /* size of regmatch_info_aux.poscache */
bool intuit; /* re_intuit_start() is the top-level caller */
bool is_utf8_pat; /* regex is utf8 */
bool is_utf8_target; /* string being matched is utf8 */