gh-126703: Add freelist for PyComplexObject's (gh-135233)

This commit is contained in:
Sergey B Kirpichev 2025-06-13 16:32:26 +03:00 committed by GitHub
parent eed827ed09
commit c646846c1e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 25 additions and 6 deletions

View file

@ -16,6 +16,7 @@ extern "C" {
# define Py_dicts_MAXFREELIST 80
# define Py_dictkeys_MAXFREELIST 80
# define Py_floats_MAXFREELIST 100
# define Py_complexes_MAXFREELIST 100
# define Py_ints_MAXFREELIST 100
# define Py_slices_MAXFREELIST 1
# define Py_ranges_MAXFREELIST 6
@ -43,6 +44,7 @@ struct _Py_freelist {
struct _Py_freelists {
struct _Py_freelist floats;
struct _Py_freelist complexes;
struct _Py_freelist ints;
struct _Py_freelist tuples[PyTuple_MAXSAVESIZE];
struct _Py_freelist lists;

View file

@ -1,4 +1,3 @@
/* Complex object implementation */
/* Borrows heavily from floatobject.c */
@ -9,6 +8,7 @@
#include "pycore_call.h" // _PyObject_CallNoArgs()
#include "pycore_complexobject.h" // _PyComplex_FormatAdvancedWriter()
#include "pycore_floatobject.h" // _Py_convert_int_to_double()
#include "pycore_freelist.h" // _Py_FREELIST_FREE(), _Py_FREELIST_POP()
#include "pycore_long.h" // _PyLong_GetZero()
#include "pycore_object.h" // _PyObject_Init()
#include "pycore_pymath.h" // _Py_ADJUST_ERANGE2()
@ -410,16 +410,32 @@ complex_subtype_from_c_complex(PyTypeObject *type, Py_complex cval)
PyObject *
PyComplex_FromCComplex(Py_complex cval)
{
/* Inline PyObject_New */
PyComplexObject *op = PyObject_Malloc(sizeof(PyComplexObject));
PyComplexObject *op = _Py_FREELIST_POP(PyComplexObject, complexes);
if (op == NULL) {
return PyErr_NoMemory();
/* Inline PyObject_New */
op = PyObject_Malloc(sizeof(PyComplexObject));
if (op == NULL) {
return PyErr_NoMemory();
}
_PyObject_Init((PyObject*)op, &PyComplex_Type);
}
_PyObject_Init((PyObject*)op, &PyComplex_Type);
op->cval = cval;
return (PyObject *) op;
}
static void
complex_dealloc(PyObject *op)
{
assert(PyComplex_Check(op));
if (PyComplex_CheckExact(op)) {
_Py_FREELIST_FREE(complexes, op, PyObject_Free);
}
else {
Py_TYPE(op)->tp_free(op);
}
}
static PyObject *
complex_subtype_from_doubles(PyTypeObject *type, double real, double imag)
{
@ -1383,7 +1399,7 @@ PyTypeObject PyComplex_Type = {
"complex",
sizeof(PyComplexObject),
0,
0, /* tp_dealloc */
complex_dealloc, /* tp_dealloc */
0, /* tp_vectorcall_offset */
0, /* tp_getattr */
0, /* tp_setattr */

View file

@ -925,6 +925,7 @@ _PyObject_ClearFreeLists(struct _Py_freelists *freelists, int is_finalization)
// In the free-threaded build, freelists are per-PyThreadState and cleared in PyThreadState_Clear()
// In the default build, freelists are per-interpreter and cleared in finalize_interp_types()
clear_freelist(&freelists->floats, is_finalization, free_object);
clear_freelist(&freelists->complexes, is_finalization, free_object);
for (Py_ssize_t i = 0; i < PyTuple_MAXSAVESIZE; i++) {
clear_freelist(&freelists->tuples[i], is_finalization, free_object);
}