https://github.com/python/cpython/commit/c646846c1e8f60e52b636b68bfd0df5e84229098
commit: c646846c1e8f60e52b636b68bfd0df5e84229098
branch: main
author: Sergey B Kirpichev <skirpic...@gmail.com>
committer: corona10 <donghee.n...@gmail.com>
date: 2025-06-13T22:32:26+09:00
summary:

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

files:
M Include/internal/pycore_freelist_state.h
M Objects/complexobject.c
M Objects/object.c

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 */
diff --git a/Objects/object.c b/Objects/object.c
index 9fe61ba7f1593a..eff3a9862129a2 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -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);
     }

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: arch...@mail-archive.com

Reply via email to