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) {