mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Avoid needless memsets by creating a variant of bc_new_num that doesn't memset (#14133)
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 ```
This commit is contained in:
@@ -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. */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -35,8 +35,7 @@
|
||||
#include <string.h>
|
||||
#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. */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -154,12 +154,12 @@ after_fractional:
|
||||
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.
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user