From f031f945d2ec8e6467dbd40e70915d65b34928d4 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Sat, 7 Jun 2025 13:26:44 +0300 Subject: [PATCH] gh-126703: add freelist for PyComplexObject's --- Include/internal/pycore_freelist_state.h | 2 ++ Objects/complexobject.c | 28 +++++++++++++++++++----- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/Include/internal/pycore_freelist_state.h b/Include/internal/pycore_freelist_state.h index 4828dfd948f70a..59beb92f3f7b9c 100644 --- a/Include/internal/pycore_freelist_state.h +++ b/Include/internal/pycore_freelist_state.h @@ -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; diff --git a/Objects/complexobject.c b/Objects/complexobject.c index c2dd320ae73988..b66ebe131ae605 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -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 */