From: Mark H Weaver <mhw@netris.org>
To: guile-devel@gnu.org
Subject: Re: [PATCH] Configure GMP to use GC allocation functions, remove bignum finalizers
Date: Tue, 31 May 2011 16:07:29 -0400 [thread overview]
Message-ID: <87pqmyocqm.fsf@netris.org> (raw)
In-Reply-To: <87tycaodlk.fsf@netris.org> (Mark H. Weaver's message of "Tue, 31 May 2011 15:48:55 -0400")
[-- Attachment #1: Type: text/plain, Size: 367 bytes --]
Here is a revised version of the patch, which fixes a typo in a comment
and a poorly chosen "what" tag for allocation.
Also, the definition of factorial in my email had a typo. It should be:
(define (factorial n)
(define (fac n acc)
(if (<= n 1)
acc
(fac (1- n) (* n acc))))
(fac n 1))
Apologies for the sloppiness,
Mark
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Configure GMP to use GC allocation functions, remove bignum finalizers --]
[-- Type: text/x-diff, Size: 4104 bytes --]
From 2a8c5a5b464f2af723476585f620a108ac1cc37b Mon Sep 17 00:00:00 2001
From: Mark H Weaver <mhw@netris.org>
Date: Tue, 31 May 2011 15:26:41 -0400
Subject: [PATCH] Configure GMP to use GC allocation functions, remove bignum finalizers
* libguile/numbers.c (custom_gmp_malloc, custom_gmp_realloc,
custom_gmp_free): New static functions used by GMP for allocation.
These are just wrappers for scm_gc_malloc, scm_gc_realloc, and
scm_gc_free.
(scm_init_numbers): Use mp_set_memory_functions to configure GMP to
use custom_gmp_{malloc,realloc,free} for memory allocation.
(make_bignum): Allocate the mpz_t (and type tag) using scm_gc_malloc,
so that the GC will see the pointer to the digits, which are now
allocated using custom_gmp_malloc. Previously,
scm_gc_malloc_pointerless was used to allocate the mpz_t, and a
finalizer was used to free the digits.
(finalize_bignum): Remove this static function.
(scm_bigprint): Use custom_gmp_free to deallocate the string returned
by mpz_get_str.
---
libguile/numbers.c | 53 ++++++++++++++++++++++++++++++++++++---------------
1 files changed, 37 insertions(+), 16 deletions(-)
diff --git a/libguile/numbers.c b/libguile/numbers.c
index 5aeced6..d14e5ea 100644
--- a/libguile/numbers.c
+++ b/libguile/numbers.c
@@ -172,14 +172,32 @@ scm_from_complex_double (complex double z)
static mpz_t z_negative_one;
\f
-/* Clear the `mpz_t' embedded in bignum PTR. */
-static void
-finalize_bignum (GC_PTR ptr, GC_PTR data)
+
+/* The next three functions (custom_gmp_*) are passed to
+ mp_set_memory_functions (in GMP) so that memory used by the digits
+ themselves are allocated by the garbage collector. This is needed so
+ that GC will be run at appropriate times. Otherwise, a program which
+ creates many large bignums would malloc a huge amount of memory
+ before the GC runs. */
+static void *
+custom_gmp_malloc (size_t alloc_size)
+{
+ /* Unfortunately we cannot safely use scm_gc_malloc_pointerless here,
+ because the GMP docs specifically warns that it may use allocated
+ blocks to hold pointers to other allocated blocks. */
+ return scm_gc_malloc (alloc_size, "gmp-internal");
+}
+
+static void *
+custom_gmp_realloc (void *old_ptr, size_t old_size, size_t new_size)
{
- SCM bignum;
+ return scm_gc_realloc (old_ptr, old_size, new_size, "gmp-internal");
+}
- bignum = PTR2SCM (ptr);
- mpz_clear (SCM_I_BIG_MPZ (bignum));
+static void
+custom_gmp_free (void *ptr, size_t size)
+{
+ scm_gc_free (ptr, size, "gmp-internal");
}
/* Return a new uninitialized bignum. */
@@ -187,18 +205,12 @@ static inline SCM
make_bignum (void)
{
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'. */
- p = scm_gc_malloc_pointerless (sizeof (scm_t_bits) + sizeof (mpz_t),
- "bignum");
+ p = scm_gc_malloc (sizeof (scm_t_bits) + sizeof (mpz_t),
+ "bignum");
p[0] = scm_tc16_big;
- GC_REGISTER_FINALIZER_NO_ORDER (p, finalize_bignum, NULL,
- &prev_finalizer,
- &prev_finalizer_data);
-
return SCM_PACK (p);
}
@@ -5360,9 +5372,10 @@ int
scm_bigprint (SCM exp, SCM port, scm_print_state *pstate SCM_UNUSED)
{
char *str = mpz_get_str (NULL, 10, SCM_I_BIG_MPZ (exp));
+ size_t len = (size_t) strlen (str);
scm_remember_upto_here_1 (exp);
- scm_lfwrite (str, (size_t) strlen (str), port);
- free (str);
+ scm_lfwrite (str, len, port);
+ custom_gmp_free (str, len + 1);
return !0;
}
/*** END nums->strs ***/
@@ -9668,6 +9681,14 @@ scm_init_numbers ()
{
int i;
+ /* IMPORTANT: mp_set_memory_functions _must_ be called before any GMP
+ functions are called, or else custom_gmp_realloc and/or
+ custom_gmp_free could be called on a memory block allocated with
+ plain malloc, which would be bad. */
+ mp_set_memory_functions (custom_gmp_malloc,
+ custom_gmp_realloc,
+ custom_gmp_free);
+
mpz_init_set_si (z_negative_one, -1);
/* It may be possible to tune the performance of some algorithms by using
--
1.7.1
next prev parent reply other threads:[~2011-05-31 20:07 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-05-31 19:48 [PATCH] Configure GMP to use GC allocation functions, remove bignum finalizers Mark H Weaver
2011-05-31 20:07 ` Mark H Weaver [this message]
2011-05-31 21:52 ` Ludovic Courtès
2011-05-31 23:18 ` Neil Jerram
2011-05-31 23:32 ` Neil Jerram
2011-06-01 8:34 ` Andy Wingo
2011-06-02 23:14 ` Ludovic Courtès
2011-11-27 19:33 ` Andy Wingo
2011-11-27 21:25 ` Ludovic Courtès
2011-11-28 22:23 ` Andy Wingo
2011-11-28 23:10 ` Ludovic Courtès
2011-11-28 23:50 ` Andy Wingo
2011-11-29 11:06 ` Ludovic Courtès
2011-11-29 11:35 ` Andy Wingo
2011-11-29 13:20 ` Ludovic Courtès
2011-11-29 12:45 ` Andy Wingo
2011-11-29 13:18 ` Ludovic Courtès
2011-11-29 14:44 ` Andy Wingo
2011-11-29 16:22 ` Ludovic Courtès
2011-12-02 11:10 ` Andy Wingo
2011-12-02 17:02 ` Ludovic Courtès
2011-12-02 18:12 ` Andy Wingo
2011-12-02 22:17 ` Ludovic Courtès
2011-12-03 10:57 ` Andy Wingo
2011-12-03 17:57 ` Ludovic Courtès
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/guile/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87pqmyocqm.fsf@netris.org \
--to=mhw@netris.org \
--cc=guile-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).