Commit edea3e96c6 for perl
commit edea3e96c6e88108c44e5a9ac2b24adf110d7928
Author: Richard Leach <rich+perl@hyphen-dash-hyphen.info>
Date: Thu Sep 10 13:20:21 2026 +0000
Perl_sv_clear: no bodies are allocated outside of PURIFY builds
This commit also duplicates the "free_rv" code for SVt_IV to directly
use rather than jumping to the shared code to hopefully help codegen.
(With gcc, at least, this commit led to better code layout for
bodiless SVs, regardless of content. Overall this commit caused a
slight reduction in the number of generated instructions, so
the "free_rv" duplication wasn't at the cost of code bloat.)
diff --git a/sv.c b/sv.c
index 728ead056b..d693c9fb78 100644
--- a/sv.c
+++ b/sv.c
@@ -7747,8 +7747,16 @@ Perl_sv_clear(pTHX_ SV *const orig_sv)
* efficient than stepping through the general logic.
*/
- if (SvROK(sv))
- goto free_rv;
+ if (SvROK(sv)) {
+ /* This duplicates the same code used for RV-in-PV, but
+ * duplication will help (some) compilers to produce
+ * better code layout. */
+ SV * const target = SvRV(sv);
+ if (SvWEAKREF(sv))
+ sv_del_backref(target, sv);
+ else
+ next_sv = target;
+ }
SvFLAGS(sv) &= SVf_BREAK;
SvFLAGS(sv) |= SVTYPEMASK;
goto free_head;
@@ -7956,7 +7964,6 @@ Perl_sv_clear(pTHX_ SV *const orig_sv)
/* Don't even bother with turning off the OOK flag. */
}
if (SvROK(sv)) {
- free_rv:
{
SV * const target = SvRV(sv);
if (SvWEAKREF(sv))
@@ -8028,13 +8035,13 @@ Perl_sv_clear(pTHX_ SV *const orig_sv)
SvFLAGS(sv) &= SVf_BREAK;
SvFLAGS(sv) |= SVTYPEMASK;
- if (sv_type_details->arena) {
- del_body(((char *)SvANY(sv) + sv_type_details->offset),
- &PL_body_roots[arena_index]);
- }
- else if (sv_type_details->body_size) {
- safefree(SvANY(sv));
- }
+#ifndef PURIFY
+ assert(sv_type_details->arena);
+ del_body(((char *)SvANY(sv) + sv_type_details->offset),
+ &PL_body_roots[arena_index]);
+#else
+ safefree(SvANY(sv));
+#endif
}
free_head: