diff --git a/embed.fnc b/embed.fnc index e21628b8a0c5..40cb955a255b 100644 --- a/embed.fnc +++ b/embed.fnc @@ -4706,6 +4706,7 @@ RST |bool |scalar_mod_type|NULLOK const OP *o \ |I32 type RS |OP * |search_const |NN OP *o S |void |simplify_sort |NN OP *o +Ti |U16 |size_to_psize |size_t size RS |OP * |too_few_arguments_pv \ |NN OP *o \ |NN const char *name \ diff --git a/embed.h b/embed.h index 8f5e05b257ef..d118200331ab 100644 --- a/embed.h +++ b/embed.h @@ -1425,6 +1425,7 @@ # define scalarkids(a) S_scalarkids(aTHX_ a) # define search_const(a) S_search_const(aTHX_ a) # define simplify_sort(a) S_simplify_sort(aTHX_ a) +# define size_to_psize S_size_to_psize # define too_few_arguments_pv(a,b,c) S_too_few_arguments_pv(aTHX_ a,b,c) # define too_many_arguments_pv(a,b,c) S_too_many_arguments_pv(aTHX_ a,b,c) # define voidnonfinal(a) S_voidnonfinal(aTHX_ a) diff --git a/op.c b/op.c index a48093d47926..6792c25e958a 100644 --- a/op.c +++ b/op.c @@ -207,7 +207,13 @@ Perl_op_prune_chain_head(OP** op_p) #endif /* rounds up to nearest pointer */ -#define SIZE_TO_PSIZE(x) ((U16)(((x) + sizeof(I32 *) - 1)/sizeof(I32 *))) +PERL_STATIC_INLINE U16 +S_size_to_psize(size_t sz) { + size_t psize = (sz + sizeof(I32 *) - 1) / sizeof(I32 *); + assert(psize < U16_MAX); + + return (U16)psize; +} #define DIFF(o,p) \ (assert((size_t)((char *)(p) - (char *)(o)) % sizeof(I32**) == 0), \ @@ -221,7 +227,7 @@ Perl_op_prune_chain_head(OP** op_p) ) /* opslot_size includes the size of the slot header, and an op can't be smaller than BASEOP */ -#define OPSLOT_SIZE_BASE (SIZE_TO_PSIZE(sizeof(OPSLOT))) +#define OPSLOT_SIZE_BASE (size_to_psize(sizeof(OPSLOT))) /* the number of bytes to allocate for a slab with sz * sizeof(I32 **) space for op */ #define OpSLABSizeBytes(sz) \ @@ -350,7 +356,7 @@ Perl_Slab_Alloc(pTHX_ size_t sz) else ++(head_slab = (OPSLAB *)CvSTART(PL_compcv))->opslab_refcnt; /* size in pointer units, including the OPSLOT header */ - U16 sz_in_p = SIZE_TO_PSIZE(sz + OPSLOT_HEADER); + U16 sz_in_p = size_to_psize(sz + OPSLOT_HEADER); /* The head slab for each CV maintains a free list of OPs. In particular, constant folding will free up OPs, so it makes sense to re-use them where possible. A @@ -9501,7 +9507,7 @@ Perl_newFOROP(pTHX_ I32 flags, OP *sv, OP *expr, OP *block, OP *cont) * keep it in-place if there's space */ if (loop->op_slabbed && OpSLOT(loop)->opslot_size - < SIZE_TO_PSIZE(sizeof(LOOP) + OPSLOT_HEADER)) + < size_to_psize(sizeof(LOOP) + OPSLOT_HEADER)) { /* no space; allocate new op */ LOOP *tmp; diff --git a/proto.h b/proto.h index 5b57034cc58b..a5fd57078154 100644 --- a/proto.h +++ b/proto.h @@ -7464,6 +7464,10 @@ S_op_std_init(pTHX_ OP *o); # define PERL_ARGS_ASSERT_OP_STD_INIT \ assert(o) +PERL_STATIC_INLINE U16 +S_size_to_psize(size_t size); +# define PERL_ARGS_ASSERT_SIZE_TO_PSIZE + # endif /* !defined(PERL_NO_INLINE_FUNCTIONS) */ #endif /* defined(PERL_IN_OP_C) */ #if defined(PERL_IN_OP_C) || defined(PERL_IN_PEEP_C)