Skip to content

Commit ff39e3f

Browse files
authored
gh-126703: Add freelist for PyMethodObject (#128594)
1 parent 5ace717 commit ff39e3f

File tree

4 files changed

+12
-3
lines changed

4 files changed

+12
-3
lines changed

Include/internal/pycore_freelist_state.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ extern "C" {
2222
# define Py_futureiters_MAXFREELIST 255
2323
# define Py_object_stack_chunks_MAXFREELIST 4
2424
# define Py_unicode_writers_MAXFREELIST 1
25+
# define Py_pymethodobjects_MAXFREELIST 20
2526

2627
// A generic freelist of either PyObjects or other data structures.
2728
struct _Py_freelist {
@@ -48,6 +49,7 @@ struct _Py_freelists {
4849
struct _Py_freelist futureiters;
4950
struct _Py_freelist object_stack_chunks;
5051
struct _Py_freelist unicode_writers;
52+
struct _Py_freelist pymethodobjects;
5153
};
5254

5355
#ifdef __cplusplus
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Improve performance of class methods by using a freelist.

Objects/classobject.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "Python.h"
44
#include "pycore_call.h" // _PyObject_VectorcallTstate()
55
#include "pycore_ceval.h" // _PyEval_GetBuiltin()
6+
#include "pycore_freelist.h"
67
#include "pycore_object.h"
78
#include "pycore_pyerrors.h"
89
#include "pycore_pystate.h" // _PyThreadState_GET()
@@ -112,9 +113,12 @@ PyMethod_New(PyObject *func, PyObject *self)
112113
PyErr_BadInternalCall();
113114
return NULL;
114115
}
115-
PyMethodObject *im = PyObject_GC_New(PyMethodObject, &PyMethod_Type);
116+
PyMethodObject *im = _Py_FREELIST_POP(PyMethodObject, pymethodobjects);
116117
if (im == NULL) {
117-
return NULL;
118+
im = PyObject_GC_New(PyMethodObject, &PyMethod_Type);
119+
if (im == NULL) {
120+
return NULL;
121+
}
118122
}
119123
im->im_weakreflist = NULL;
120124
im->im_func = Py_NewRef(func);
@@ -245,7 +249,8 @@ method_dealloc(PyObject *self)
245249
PyObject_ClearWeakRefs((PyObject *)im);
246250
Py_DECREF(im->im_func);
247251
Py_XDECREF(im->im_self);
248-
PyObject_GC_Del(im);
252+
assert(Py_IS_TYPE(self, &PyMethod_Type));
253+
_Py_FREELIST_FREE(pymethodobjects, (PyObject *)im, PyObject_GC_Del);
249254
}
250255

251256
static PyObject *

Objects/object.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -937,6 +937,7 @@ _PyObject_ClearFreeLists(struct _Py_freelists *freelists, int is_finalization)
937937
}
938938
clear_freelist(&freelists->unicode_writers, is_finalization, PyMem_Free);
939939
clear_freelist(&freelists->ints, is_finalization, free_object);
940+
clear_freelist(&freelists->pymethodobjects, is_finalization, free_object);
940941
}
941942

942943
/*

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy