mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-06 06:20:55 -08:00
Tally GMP allocations
Without this, bignum allocations in the pidigits don't properly trigger GC. This patch changes the peak memory usage for the pidigits benchmark by a factor of 6. The benchmark also begins to spend much more time in GC, as it should be: | | max rss | elapsed time | |--------+-----------+--------------| | before | 392472 KB | 6.7 s | | after | 58512 KB | 32.93 s | * src/bignum.h (init_gmp_memory_functions): Declare new function. * src/alloc.c (init_gmp_memory_functions): Implement it. (xmalloc_for_gmp): New helper. (xrealloc_for_gmp, xfree_for_gmp): Moved here from bignum.c. * src/bignum.c (init_bignum): Call init_gmp_memory_functions.
This commit is contained in:
parent
b01c6b2849
commit
43a000c31b
3 changed files with 40 additions and 21 deletions
36
src/alloc.c
36
src/alloc.c
|
|
@ -2600,6 +2600,42 @@ make_float (double float_value)
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
xmalloc_for_gmp (size_t size)
|
||||
{
|
||||
tally_consing (size);
|
||||
return xmalloc (size);
|
||||
}
|
||||
|
||||
static void *
|
||||
xrealloc_for_gmp (void *ptr, size_t old_size, size_t new_size)
|
||||
{
|
||||
tally_consing (new_size - old_size);
|
||||
return xrealloc (ptr, new_size);
|
||||
}
|
||||
|
||||
static void
|
||||
xfree_for_gmp (void *ptr, size_t size)
|
||||
{
|
||||
tally_consing (-size);
|
||||
xfree (ptr);
|
||||
}
|
||||
|
||||
void
|
||||
init_gmp_memory_functions (void)
|
||||
{
|
||||
/* FIXME: The Info node `(gmp) Custom Allocation' states: "No error
|
||||
return is allowed from any of these functions, if they return
|
||||
then they must have performed the specified operation. [...]
|
||||
There's currently no defined way for the allocation functions
|
||||
to recover from an error such as out of memory, they must
|
||||
terminate program execution. A 'longjmp' or throwing a C++
|
||||
exception will have undefined results." But xmalloc and xrealloc
|
||||
do call 'longjmp'. */
|
||||
mp_set_memory_functions (xmalloc_for_gmp, xrealloc_for_gmp,
|
||||
xfree_for_gmp);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
|
|
|
|||
22
src/bignum.c
22
src/bignum.c
|
|
@ -36,33 +36,13 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
|
||||
mpz_t mpz[5];
|
||||
|
||||
static void *
|
||||
xrealloc_for_gmp (void *ptr, size_t ignore, size_t size)
|
||||
{
|
||||
return xrealloc (ptr, size);
|
||||
}
|
||||
|
||||
static void
|
||||
xfree_for_gmp (void *ptr, size_t ignore)
|
||||
{
|
||||
xfree (ptr);
|
||||
}
|
||||
|
||||
void
|
||||
init_bignum (void)
|
||||
{
|
||||
eassert (mp_bits_per_limb == GMP_NUMB_BITS);
|
||||
integer_width = 1 << 16;
|
||||
|
||||
/* FIXME: The Info node `(gmp) Custom Allocation' states: "No error
|
||||
return is allowed from any of these functions, if they return
|
||||
then they must have performed the specified operation. [...]
|
||||
There's currently no defined way for the allocation functions to
|
||||
recover from an error such as out of memory, they must terminate
|
||||
program execution. A 'longjmp' or throwing a C++ exception will
|
||||
have undefined results." But xmalloc and xrealloc do call
|
||||
'longjmp'. */
|
||||
mp_set_memory_functions (xmalloc, xrealloc_for_gmp, xfree_for_gmp);
|
||||
init_gmp_memory_functions ();
|
||||
|
||||
for (int i = 0; i < ARRAYELTS (mpz); i++)
|
||||
mpz_init (mpz[i]);
|
||||
|
|
|
|||
|
|
@ -59,6 +59,9 @@ extern void emacs_mpz_pow_ui (mpz_t, mpz_t const, unsigned long)
|
|||
extern double mpz_get_d_rounded (mpz_t const);
|
||||
extern Lisp_Object get_random_bignum (struct Lisp_Bignum const *);
|
||||
|
||||
/* defined in alloc.c */
|
||||
extern void init_gmp_memory_functions (void);
|
||||
|
||||
INLINE_HEADER_BEGIN
|
||||
|
||||
INLINE struct Lisp_Bignum *
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue