From cef7a38ccdfeb549d7359659bd1478aa95489cd9 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Sat, 4 May 2024 16:07:59 +0200 Subject: [PATCH] Avoid needless memsets by creating a variant of bc_new_num that doesn't memset Also avoid some memsets where we do call bc_new_num. After: ``` 1.2066178321838 1.5389559268951 1.6050860881805 ``` Before: ``` 1.3858470916748 1.6806011199951 1.9091980457306 ``` --- ext/bcmath/libbcmath/src/add.c | 1 - ext/bcmath/libbcmath/src/bcmath.h | 9 ++++++--- ext/bcmath/libbcmath/src/div.c | 2 -- ext/bcmath/libbcmath/src/init.c | 14 ++++++++++++-- ext/bcmath/libbcmath/src/recmul.c | 2 +- ext/bcmath/libbcmath/src/str2num.c | 4 ++-- ext/bcmath/libbcmath/src/sub.c | 1 - 7 files changed, 21 insertions(+), 12 deletions(-) diff --git a/ext/bcmath/libbcmath/src/add.c b/ext/bcmath/libbcmath/src/add.c index d98cb3efb85ea..67fca23e5b590 100644 --- a/ext/bcmath/libbcmath/src/add.c +++ b/ext/bcmath/libbcmath/src/add.c @@ -58,7 +58,6 @@ bc_num bc_add(bc_num n1, bc_num n2, size_t scale_min) case 0: /* They are equal! return zero with the correct scale! */ sum = bc_new_num (1, MAX(scale_min, MAX(n1->n_scale, n2->n_scale))); - memset(sum->n_value, 0, sum->n_scale + 1); break; case 1: /* n2 is less than n1, subtract n2 from n1. */ diff --git a/ext/bcmath/libbcmath/src/bcmath.h b/ext/bcmath/libbcmath/src/bcmath.h index dc1839512f088..5a92273033a9b 100644 --- a/ext/bcmath/libbcmath/src/bcmath.h +++ b/ext/bcmath/libbcmath/src/bcmath.h @@ -86,6 +86,8 @@ void bc_init_numbers(void); bc_num _bc_new_num_ex(size_t length, size_t scale, bool persistent); +bc_num _bc_new_num_nonzeroed_ex(size_t length, size_t scale, bool persistent); + void _bc_free_num_ex(bc_num *num, bool persistent); /* Make a copy of a number! Just increments the reference count! */ @@ -167,8 +169,9 @@ void bc_raise_bc_exponent(bc_num base, bc_num exponent, bc_num *resul, size_t sc bool bc_sqrt(bc_num *num, size_t scale); /* Prototypes needed for external utility routines. */ -#define bc_new_num(length, scale) _bc_new_num_ex((length), (scale), 0) -#define bc_free_num(num) _bc_free_num_ex((num), 0) -#define bc_num2str(num) bc_num2str_ex((num), (num->n_scale)) +#define bc_new_num(length, scale) _bc_new_num_ex((length), (scale), 0) +#define bc_new_num_nonzeroed(length, scale) _bc_new_num_nonzeroed_ex((length), (scale), 0) +#define bc_free_num(num) _bc_free_num_ex((num), 0) +#define bc_num2str(num) bc_num2str_ex((num), (num->n_scale)) #endif diff --git a/ext/bcmath/libbcmath/src/div.c b/ext/bcmath/libbcmath/src/div.c index f45188455e7f2..5d3f0439cc0b7 100644 --- a/ext/bcmath/libbcmath/src/div.c +++ b/ext/bcmath/libbcmath/src/div.c @@ -97,7 +97,6 @@ bool bc_divide(bc_num n1, bc_num n2, bc_num *quot, int scale) if (n2->n_scale == 0 && n2->n_len == 1 && *n2->n_value == 1) { qval = bc_new_num (n1->n_len, scale); qval->n_sign = (n1->n_sign == n2->n_sign ? PLUS : MINUS); - memset(&qval->n_value[n1->n_len], 0, scale); memcpy(qval->n_value, n1->n_value, n1->n_len + MIN(n1->n_scale, scale)); bc_free_num (quot); *quot = qval; @@ -146,7 +145,6 @@ bool bc_divide(bc_num n1, bc_num n2, bc_num *quot, int scale) /* Allocate and zero the storage for the quotient. */ qval = bc_new_num (qdigits - scale, scale); - memset(qval->n_value, 0, qdigits); /* Allocate storage for the temporary storage mval. */ mval = (unsigned char *) safe_emalloc(1, len2, 1); diff --git a/ext/bcmath/libbcmath/src/init.c b/ext/bcmath/libbcmath/src/init.c index 1db324aeee226..2c109f3fb92fb 100644 --- a/ext/bcmath/libbcmath/src/init.c +++ b/ext/bcmath/libbcmath/src/init.c @@ -35,8 +35,7 @@ #include #include "zend_alloc.h" -/* new_num allocates a number and sets fields to known values. */ -bc_num _bc_new_num_ex(size_t length, size_t scale, bool persistent) +static zend_always_inline bc_num _bc_new_num_nonzeroed_ex_internal(size_t length, size_t scale, bool persistent) { /* PHP Change: malloc() -> pemalloc(), removed free_list code, merged n_ptr and n_value */ bc_num temp = safe_pemalloc(1, sizeof(bc_struct) + length, scale, persistent); @@ -45,10 +44,21 @@ bc_num _bc_new_num_ex(size_t length, size_t scale, bool persistent) temp->n_scale = scale; temp->n_refs = 1; temp->n_value = (char *) temp + sizeof(bc_struct); + return temp; +} + +/* new_num allocates a number and sets fields to known values. */ +bc_num _bc_new_num_ex(size_t length, size_t scale, bool persistent) +{ + bc_num temp = _bc_new_num_nonzeroed_ex_internal(length, scale, persistent); memset(temp->n_value, 0, length + scale); return temp; } +bc_num _bc_new_num_nonzeroed_ex(size_t length, size_t scale, bool persistent) +{ + return _bc_new_num_nonzeroed_ex_internal(length, scale, persistent); +} /* "Frees" a bc_num NUM. Actually decreases reference count and only frees the storage if reference count is zero. */ diff --git a/ext/bcmath/libbcmath/src/recmul.c b/ext/bcmath/libbcmath/src/recmul.c index 127330ba3ae54..3b3b696f99d46 100644 --- a/ext/bcmath/libbcmath/src/recmul.c +++ b/ext/bcmath/libbcmath/src/recmul.c @@ -68,7 +68,7 @@ static void _bc_simp_mul(bc_num n1, size_t n1len, bc_num n2, int n2len, bc_num * int prodlen = n1len + n2len + 1; - *prod = bc_new_num (prodlen, 0); + *prod = bc_new_num_nonzeroed(prodlen, 0); n1end = (char *) (n1->n_value + n1len - 1); n2end = (char *) (n2->n_value + n2len - 1); diff --git a/ext/bcmath/libbcmath/src/str2num.c b/ext/bcmath/libbcmath/src/str2num.c index 8a94567a6f4f2..370d899772ff8 100644 --- a/ext/bcmath/libbcmath/src/str2num.c +++ b/ext/bcmath/libbcmath/src/str2num.c @@ -154,12 +154,12 @@ bool bc_str2num(bc_num *num, const char *str, const char *end, size_t scale, boo zero_int = true; digits = 1; } - *num = bc_new_num (digits, str_scale); + *num = bc_new_num_nonzeroed(digits, str_scale); (*num)->n_sign = *str == '-' ? MINUS : PLUS; char *nptr = (*num)->n_value; if (zero_int) { - nptr++; + *nptr++ = 0; /* * If zero_int is true and the str_scale is 0, there is an early return, * so here str_scale is always greater than 0. diff --git a/ext/bcmath/libbcmath/src/sub.c b/ext/bcmath/libbcmath/src/sub.c index a977eac3926a7..92e7ffda949cc 100644 --- a/ext/bcmath/libbcmath/src/sub.c +++ b/ext/bcmath/libbcmath/src/sub.c @@ -59,7 +59,6 @@ bc_num bc_sub(bc_num n1, bc_num n2, size_t scale_min) /* They are equal! return zero! */ size_t res_scale = MAX (scale_min, MAX(n1->n_scale, n2->n_scale)); diff = bc_new_num (1, res_scale); - memset(diff->n_value, 0, res_scale + 1); break; } case 1: