Commit 322735f711 for perl
commit 322735f711b4c101644ff5dff294a2ab81937fe2
Author: Richard Leach <rich+perl@hyphen-dash-hyphen.info>
Date: Fri Sep 11 09:12:16 2026 +0000
Add PL_ prefix to bodies_by_type[] and have one copy in globals.c
`Perl_newSV_type` originally needed the `bodies_by_type[]` structure to
be located inside _sv_inline.h_ for type values to be propagated at
compile time. Unfortunately, this led to some binary bloating.
`Perl_newSV_type` doesn't have this dependency any more, though it does
still need the structure to be accessible under `DEBUGGING` or `PURIFY`
builds. This commit declares it `EXTCONST` to make it available in
all compilation units but only be populated in _globals.c_.
The `PL_` has been added to keep namespace pollution to the usual
prefixes.
diff --git a/globvar.sym b/globvar.sym
index b9cea72af6..617104a1b1 100644
--- a/globvar.sym
+++ b/globvar.sym
@@ -8,6 +8,7 @@ PL_Yes
PL_bincompat_options
PL_bitcount
PL_block_type
+PL_bodies_by_type
PL_c9_utf8_dfa_tab
PL_charclass
PL_check
diff --git a/sv.c b/sv.c
index 550d3b9efd..d1a873e4c1 100644
--- a/sv.c
+++ b/sv.c
@@ -835,7 +835,7 @@ supporting the multiple body-types.
If PURIFY is defined, or PERL_ARENA_SIZE=0, arenas are not used, and
the (new|del)_X*V macros are mapped directly to malloc/free.
-For each sv-type, struct body_details bodies_by_type[] carries
+For each sv-type, struct body_details PL_bodies_by_type[] carries
parameters which control these aspects of SV handling:
Arena_size determines whether arenas are used for this body type, and if
@@ -855,7 +855,7 @@ For the sv-types that have no bodies, arenas are not used, so those
PL_body_roots[sv_type] are unused, and can be overloaded. In
something of a special case, SVt_NULL is borrowed for HE arenas;
PL_body_roots[HE_ARENA_ROOT_IX=SVt_NULL] is filled by S_more_he, but the
-bodies_by_type[SVt_NULL] slot is not used, as the table is not
+PL_bodies_by_type[SVt_NULL] slot is not used, as the table is not
available in hv.c. Similarly SVt_IV is re-used for HVAUX_ARENA_ROOT_IX.
*/
@@ -879,7 +879,7 @@ Perl_more_bodies (pTHX_ const svtype sv_type)
const struct body_details *type_details =
(sv_type > SVt_IV)
- ? bodies_by_type + sv_type
+ ? PL_bodies_by_type + sv_type
: (sv_type == SVt_NULL)
? NULL
: &fake_hv_with_aux
@@ -904,7 +904,7 @@ Perl_more_bodies (pTHX_ const svtype sv_type)
done_sanity_check = TRUE;
while (i--)
- assert (bodies_by_type[i].type == i);
+ assert (PL_bodies_by_type[i].type == i);
}
#endif
@@ -1000,7 +1000,7 @@ Perl_newSV_type_generic(pTHX_ const svtype type)
void* new_body;
const struct body_details *type_details;
- type_details = bodies_by_type + type;
+ type_details = PL_bodies_by_type + type;
switch (type) {
case SVt_NULL:
@@ -1082,13 +1082,13 @@ Perl_newSV_type_generic(pTHX_ const svtype type)
/* For a type known at compile time, it should be possible for the
* compiler to deduce the value of (type_details->arena), resolve
* that branch below, and inline the relevant values from
- * bodies_by_type. Except, at least for gcc, it seems not to do that.
+ * PL_bodies_by_type. Except, at least for gcc, it seems not to do that.
* We help it out here with two deviations from sv_upgrade:
* (1) Minor rearrangement here, so that PVFM - the only type at this
* point not to be allocated from an array appears last, not PV.
* (2) The ASSUME() statement here for everything that isn't PVFM.
* Obviously this all only holds as long as it's a true reflection of
- * the bodies_by_type lookup table. */
+ * the PL_bodies_by_type lookup table. */
#ifndef PURIFY
ASSUME(type_details->arena);
#endif
@@ -1157,7 +1157,7 @@ Perl_sv_upgrade(pTHX_ SV *const sv, svtype new_type)
const svtype old_type = SvTYPE(sv);
const struct body_details *new_type_details;
const struct body_details *old_type_details
- = bodies_by_type + old_type;
+ = PL_bodies_by_type + old_type;
SV *referent = NULL;
if (old_type == new_type)
@@ -1262,7 +1262,7 @@ Perl_sv_upgrade(pTHX_ SV *const sv, svtype new_type)
croak("sv_upgrade from type %d down to type %d",
(int)old_type, (int)new_type);
- new_type_details = bodies_by_type + new_type;
+ new_type_details = PL_bodies_by_type + new_type;
SvFLAGS(sv) &= ~SVTYPEMASK;
SvFLAGS(sv) |= new_type;
@@ -1472,7 +1472,7 @@ Perl_hv_auxalloc(pTHX_ HV *hv)
{
PERL_ARGS_ASSERT_HV_AUXALLOC;
- const struct body_details *old_type_details = bodies_by_type + SVt_PVHV;
+ const struct body_details *old_type_details = PL_bodies_by_type + SVt_PVHV;
void *old_body;
void *new_body;
@@ -7886,13 +7886,13 @@ Perl_sv_clear(pTHX_ SV *const orig_sv)
/* Historically this check on type was needed so that the code to
* free bodies wasn't reached for these types, because the arena
* slots were re-used for HEs and pointer table entries. The
- * metadata table `bodies_by_type` had the information for the sizes
+ * metadata table `PL_bodies_by_type` had the information for the sizes
* for HEs and PTEs, hence the code here had to have a special-case
* check to ensure that the "regular" body freeing code wasn't
- * reached, and get confused by the "lies" in `bodies_by_type`.
+ * reached, and get confused by the "lies" in `PL_bodies_by_type`.
*
* However, it hasn't actually been needed for that reason since
- * Aug 2010 (commit 829cd18aa7f45221), because `bodies_by_type` was
+ * Aug 2010 (commit 829cd18aa7f45221), because `PL_bodies_by_type` was
* changed to always hold the accurate metadata for the SV types.
* This was possible because PTEs were no longer allocated from the
* "SVt_IV" arena, and the code to allocate HEs from the "SVt_NULL"
@@ -8191,7 +8191,7 @@ Perl_sv_clear(pTHX_ SV *const orig_sv)
}
else {
arena_index = type;
- sv_type_details = bodies_by_type + arena_index;
+ sv_type_details = PL_bodies_by_type + arena_index;
}
SvFLAGS(sv) &= SVf_BREAK;
@@ -16244,7 +16244,7 @@ S_sv_dup_common(pTHX_ const SV *const ssv, CLONE_PARAMS *const param)
void *new_body;
const svtype sv_type = SvTYPE(ssv);
const struct body_details *sv_type_details
- = bodies_by_type + sv_type;
+ = PL_bodies_by_type + sv_type;
switch (sv_type) {
default:
diff --git a/sv_inline.h b/sv_inline.h
index 7b2656b0af..058ebb334f 100644
--- a/sv_inline.h
+++ b/sv_inline.h
@@ -186,7 +186,8 @@ static const struct body_details fake_hv_with_aux =
SVt_PVHV, TRUE, NONV, HASARENA,
FIT_ARENA(0, sizeof(ALIGNED_TYPE_NAME(XPVHV_WITH_AUX))) };
-static const struct body_details bodies_by_type[] = {
+#ifdef DOINIT
+EXTCONST struct body_details PL_bodies_by_type[] = {
/* HEs use this offset for their arena. */
{ 0, 0, 0, SVt_NULL, FALSE, NONV, NOARENA, 0 },
@@ -296,10 +297,13 @@ static const struct body_details bodies_by_type[] = {
SVt_PVOBJ, TRUE, NONV, HASARENA,
FIT_ARENA(0, sizeof(ALIGNED_TYPE_NAME(XPVOBJ))) },
};
+#else
+EXTCONST struct body_details PL_bodies_by_type[];
+#endif
#define new_body_allocated(sv_type) \
(void *)((char *)S_new_body(aTHX_ sv_type) \
- - bodies_by_type[sv_type].offset)
+ - PL_bodies_by_type[sv_type].offset)
#ifdef PURIFY
#if !(NVSIZE <= IVSIZE)
@@ -323,7 +327,7 @@ static const struct body_details bodies_by_type[] = {
#define new_XPVMG() new_body_allocated(SVt_PVMG)
#define del_body_by_type(p, type) \
- del_body(p + bodies_by_type[(type)].offset, \
+ del_body(p + PL_bodies_by_type[(type)].offset, \
&PL_body_roots[(type)])
#endif /* PURIFY */
@@ -399,7 +403,7 @@ Perl_newSV_type(pTHX_ const svtype type)
const struct body_details *type_details;
PERL_UNUSED_VAR(type_details);
#if defined(PURIFY) || defined(DEBUGGING)
- type_details = bodies_by_type + type;
+ type_details = PL_bodies_by_type + type;
#endif
switch (type) {