bpo-37340: remove free_list for bound method objects (GH-14232)
This commit is contained in:
parent
76b645124b
commit
3e54b57531
|
@ -99,11 +99,6 @@ typedef struct {
|
|||
|
||||
PyAPI_FUNC(int) PyCFunction_ClearFreeList(void);
|
||||
|
||||
#ifndef Py_LIMITED_API
|
||||
PyAPI_FUNC(void) _PyCFunction_DebugMallocStats(FILE *out);
|
||||
PyAPI_FUNC(void) _PyMethod_DebugMallocStats(FILE *out);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
Removed object cache (``free_list``) for bound method objects. Temporary
|
||||
bound method objects are less used than before thanks to the ``LOAD_METHOD``
|
||||
opcode and the ``_PyObject_VectorcallMethod`` C API.
|
|
@ -8,15 +8,6 @@
|
|||
|
||||
#define TP_DESCR_GET(t) ((t)->tp_descr_get)
|
||||
|
||||
/* Free list for method objects to safe malloc/free overhead
|
||||
* The im_self element is used to chain the elements.
|
||||
*/
|
||||
static PyMethodObject *free_list;
|
||||
static int numfree = 0;
|
||||
#ifndef PyMethod_MAXFREELIST
|
||||
#define PyMethod_MAXFREELIST 256
|
||||
#endif
|
||||
|
||||
_Py_IDENTIFIER(__name__);
|
||||
_Py_IDENTIFIER(__qualname__);
|
||||
|
||||
|
@ -103,21 +94,13 @@ method_vectorcall(PyObject *method, PyObject *const *args,
|
|||
PyObject *
|
||||
PyMethod_New(PyObject *func, PyObject *self)
|
||||
{
|
||||
PyMethodObject *im;
|
||||
if (self == NULL) {
|
||||
PyErr_BadInternalCall();
|
||||
return NULL;
|
||||
}
|
||||
im = free_list;
|
||||
if (im != NULL) {
|
||||
free_list = (PyMethodObject *)(im->im_self);
|
||||
(void)PyObject_INIT(im, &PyMethod_Type);
|
||||
numfree--;
|
||||
}
|
||||
else {
|
||||
im = PyObject_GC_New(PyMethodObject, &PyMethod_Type);
|
||||
if (im == NULL)
|
||||
return NULL;
|
||||
PyMethodObject *im = PyObject_GC_New(PyMethodObject, &PyMethod_Type);
|
||||
if (im == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
im->im_weakreflist = NULL;
|
||||
Py_INCREF(func);
|
||||
|
@ -252,14 +235,7 @@ method_dealloc(PyMethodObject *im)
|
|||
PyObject_ClearWeakRefs((PyObject *)im);
|
||||
Py_DECREF(im->im_func);
|
||||
Py_XDECREF(im->im_self);
|
||||
if (numfree < PyMethod_MAXFREELIST) {
|
||||
im->im_self = (PyObject *)free_list;
|
||||
free_list = im;
|
||||
numfree++;
|
||||
}
|
||||
else {
|
||||
PyObject_GC_Del(im);
|
||||
}
|
||||
PyObject_GC_Del(im);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
|
@ -395,16 +371,7 @@ PyTypeObject PyMethod_Type = {
|
|||
int
|
||||
PyMethod_ClearFreeList(void)
|
||||
{
|
||||
int freelist_size = numfree;
|
||||
|
||||
while (free_list) {
|
||||
PyMethodObject *im = free_list;
|
||||
free_list = (PyMethodObject *)(im->im_self);
|
||||
PyObject_GC_Del(im);
|
||||
numfree--;
|
||||
}
|
||||
assert(numfree == 0);
|
||||
return freelist_size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -413,15 +380,6 @@ PyMethod_Fini(void)
|
|||
(void)PyMethod_ClearFreeList();
|
||||
}
|
||||
|
||||
/* Print summary info about the state of the optimized allocator */
|
||||
void
|
||||
_PyMethod_DebugMallocStats(FILE *out)
|
||||
{
|
||||
_PyDebugAllocatorStats(out,
|
||||
"free PyMethodObject",
|
||||
numfree, sizeof(PyMethodObject));
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
* instance method
|
||||
*/
|
||||
|
|
|
@ -7,15 +7,6 @@
|
|||
#include "pycore_pystate.h"
|
||||
#include "structmember.h"
|
||||
|
||||
/* Free list for method objects to safe malloc/free overhead
|
||||
* The m_self element is used to chain the objects.
|
||||
*/
|
||||
static PyCFunctionObject *free_list = NULL;
|
||||
static int numfree = 0;
|
||||
#ifndef PyCFunction_MAXFREELIST
|
||||
#define PyCFunction_MAXFREELIST 256
|
||||
#endif
|
||||
|
||||
/* undefine macro trampoline to PyCFunction_NewEx */
|
||||
#undef PyCFunction_New
|
||||
|
||||
|
@ -66,17 +57,10 @@ PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
PyCFunctionObject *op;
|
||||
op = free_list;
|
||||
if (op != NULL) {
|
||||
free_list = (PyCFunctionObject *)(op->m_self);
|
||||
(void)PyObject_INIT(op, &PyCFunction_Type);
|
||||
numfree--;
|
||||
}
|
||||
else {
|
||||
op = PyObject_GC_New(PyCFunctionObject, &PyCFunction_Type);
|
||||
if (op == NULL)
|
||||
return NULL;
|
||||
PyCFunctionObject *op =
|
||||
PyObject_GC_New(PyCFunctionObject, &PyCFunction_Type);
|
||||
if (op == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
op->m_weakreflist = NULL;
|
||||
op->m_ml = ml;
|
||||
|
@ -130,14 +114,7 @@ meth_dealloc(PyCFunctionObject *m)
|
|||
}
|
||||
Py_XDECREF(m->m_self);
|
||||
Py_XDECREF(m->m_module);
|
||||
if (numfree < PyCFunction_MAXFREELIST) {
|
||||
m->m_self = (PyObject *)free_list;
|
||||
free_list = m;
|
||||
numfree++;
|
||||
}
|
||||
else {
|
||||
PyObject_GC_Del(m);
|
||||
}
|
||||
PyObject_GC_Del(m);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
|
@ -338,16 +315,7 @@ PyTypeObject PyCFunction_Type = {
|
|||
int
|
||||
PyCFunction_ClearFreeList(void)
|
||||
{
|
||||
int freelist_size = numfree;
|
||||
|
||||
while (free_list) {
|
||||
PyCFunctionObject *v = free_list;
|
||||
free_list = (PyCFunctionObject *)(v->m_self);
|
||||
PyObject_GC_Del(v);
|
||||
numfree--;
|
||||
}
|
||||
assert(numfree == 0);
|
||||
return freelist_size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -356,15 +324,6 @@ PyCFunction_Fini(void)
|
|||
(void)PyCFunction_ClearFreeList();
|
||||
}
|
||||
|
||||
/* Print summary info about the state of the optimized allocator */
|
||||
void
|
||||
_PyCFunction_DebugMallocStats(FILE *out)
|
||||
{
|
||||
_PyDebugAllocatorStats(out,
|
||||
"free PyCFunctionObject",
|
||||
numfree, sizeof(PyCFunctionObject));
|
||||
}
|
||||
|
||||
|
||||
/* Vectorcall functions for each of the PyCFunction calling conventions,
|
||||
* except for METH_VARARGS (possibly combined with METH_KEYWORDS) which
|
||||
|
|
|
@ -1959,12 +1959,10 @@ Py_ssize_t (*_Py_abstract_hack)(PyObject *) = PyObject_Size;
|
|||
void
|
||||
_PyObject_DebugTypeStats(FILE *out)
|
||||
{
|
||||
_PyCFunction_DebugMallocStats(out);
|
||||
_PyDict_DebugMallocStats(out);
|
||||
_PyFloat_DebugMallocStats(out);
|
||||
_PyFrame_DebugMallocStats(out);
|
||||
_PyList_DebugMallocStats(out);
|
||||
_PyMethod_DebugMallocStats(out);
|
||||
_PyTuple_DebugMallocStats(out);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue