[Gmp-commit] /var/hg/gmp: mini-gmp: Pass correct old_size to custom free and ...

mercurial at gmplib.org mercurial at gmplib.org
Wed May 27 18:45:55 UTC 2020


details:   /var/hg/gmp/rev/5c0356b63cf0
changeset: 18077:5c0356b63cf0
user:      Niels M?ller <nisse at lysator.liu.se>
date:      Wed May 27 20:45:14 2020 +0200
description:
mini-gmp: Pass correct old_size to custom free and reallocate functions.

Contributed by Minux Ma.

diffstat:

 mini-gmp/ChangeLog         |   20 ++++++++
 mini-gmp/README            |    7 ---
 mini-gmp/mini-gmp.c        |  104 +++++++++++++++++++++++++++-----------------
 mini-gmp/mini-mpq.c        |   16 +++---
 mini-gmp/tests/t-double.c  |    2 +-
 mini-gmp/tests/t-mpq_str.c |    7 +-
 mini-gmp/tests/t-str.c     |    5 +-
 mini-gmp/tests/testutils.c |   27 +++++++++--
 mini-gmp/tests/testutils.h |    2 +-
 9 files changed, 120 insertions(+), 70 deletions(-)

diffs (truncated from 538 to 300 lines):

diff -r df0effd0a69e -r 5c0356b63cf0 mini-gmp/ChangeLog
--- a/mini-gmp/ChangeLog	Sun May 17 22:55:12 2020 +0200
+++ b/mini-gmp/ChangeLog	Wed May 27 20:45:14 2020 +0200
@@ -1,3 +1,23 @@
+2020-05-27  Minux Ma  <minux.ma at gmail.com>
+
+	Pass correct old_size to custom free and reallocate functions.
+	* mini-gmp.c (gmp_alloc): Renamed macro from...
+	(gmp_xalloc): .. old name.
+	(gmp_realloc): New macro, with old_size argument.
+	(gmp_free): Take size argument, and pass on.
+	(gmp_realloc_limbs): Add old_size argument, and rename from
+	(gmp_xrealloc_limbs): ... old name..
+	(gmp_free_limbs): New function, with size argument. Lots of
+	updates, only non-trivial ones listed below.
+	(mpn_div_qr_1_preinv): Use gmp_free_limbs, simplify dealloc logic.
+	(mpz_get_str): Realloc result area when needed, to match final
+	digit count.
+	* mini-mpq.c (mpq_get_str, mpq_out_str, mpq_set_str): Pass correct
+	size to gmp_free_func.
+	* tests/testutils.c (tu_realloc, tu_free): Check that old_size
+	matches size in block header.
+	(testfree): Add size argument. Update all callers.
+
 2020-04-20  Niels Möller  <nisse at lysator.liu.se>
 
 	* mini-gmp.c (mpz_fits_slong_p): Simplify, by using mpz_cmp_si.
diff -r df0effd0a69e -r 5c0356b63cf0 mini-gmp/README
--- a/mini-gmp/README	Sun May 17 22:55:12 2020 +0200
+++ b/mini-gmp/README	Wed May 27 20:45:14 2020 +0200
@@ -45,13 +45,6 @@
 
   mpz_export and mpz_import support only NAILS = 0.
 
-  The REALLOC_FUNC and FREE_FUNC registered with
-  mp_set_memory_functions does not get the correct size of the
-  allocated block in the corresponding argument. mini-gmp always
-  passes zero for these rarely used arguments.
-
-  When mpz_get_str allocates the block, it can be longer than needed.
-
 The performance target for mini-gmp is to be at most 10 times slower
 than the real GMP library, for numbers of size up to a few hundred
 bits. No asymptotically fast algorithms are included in mini-gmp, so
diff -r df0effd0a69e -r 5c0356b63cf0 mini-gmp/mini-gmp.c
--- a/mini-gmp/mini-gmp.c	Sun May 17 22:55:12 2020 +0200
+++ b/mini-gmp/mini-gmp.c	Wed May 27 20:45:14 2020 +0200
@@ -351,20 +351,27 @@
   gmp_free_func = free_func;
 }
 
-#define gmp_xalloc(size) ((*gmp_allocate_func)((size)))
-#define gmp_free(p) ((*gmp_free_func) ((p), 0))
+#define gmp_alloc(size) ((*gmp_allocate_func)((size)))
+#define gmp_free(p, size) ((*gmp_free_func) ((p), (size)))
+#define gmp_realloc(ptr, old_size, size) ((*gmp_reallocate_func)(ptr, old_size, size))
 
 static mp_ptr
-gmp_xalloc_limbs (mp_size_t size)
+gmp_alloc_limbs (mp_size_t size)
 {
-  return (mp_ptr) gmp_xalloc (size * sizeof (mp_limb_t));
+  return (mp_ptr) gmp_alloc (size * sizeof (mp_limb_t));
 }
 
 static mp_ptr
-gmp_xrealloc_limbs (mp_ptr old, mp_size_t size)
+gmp_realloc_limbs (mp_ptr old, mp_size_t old_size, mp_size_t size)
 {
   assert (size > 0);
-  return (mp_ptr) (*gmp_reallocate_func) (old, 0, size * sizeof (mp_limb_t));
+  return (mp_ptr) gmp_realloc (old, old_size * sizeof (mp_limb_t), size * sizeof (mp_limb_t));
+}
+
+static void
+gmp_free_limbs (mp_ptr old, mp_size_t size)
+{
+  gmp_free (old, size * sizeof (mp_limb_t));
 }
 
 

@@ -956,11 +963,17 @@
   mp_limb_t d, di;
   mp_limb_t r;
   mp_ptr tp = NULL;
+  mp_size_t tn = 0;
 
   if (inv->shift > 0)
     {
       /* Shift, reusing qp area if possible. In-place shift if qp == np. */
-      tp = qp ? qp : gmp_xalloc_limbs (nn);
+      tp = qp;
+      if (!tp)
+        {
+	   tn = nn;
+	   tp = gmp_alloc_limbs (tn);
+        }
       r = mpn_lshift (tp, np, nn, inv->shift);
       np = tp;
     }
@@ -977,8 +990,8 @@
       if (qp)
 	qp[nn] = q;
     }
-  if ((inv->shift > 0) && (tp != qp))
-    gmp_free (tp);
+  if (tn)
+    gmp_free_limbs (tp, tn);
 
   return r >> inv->shift;
 }
@@ -1136,13 +1149,13 @@
   mpn_div_qr_invert (&inv, dp, dn);
   if (dn > 2 && inv.shift > 0)
     {
-      tp = gmp_xalloc_limbs (dn);
+      tp = gmp_alloc_limbs (dn);
       gmp_assert_nocarry (mpn_lshift (tp, dp, dn, inv.shift));
       dp = tp;
     }
   mpn_div_qr_preinv (qp, np, nn, dp, dn, &inv);
   if (tp)
-    gmp_free (tp);
+    gmp_free_limbs (tp, dn);
 }
 
 

@@ -1428,14 +1441,14 @@
 
   r->_mp_alloc = rn;
   r->_mp_size = 0;
-  r->_mp_d = gmp_xalloc_limbs (rn);
+  r->_mp_d = gmp_alloc_limbs (rn);
 }
 
 void
 mpz_clear (mpz_t r)
 {
   if (r->_mp_alloc)
-    gmp_free (r->_mp_d);
+    gmp_free_limbs (r->_mp_d, r->_mp_alloc);
 }
 
 static mp_ptr
@@ -1444,9 +1457,9 @@
   size = GMP_MAX (size, 1);
 
   if (r->_mp_alloc)
-    r->_mp_d = gmp_xrealloc_limbs (r->_mp_d, size);
+    r->_mp_d = gmp_realloc_limbs (r->_mp_d, r->_mp_alloc, size);
   else
-    r->_mp_d = gmp_xalloc_limbs (size);
+    r->_mp_d = gmp_alloc_limbs (size);
   r->_mp_alloc = size;
 
   if (GMP_ABS (r->_mp_size) > size)
@@ -3096,7 +3109,7 @@
 	 one, using a *normalized* m. */
       minv.shift = 0;
 
-      tp = gmp_xalloc_limbs (mn);
+      tp = gmp_alloc_limbs (mn);
       gmp_assert_nocarry (mpn_lshift (tp, mp, mn, shift));
       mp = tp;
     }
@@ -3162,7 +3175,7 @@
       tr->_mp_size = mpn_normalized_size (tr->_mp_d, mn);
     }
   if (tp)
-    gmp_free (tp);
+    gmp_free_limbs (tp, mn);
 
   mpz_swap (r, tr);
   mpz_clear (tr);
@@ -4166,7 +4179,7 @@
 size_t
 mpz_sizeinbase (const mpz_t u, int base)
 {
-  mp_size_t un;
+  mp_size_t un, tn;
   mp_srcptr up;
   mp_ptr tp;
   mp_bitcnt_t bits;
@@ -4199,20 +4212,21 @@
 	 10. */
     }
 
-  tp = gmp_xalloc_limbs (un);
+  tp = gmp_alloc_limbs (un);
   mpn_copyi (tp, up, un);
   mpn_div_qr_1_invert (&bi, base);
 
+  tn = un;
   ndigits = 0;
   do
     {
       ndigits++;
-      mpn_div_qr_1_preinv (tp, tp, un, &bi);
-      un -= (tp[un-1] == 0);
+      mpn_div_qr_1_preinv (tp, tp, tn, &bi);
+      tn -= (tp[tn-1] == 0);
     }
-  while (un > 0);
-
-  gmp_free (tp);
+  while (tn > 0);
+
+  gmp_free_limbs (tp, un);
   return ndigits;
 }
 
@@ -4222,7 +4236,7 @@
   unsigned bits;
   const char *digits;
   mp_size_t un;
-  size_t i, sn;
+  size_t i, sn, osn;
 
   digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
   if (base > 1)
@@ -4243,15 +4257,19 @@
 
   sn = 1 + mpz_sizeinbase (u, base);
   if (!sp)
-    sp = (char *) gmp_xalloc (1 + sn);
-
+    {
+      osn = 1 + sn;
+      sp = (char *) gmp_alloc (osn);
+    }
+  else
+    osn = 0;
   un = GMP_ABS (u->_mp_size);
 
   if (un == 0)
     {
       sp[0] = '0';
-      sp[1] = '\0';
-      return sp;
+      sn = 1;
+      goto ret;
     }
 
   i = 0;
@@ -4270,17 +4288,20 @@
       mp_ptr tp;
 
       mpn_get_base_info (&info, base);
-      tp = gmp_xalloc_limbs (un);
+      tp = gmp_alloc_limbs (un);
       mpn_copyi (tp, u->_mp_d, un);
 
       sn = i + mpn_get_str_other ((unsigned char *) sp + i, base, &info, tp, un);
-      gmp_free (tp);
+      gmp_free_limbs (tp, un);
     }
 
   for (; i < sn; i++)
     sp[i] = digits[(unsigned char) sp[i]];
 
+ret:
   sp[sn] = '\0';
+  if (osn && osn != sn + 1)
+    sp = gmp_realloc(sp, osn, sn + 1);
   return sp;
 }
 
@@ -4290,7 +4311,7 @@
   unsigned bits, value_of_a;
   mp_size_t rn, alloc;
   mp_ptr rp;
-  size_t dn;
+  size_t dn, sn;
   int sign;
   unsigned char *dp;
 
@@ -4328,7 +4349,8 @@
       r->_mp_size = 0;
       return -1;
     }
-  dp = (unsigned char *) gmp_xalloc (strlen (sp));
+  sn = strlen(sp);
+  dp = (unsigned char *) gmp_alloc (sn);
 
   value_of_a = (base > 36) ? 36 : 10;
   for (dn = 0; *sp; sp++)
@@ -4348,7 +4370,7 @@
 
       if (digit >= (unsigned) base)
 	{
-	  gmp_free (dp);
+	  gmp_free (dp, sn);
 	  r->_mp_size = 0;
 	  return -1;
 	}
@@ -4358,7 +4380,7 @@
 
   if (!dn)
     {
-      gmp_free (dp);



More information about the gmp-commit mailing list