mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-22 04:30:19 +02:00
Fix bignum memory leak.
The `mpz_t' associated with a bignum would never be freed, so an expression like `(while #t (expt 2 5000))' would quickly lead to memory exhaustion. * libguile/numbers.c (finalize_bignum): New function. (make_bignum): Register it as a finalizer for P.
This commit is contained in:
parent
d017fcdfcb
commit
864e7d424e
1 changed files with 18 additions and 0 deletions
|
@ -60,6 +60,7 @@
|
||||||
#include "libguile/root.h"
|
#include "libguile/root.h"
|
||||||
#include "libguile/smob.h"
|
#include "libguile/smob.h"
|
||||||
#include "libguile/strings.h"
|
#include "libguile/strings.h"
|
||||||
|
#include "libguile/bdw-gc.h"
|
||||||
|
|
||||||
#include "libguile/validate.h"
|
#include "libguile/validate.h"
|
||||||
#include "libguile/numbers.h"
|
#include "libguile/numbers.h"
|
||||||
|
@ -152,20 +153,37 @@ scm_from_complex_double (complex double z)
|
||||||
static mpz_t z_negative_one;
|
static mpz_t z_negative_one;
|
||||||
|
|
||||||
|
|
||||||
|
/* Clear the `mpz_t' embedded in bignum PTR. */
|
||||||
|
static void
|
||||||
|
finalize_bignum (GC_PTR ptr, GC_PTR data)
|
||||||
|
{
|
||||||
|
SCM bignum;
|
||||||
|
|
||||||
|
bignum = PTR2SCM (ptr);
|
||||||
|
mpz_clear (SCM_I_BIG_MPZ (bignum));
|
||||||
|
}
|
||||||
|
|
||||||
/* Return a new uninitialized bignum. */
|
/* Return a new uninitialized bignum. */
|
||||||
static inline SCM
|
static inline SCM
|
||||||
make_bignum (void)
|
make_bignum (void)
|
||||||
{
|
{
|
||||||
scm_t_bits *p;
|
scm_t_bits *p;
|
||||||
|
GC_finalization_proc prev_finalizer;
|
||||||
|
GC_PTR prev_finalizer_data;
|
||||||
|
|
||||||
/* Allocate one word for the type tag and enough room for an `mpz_t'. */
|
/* Allocate one word for the type tag and enough room for an `mpz_t'. */
|
||||||
p = scm_gc_malloc_pointerless (sizeof (scm_t_bits) + sizeof (mpz_t),
|
p = scm_gc_malloc_pointerless (sizeof (scm_t_bits) + sizeof (mpz_t),
|
||||||
"bignum");
|
"bignum");
|
||||||
p[0] = scm_tc16_big;
|
p[0] = scm_tc16_big;
|
||||||
|
|
||||||
|
GC_REGISTER_FINALIZER_NO_ORDER (p, finalize_bignum, NULL,
|
||||||
|
&prev_finalizer,
|
||||||
|
&prev_finalizer_data);
|
||||||
|
|
||||||
return SCM_PACK (p);
|
return SCM_PACK (p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SCM
|
SCM
|
||||||
scm_i_mkbig ()
|
scm_i_mkbig ()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue