diff --git a/embed.fnc b/embed.fnc index 0332f63875ec..b0510db2d229 100644 --- a/embed.fnc +++ b/embed.fnc @@ -2043,9 +2043,7 @@ p |int |mode_from_discipline \ |STRLEN len : Used in sv.c and hv.c -Cop |void * |more_bodies |const svtype sv_type \ - |const size_t body_size \ - |const size_t arena_size +Cop |void * |more_bodies |const svtype sv_type Cp |const char *|moreswitches \ |NN const char *s Adp |void |mortal_destructor_sv \ diff --git a/hv.c b/hv.c index 8c65091fd2ca..a62350ff4e94 100644 --- a/hv.c +++ b/hv.c @@ -159,7 +159,7 @@ S_new_he(pTHX) void ** const root = &PL_body_roots[HE_ARENA_ROOT_IX]; if (!*root) - Perl_more_bodies(aTHX_ HE_ARENA_ROOT_IX, sizeof(HE), PERL_ARENA_SIZE); + Perl_more_bodies(aTHX_ HE_ARENA_ROOT_IX); he = (HE*) *root; assert(he); *root = HeNEXT(he); diff --git a/proto.h b/proto.h index e132956f8ac8..f11476f1163c 100644 --- a/proto.h +++ b/proto.h @@ -2555,7 +2555,7 @@ Perl_mode_from_discipline(pTHX_ const char *s, STRLEN len) #define PERL_ARGS_ASSERT_MODE_FROM_DISCIPLINE PERL_CALLCONV void * -Perl_more_bodies(pTHX_ const svtype sv_type, const size_t body_size, const size_t arena_size); +Perl_more_bodies(pTHX_ const svtype sv_type); #define PERL_ARGS_ASSERT_MORE_BODIES PERL_CALLCONV const char * diff --git a/sv.c b/sv.c index e8c6e65a2717..1ce51330cc02 100644 --- a/sv.c +++ b/sv.c @@ -856,10 +856,22 @@ available in hv.c. Similarly SVt_IV is re-used for HVAUX_ARENA_ROOT_IX. void * -Perl_more_bodies (pTHX_ const svtype sv_type, const size_t body_size, - const size_t arena_size) +Perl_more_bodies (pTHX_ const svtype sv_type) { void ** const root = &PL_body_roots[sv_type]; + + const struct body_details *type_details = + (sv_type > SVt_IV) + ? bodies_by_type + sv_type + : (sv_type == SVt_NULL) + ? NULL + : &fake_hv_with_aux + ; + + const size_t body_size = (type_details) ? type_details->body_size + : sizeof(HE); + const size_t arena_size = (type_details) ? type_details->arena_size + : PERL_ARENA_SIZE; struct arena_desc *adesc; struct arena_set *aroot = (struct arena_set *) PL_body_arenas; unsigned int curr; @@ -1291,7 +1303,7 @@ Perl_hv_auxalloc(pTHX_ HV *hv) { #ifdef PURIFY new_body = new_NOARENAZ(&fake_hv_with_aux); #else - new_body_from_arena(new_body, HVAUX_ARENA_ROOT_IX, fake_hv_with_aux); + new_body_from_arena(new_body, HVAUX_ARENA_ROOT_IX); #endif old_body = SvANY(hv); @@ -14799,7 +14811,7 @@ S_sv_dup_common(pTHX_ const SV *const ssv, CLONE_PARAMS *const param) #ifdef PURIFY new_body = new_NOARENA(sv_type_details); #else - new_body_from_arena(new_body, HVAUX_ARENA_ROOT_IX, fake_hv_with_aux); + new_body_from_arena(new_body, HVAUX_ARENA_ROOT_IX); #endif goto have_body; } diff --git a/sv_inline.h b/sv_inline.h index 57a68796cb02..70153d2024aa 100644 --- a/sv_inline.h +++ b/sv_inline.h @@ -180,6 +180,14 @@ ALIGNED_TYPE(XPVOBJ); STRUCT_OFFSET(type, last_member) \ + sizeof (((type*)SvANY((const SV *)0))->last_member) +static const struct body_details fake_hv_with_aux = + /* The SVt_IV arena is used for (larger) PVHV bodies. */ + { sizeof(ALIGNED_TYPE_NAME(XPVHV_WITH_AUX)), + copy_length(XPVHV, xhv_max), + 0, + SVt_PVHV, TRUE, NONV, HASARENA, + FIT_ARENA(0, sizeof(ALIGNED_TYPE_NAME(XPVHV_WITH_AUX))) }; + static const struct body_details bodies_by_type[] = { /* HEs use this offset for their arena. */ { 0, 0, 0, SVt_NULL, FALSE, NONV, NOARENA, 0 }, @@ -328,13 +336,11 @@ static const struct body_details bodies_by_type[] = { #ifndef PURIFY /* grab a new thing from the arena's free list, allocating more if necessary. */ -#define new_body_from_arena(xpv, root_index, type_meta) \ +#define new_body_from_arena(xpv, root_index) \ STMT_START { \ void ** const r3wt = &PL_body_roots[root_index]; \ xpv = (PTR_TBL_ENT_t*) (*((void **)(r3wt)) \ - ? *((void **)(r3wt)) : Perl_more_bodies(aTHX_ root_index, \ - type_meta.body_size,\ - type_meta.arena_size)); \ + ? *((void **)(r3wt)) : Perl_more_bodies(aTHX_ root_index)); \ *(r3wt) = *(void**)(xpv); \ } STMT_END @@ -342,7 +348,7 @@ PERL_STATIC_INLINE void * S_new_body(pTHX_ const svtype sv_type) { void *xpv; - new_body_from_arena(xpv, sv_type, bodies_by_type[sv_type]); + new_body_from_arena(xpv, sv_type); return xpv; } @@ -351,14 +357,6 @@ S_new_body(pTHX_ const svtype sv_type) static const struct body_details fake_rv = { 0, 0, 0, SVt_IV, FALSE, NONV, NOARENA, 0 }; -static const struct body_details fake_hv_with_aux = - /* The SVt_IV arena is used for (larger) PVHV bodies. */ - { sizeof(ALIGNED_TYPE_NAME(XPVHV_WITH_AUX)), - copy_length(XPVHV, xhv_max), - 0, - SVt_PVHV, TRUE, NONV, HASARENA, - FIT_ARENA(0, sizeof(ALIGNED_TYPE_NAME(XPVHV_WITH_AUX))) }; - /* =for apidoc newSV_type @@ -381,6 +379,7 @@ Perl_newSV_type(pTHX_ const svtype type) SvFLAGS(sv) &= ~SVTYPEMASK; SvFLAGS(sv) |= type; +// SvFLAGS(sv) = type; switch (type) { case SVt_NULL: