[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