1
Fork 0
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:
Helmut Eller 2025-12-01 15:37:57 +01:00
parent b01c6b2849
commit 43a000c31b
3 changed files with 40 additions and 21 deletions

View file

@ -2600,6 +2600,42 @@ make_float (double float_value)
#endif #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);
}
/*********************************************************************** /***********************************************************************

View file

@ -36,33 +36,13 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
mpz_t mpz[5]; 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 void
init_bignum (void) init_bignum (void)
{ {
eassert (mp_bits_per_limb == GMP_NUMB_BITS); eassert (mp_bits_per_limb == GMP_NUMB_BITS);
integer_width = 1 << 16; integer_width = 1 << 16;
/* FIXME: The Info node `(gmp) Custom Allocation' states: "No error init_gmp_memory_functions ();
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);
for (int i = 0; i < ARRAYELTS (mpz); i++) for (int i = 0; i < ARRAYELTS (mpz); i++)
mpz_init (mpz[i]); mpz_init (mpz[i]);

View file

@ -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 double mpz_get_d_rounded (mpz_t const);
extern Lisp_Object get_random_bignum (struct Lisp_Bignum 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_HEADER_BEGIN
INLINE struct Lisp_Bignum * INLINE struct Lisp_Bignum *