mirror of
https://github.com/Perl/perl5.git
synced 2026-01-27 01:44:43 +00:00
Perl_more_bodies - figure out sizing from sv_type
`Perl_more_bodies` allocates and sets up a new arena for the likes of
SV body, HE, and HVAUX structs. It has traditionally been called with
three arguments:
* the `svtype`
* the size of the structs that the arena will contain
* the size of the arena to allocate
This commit changes the function definition such that it only takes
a single argument: the `svtype`. From that, and with a bit of
additional logic to account of HE and HVAUX using the indexes
notionally for SVt_NULL and SVt_IV, `Perl_more_bodies` can figure
out the sizing for itself.
The rationale for this is that:
* When an application is starting up, the need to call `Perl_more_bodies`
is the unlikely case in each new SV allocation or upgrade.
* When the application has reached a steady state, the function
may not be called regardless of how many SVs are created or upgraded.
With `Perl_newSV_type` being an inline function, there are a lot of
potential callers to this function though, each of which will have
two `mov` instructions for pushing the two size parameters onto the
stack should the need to call `Perl_more_bodies` arise. Removing two
instructions from each potential call site should help reduce binary
size a little and avoid taking up unnecessary space in the CPU's
instruction buffer.
This commit is contained in:
parent
9c39a33a0e
commit
b40ae72cfc
@ -2024,9 +2024,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 \
|
||||
|
||||
2
hv.c
2
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);
|
||||
|
||||
2
proto.h
generated
2
proto.h
generated
@ -2493,7 +2493,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 *
|
||||
|
||||
20
sv.c
20
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);
|
||||
@ -14713,7 +14725,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;
|
||||
}
|
||||
|
||||
24
sv_inline.h
24
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
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user