diff --git a/gmp.c b/gmp.c index 0e4737e0..1214a26e 100644 --- a/gmp.c +++ b/gmp.c @@ -7,21 +7,24 @@ #include #include -#if !defined(PYPY_VERSION) -# define MAX_CACHE_SIZE 100 -#else -# define MAX_CACHE_SIZE 0 +#define ON_CPYTHON 1 +#if defined(PYPY_VERSION) || defined(GRAALVM_PYTHON) +# undef ON_CPYTHON #endif -#define MAX_CACHED_SIZEOF 256 + +#ifdef ON_CPYTHON +# define MAX_FREELIST_SIZE 100 +# define MAX_FREELIST_SIZEOF 256 typedef struct { - MPZ_Object *gmp_cache[MAX_CACHE_SIZE + 1]; - size_t gmp_cache_size; + MPZ_Object *freelist[MAX_FREELIST_SIZE + 1]; + size_t freelist_size; } gmp_global; _Thread_local gmp_global global = { - .gmp_cache_size = 0, + .freelist_size = 0, }; +#endif uint8_t bits_per_digit; Py_hash_t pyhash_modulus; @@ -31,12 +34,14 @@ MPZ_new(void) { MPZ_Object *res; - if (global.gmp_cache_size) { - res = global.gmp_cache[--global.gmp_cache_size]; +#ifdef ON_CPYTHON + if (global.freelist_size) { + res = global.freelist[--global.freelist_size]; (void)zz_set(0, &res->z); - Py_XINCREF((PyObject *)res); + Py_INCREF((PyObject *)res); } else { +#endif res = PyObject_New(MPZ_Object, &MPZ_Type); if (!res) { return NULL; /* LCOV_EXCL_LINE */ @@ -44,7 +49,9 @@ MPZ_new(void) if (zz_init(&res->z)) { return (MPZ_Object *)PyErr_NoMemory(); /* LCOV_EXCL_LINE */ } +#ifdef ON_CPYTHON } +#endif res->hash_cache = -1; return res; } @@ -644,13 +651,15 @@ dealloc(PyObject *self) { MPZ_Object *u = (MPZ_Object *)self; - if (global.gmp_cache_size < MAX_CACHE_SIZE - && zz_sizeof(&u->z) <= MAX_CACHED_SIZEOF +#ifdef ON_CPYTHON + if (global.freelist_size < MAX_FREELIST_SIZE + && zz_sizeof(&u->z) <= MAX_FREELIST_SIZEOF && MPZ_CheckExact(self)) { - global.gmp_cache[global.gmp_cache_size++] = u; + global.freelist[global.freelist_size++] = u; } else { +#endif freefunc tp_free; if (MPZ_CheckExact(self)) { @@ -661,7 +670,9 @@ dealloc(PyObject *self) } zz_clear(&u->z); tp_free(self); +#ifdef ON_CPYTHON } +#endif } static PyObject * @@ -2611,19 +2622,6 @@ gmp__mpmath_create(PyObject *self, PyObject *const *args, Py_ssize_t nargs) return Py_BuildValue("(bNNK)", negative, man, iexp, bc); } -static PyObject * -gmp__free_cache(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args)) -{ - while (global.gmp_cache_size) { - MPZ_Object *u = global.gmp_cache[--global.gmp_cache_size]; - PyObject *self = (PyObject *)u; - - zz_clear(&u->z); - PyObject_Free(self); - } - Py_RETURN_NONE; -} - static PyMethodDef gmp_functions[] = { {"gcd", (PyCFunction)gmp_gcd, METH_FASTCALL, ("gcd($module, /, *integers)\n--\n\n" @@ -2656,8 +2654,6 @@ static PyMethodDef gmp_functions[] = { {"_mpmath_create", (PyCFunction)gmp__mpmath_create, METH_FASTCALL, ("_mpmath_create($module, man, exp, prec=0, rnd='d', /)\n--\n\n" "Helper function for mpmath.")}, - {"_free_cache", gmp__free_cache, METH_NOARGS, - "_free_cache($module)\n--\n\nFree mpz's cache."}, {NULL} /* sentinel */ }; diff --git a/tests/test_mpz.py b/tests/test_mpz.py index ab89ca49..146987a6 100644 --- a/tests/test_mpz.py +++ b/tests/test_mpz.py @@ -8,7 +8,6 @@ import sys import warnings from concurrent.futures import ThreadPoolExecutor -from subprocess import run import pytest from gmp import mpz @@ -1093,10 +1092,3 @@ def test_int_api(): continue mz_sig = inspect.signature(mz) assert m_sig == mz_sig - - -def test_mpz_clear(): - # for coverage (test module cleanup) - res = run([sys.executable, "-c", - "import gmp; a = gmp.mpz(1); del a; gmp._free_cache()"]) - assert res.returncode == 0