mirror of
https://github.com/python/cpython.git
synced 2025-09-27 02:39:58 +00:00
gh-126703: Add freelist for PyMethodObject
(#128594)
This commit is contained in:
parent
5ace71713b
commit
ff39e3ff7b
4 changed files with 12 additions and 3 deletions
|
@ -22,6 +22,7 @@ extern "C" {
|
||||||
# define Py_futureiters_MAXFREELIST 255
|
# define Py_futureiters_MAXFREELIST 255
|
||||||
# define Py_object_stack_chunks_MAXFREELIST 4
|
# define Py_object_stack_chunks_MAXFREELIST 4
|
||||||
# define Py_unicode_writers_MAXFREELIST 1
|
# define Py_unicode_writers_MAXFREELIST 1
|
||||||
|
# define Py_pymethodobjects_MAXFREELIST 20
|
||||||
|
|
||||||
// A generic freelist of either PyObjects or other data structures.
|
// A generic freelist of either PyObjects or other data structures.
|
||||||
struct _Py_freelist {
|
struct _Py_freelist {
|
||||||
|
@ -48,6 +49,7 @@ struct _Py_freelists {
|
||||||
struct _Py_freelist futureiters;
|
struct _Py_freelist futureiters;
|
||||||
struct _Py_freelist object_stack_chunks;
|
struct _Py_freelist object_stack_chunks;
|
||||||
struct _Py_freelist unicode_writers;
|
struct _Py_freelist unicode_writers;
|
||||||
|
struct _Py_freelist pymethodobjects;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Improve performance of class methods by using a freelist.
|
|
@ -3,6 +3,7 @@
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
#include "pycore_call.h" // _PyObject_VectorcallTstate()
|
#include "pycore_call.h" // _PyObject_VectorcallTstate()
|
||||||
#include "pycore_ceval.h" // _PyEval_GetBuiltin()
|
#include "pycore_ceval.h" // _PyEval_GetBuiltin()
|
||||||
|
#include "pycore_freelist.h"
|
||||||
#include "pycore_object.h"
|
#include "pycore_object.h"
|
||||||
#include "pycore_pyerrors.h"
|
#include "pycore_pyerrors.h"
|
||||||
#include "pycore_pystate.h" // _PyThreadState_GET()
|
#include "pycore_pystate.h" // _PyThreadState_GET()
|
||||||
|
@ -112,9 +113,12 @@ PyMethod_New(PyObject *func, PyObject *self)
|
||||||
PyErr_BadInternalCall();
|
PyErr_BadInternalCall();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
PyMethodObject *im = PyObject_GC_New(PyMethodObject, &PyMethod_Type);
|
PyMethodObject *im = _Py_FREELIST_POP(PyMethodObject, pymethodobjects);
|
||||||
if (im == NULL) {
|
if (im == NULL) {
|
||||||
return NULL;
|
im = PyObject_GC_New(PyMethodObject, &PyMethod_Type);
|
||||||
|
if (im == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
im->im_weakreflist = NULL;
|
im->im_weakreflist = NULL;
|
||||||
im->im_func = Py_NewRef(func);
|
im->im_func = Py_NewRef(func);
|
||||||
|
@ -245,7 +249,8 @@ method_dealloc(PyObject *self)
|
||||||
PyObject_ClearWeakRefs((PyObject *)im);
|
PyObject_ClearWeakRefs((PyObject *)im);
|
||||||
Py_DECREF(im->im_func);
|
Py_DECREF(im->im_func);
|
||||||
Py_XDECREF(im->im_self);
|
Py_XDECREF(im->im_self);
|
||||||
PyObject_GC_Del(im);
|
assert(Py_IS_TYPE(self, &PyMethod_Type));
|
||||||
|
_Py_FREELIST_FREE(pymethodobjects, (PyObject *)im, PyObject_GC_Del);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
|
|
@ -937,6 +937,7 @@ _PyObject_ClearFreeLists(struct _Py_freelists *freelists, int is_finalization)
|
||||||
}
|
}
|
||||||
clear_freelist(&freelists->unicode_writers, is_finalization, PyMem_Free);
|
clear_freelist(&freelists->unicode_writers, is_finalization, PyMem_Free);
|
||||||
clear_freelist(&freelists->ints, is_finalization, free_object);
|
clear_freelist(&freelists->ints, is_finalization, free_object);
|
||||||
|
clear_freelist(&freelists->pymethodobjects, is_finalization, free_object);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue