Commit 3661cbd6a8 for perl
commit 3661cbd6a80ea165e5f6be73f2e6802b8e9b10ae
Author: Richard Leach <rich+perl@hyphen-dash-hyphen.info>
Date: Sat Oct 24 22:13:43 2026 +0000
S_cleanup_regmatch_info_aux: avoid reloads, unnecesary Safefree calls
When _some_ super-linear caches have been allocated, others may not.
This commit checks each one before calling `Safefree` on it.
For example, gcov counts from a run of the test harness:
-:11820: /* free any allocated super-linear caches */
125305444:11821: if (aux->slc) {
2095084:11822: struct slc_cache_item * const slc = aux->slc;
2095084:11823: const U8 slc_count = rexi->slc_whilem_seen;
-:11824: U8 i;
13855727:11825: for (i = 0; i < slc_count; i++) {
11760643:11826: if (slc[i].slc_bitmap) {
86129:11827: Safefree(slc[i].slc_bitmap);
86129:11828: slc[i].slc_bitmap = NULL;
-:11829: }
-:11830: }
-:11831: /* free the cache array too if it was used during recursion */
2095084:11832: if (rexi->depth)
#####:11833: Safefree(slc);
-:11834: }
`aux->slc` and `rexi->slc_whilem_seen` have been cached as otherwise
compilers might well reload them on every loop iteration.
Freeing the cache array has been pulled into the `if` branch, as that
already tells us if there is an allocation to free.
diff --git a/regexec.c b/regexec.c
index 3196e05cb5..d904893332 100644
--- a/regexec.c
+++ b/regexec.c
@@ -11819,15 +11819,19 @@ S_cleanup_regmatch_info_aux(pTHX_ void *arg)
/* free any allocated super-linear caches */
if (aux->slc) {
+ struct slc_cache_item * const slc = aux->slc;
+ const U8 slc_count = rexi->slc_whilem_seen;
U8 i;
- for (i = 0; i < rexi->slc_whilem_seen; i++) {
- Safefree(aux->slc[i].slc_bitmap);
- aux->slc[i].slc_bitmap = NULL;
+ for (i = 0; i < slc_count; i++) {
+ if (slc[i].slc_bitmap) {
+ Safefree(slc[i].slc_bitmap);
+ slc[i].slc_bitmap = NULL;
+ }
}
+ /* free the cache array too if it was used during recursion */
+ if (rexi->depth)
+ Safefree(slc);
}
- /* free the cache array too if it was used during recursion */
- if (rexi->depth)
- Safefree(aux->slc);
if (eval_state) {