diff --git a/Include/internal/pycore_freelist_state.h b/Include/internal/pycore_freelist_state.h index a1a94c1f2dc880..5b95485a1ae63c 100644 --- a/Include/internal/pycore_freelist_state.h +++ b/Include/internal/pycore_freelist_state.h @@ -16,6 +16,12 @@ extern "C" { # define Py_floats_MAXFREELIST 100 # define Py_ints_MAXFREELIST 100 # define Py_slices_MAXFREELIST 1 +# define Py_pycfunctionobject_MAXFREELIST 40 +# define Py_pycmethodobject_MAXFREELIST 40 +# define Py_ranges_MAXFREELIST 10 +# define Py_range_iters_MAXFREELIST 10 +# define Py_shared_iters_MAXFREELIST 24 +# define Py_class_method_MAXFREELIST 10 # define Py_contexts_MAXFREELIST 255 # define Py_async_gens_MAXFREELIST 80 # define Py_async_gen_asends_MAXFREELIST 80 @@ -42,6 +48,12 @@ struct _Py_freelists { struct _Py_freelist dicts; struct _Py_freelist dictkeys; struct _Py_freelist slices; + struct _Py_freelist pycfunctionobject; + struct _Py_freelist pycmethodobject; + struct _Py_freelist ranges; + struct _Py_freelist range_iters; + struct _Py_freelist shared_iters; + struct _Py_freelist class_method; struct _Py_freelist contexts; struct _Py_freelist async_gens; struct _Py_freelist async_gen_asends; diff --git a/Objects/classobject.c b/Objects/classobject.c index 775894ad5a7166..408fcdab9e25b5 100644 --- a/Objects/classobject.c +++ b/Objects/classobject.c @@ -3,6 +3,7 @@ #include "Python.h" #include "pycore_call.h" // _PyObject_VectorcallTstate() #include "pycore_ceval.h" // _PyEval_GetBuiltin() +#include "pycore_freelist.h" #include "pycore_object.h" #include "pycore_pyerrors.h" #include "pycore_pystate.h" // _PyThreadState_GET() @@ -112,9 +113,13 @@ PyMethod_New(PyObject *func, PyObject *self) PyErr_BadInternalCall(); return NULL; } - PyMethodObject *im = PyObject_GC_New(PyMethodObject, &PyMethod_Type); + + PyMethodObject *im = _Py_FREELIST_POP(PyMethodObject, class_method); if (im == NULL) { - return NULL; + im = PyObject_GC_New(PyMethodObject, &PyMethod_Type); + if (im == NULL) { + return NULL; + } } im->im_weakreflist = NULL; im->im_func = Py_NewRef(func); @@ -245,7 +250,7 @@ method_dealloc(PyObject *self) PyObject_ClearWeakRefs((PyObject *)im); Py_DECREF(im->im_func); Py_XDECREF(im->im_self); - PyObject_GC_Del(im); + _Py_FREELIST_FREE(class_method, (PyObject *)im, PyObject_GC_Del); } static PyObject * diff --git a/Objects/iterobject.c b/Objects/iterobject.c index 135ced9ea1f268..3bd3a26968df5f 100644 --- a/Objects/iterobject.c +++ b/Objects/iterobject.c @@ -4,6 +4,7 @@ #include "pycore_abstract.h" // _PyObject_HasLen() #include "pycore_call.h" // _PyObject_CallNoArgs() #include "pycore_ceval.h" // _PyEval_GetBuiltin() +#include "pycore_freelist.h" // _Py_FREELIST_PUSH(), _Py_FREELIST_POP() #include "pycore_object.h" // _PyObject_GC_TRACK() typedef struct { @@ -21,9 +22,16 @@ PySeqIter_New(PyObject *seq) PyErr_BadInternalCall(); return NULL; } - it = PyObject_GC_New(seqiterobject, &PySeqIter_Type); - if (it == NULL) - return NULL; + + it = _Py_FREELIST_POP(seqiterobject, shared_iters); + if (it == NULL) { + it = PyObject_GC_New(seqiterobject, &PySeqIter_Type); + if (it == NULL) + return NULL; + } + else { + Py_SET_TYPE(it, &PySeqIter_Type); + } it->it_index = 0; it->it_seq = Py_NewRef(seq); _PyObject_GC_TRACK(it); @@ -35,7 +43,8 @@ iter_dealloc(seqiterobject *it) { _PyObject_GC_UNTRACK(it); Py_XDECREF(it->it_seq); - PyObject_GC_Del(it); + assert(sizeof(seqiterobject)==sizeof(_PyListIterObject)); + _Py_FREELIST_FREE(shared_iters, (PyObject *)it, PyObject_GC_Del); } static int diff --git a/Objects/listobject.c b/Objects/listobject.c index bbd53e7de94a31..2db0e4bfc436b5 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -3906,15 +3906,19 @@ PyTypeObject PyListIter_Type = { static PyObject * list_iter(PyObject *seq) { - _PyListIterObject *it; - if (!PyList_Check(seq)) { PyErr_BadInternalCall(); return NULL; } - it = PyObject_GC_New(_PyListIterObject, &PyListIter_Type); - if (it == NULL) - return NULL; + _PyListIterObject *it = _Py_FREELIST_POP(_PyListIterObject, shared_iters); + if (it == NULL) { + it = PyObject_GC_New(_PyListIterObject, &PyListIter_Type); + if (it == NULL) { + return NULL; + } + } else { + Py_SET_TYPE(it, &PyListIter_Type); + } it->it_index = 0; it->it_seq = (PyListObject *)Py_NewRef(seq); _PyObject_GC_TRACK(it); @@ -3927,7 +3931,7 @@ listiter_dealloc(PyObject *self) _PyListIterObject *it = (_PyListIterObject *)self; _PyObject_GC_UNTRACK(it); Py_XDECREF(it->it_seq); - PyObject_GC_Del(it); + _Py_FREELIST_FREE(shared_iters, it, PyObject_GC_Del); } static int diff --git a/Objects/methodobject.c b/Objects/methodobject.c index 345da4607423cf..362b46c9b66b75 100644 --- a/Objects/methodobject.c +++ b/Objects/methodobject.c @@ -4,6 +4,7 @@ #include "Python.h" #include "pycore_call.h" // _Py_CheckFunctionResult() #include "pycore_ceval.h" // _Py_EnterRecursiveCallTstate() +#include "pycore_freelist.h" #include "pycore_object.h" #include "pycore_pyerrors.h" #include "pycore_pystate.h" // _PyThreadState_GET() @@ -85,10 +86,13 @@ PyCMethod_New(PyMethodDef *ml, PyObject *self, PyObject *module, PyTypeObject *c "flag but no class"); return NULL; } - PyCMethodObject *om = PyObject_GC_New(PyCMethodObject, &PyCMethod_Type); - if (om == NULL) { - return NULL; - } + PyCMethodObject *om = _Py_FREELIST_POP(PyCMethodObject, pycmethodobject); + if (om == NULL) { + om = PyObject_GC_New(PyCMethodObject, &PyCMethod_Type); + if (om == NULL) { + return NULL; + } + } om->mm_class = (PyTypeObject*)Py_NewRef(cls); op = (PyCFunctionObject *)om; } else { @@ -98,9 +102,12 @@ PyCMethod_New(PyMethodDef *ml, PyObject *self, PyObject *module, PyTypeObject *c "but no METH_METHOD flag"); return NULL; } - op = PyObject_GC_New(PyCFunctionObject, &PyCFunction_Type); + op = _Py_FREELIST_POP(PyCFunctionObject, pycfunctionobject); if (op == NULL) { - return NULL; + op = PyObject_GC_New(PyCFunctionObject, &PyCFunction_Type); + if (op == NULL) { + return NULL; + } } } @@ -171,7 +178,12 @@ meth_dealloc(PyObject *self) Py_XDECREF(PyCFunction_GET_CLASS(m)); Py_XDECREF(m->m_self); Py_XDECREF(m->m_module); - PyObject_GC_Del(m); + if (m->m_ml->ml_flags & METH_METHOD) { + _Py_FREELIST_FREE(pycmethodobject, m, PyObject_GC_Del); + } + else { + _Py_FREELIST_FREE(pycfunctionobject, m, PyObject_GC_Del); + } Py_TRASHCAN_END; } diff --git a/Objects/object.c b/Objects/object.c index 4c30257ca26938..27088503ba3cd8 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -937,6 +937,12 @@ _PyObject_ClearFreeLists(struct _Py_freelists *freelists, int is_finalization) } clear_freelist(&freelists->unicode_writers, is_finalization, PyMem_Free); clear_freelist(&freelists->ints, is_finalization, free_object); + clear_freelist(&freelists->shared_iters, is_finalization, free_object); + clear_freelist(&freelists->pycfunctionobject, is_finalization, PyObject_GC_Del); + clear_freelist(&freelists->pycmethodobject, is_finalization, PyObject_GC_Del); + clear_freelist(&freelists->ranges, is_finalization, free_object); + clear_freelist(&freelists->range_iters, is_finalization, free_object); + clear_freelist(&freelists->class_method, is_finalization, free_object); } /* diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c index 2942ab624edf72..a64522d19b7ded 100644 --- a/Objects/rangeobject.c +++ b/Objects/rangeobject.c @@ -3,6 +3,7 @@ #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() #include "pycore_ceval.h" // _PyEval_GetBuiltin() +#include "pycore_freelist.h" // _Py_FREELIST_FREE(), _Py_FREELIST_POP() #include "pycore_long.h" // _PyLong_GetZero() #include "pycore_modsupport.h" // _PyArg_NoKwnames() #include "pycore_range.h" @@ -51,16 +52,18 @@ static rangeobject * make_range_object(PyTypeObject *type, PyObject *start, PyObject *stop, PyObject *step) { - rangeobject *obj = NULL; PyObject *length; length = compute_range_length(start, stop, step); if (length == NULL) { return NULL; } - obj = PyObject_New(rangeobject, type); + rangeobject *obj = _Py_FREELIST_POP(rangeobject, ranges); if (obj == NULL) { - Py_DECREF(length); - return NULL; + obj = PyObject_New(rangeobject, type); + if (obj == NULL) { + Py_DECREF(length); + return NULL; + } } obj->start = start; obj->stop = stop; @@ -170,7 +173,7 @@ range_dealloc(rangeobject *r) Py_DECREF(r->stop); Py_DECREF(r->step); Py_DECREF(r->length); - PyObject_Free(r); + _Py_FREELIST_FREE(ranges, r, PyObject_Free); } static unsigned long @@ -880,6 +883,12 @@ rangeiter_setstate(_PyRangeIterObject *r, PyObject *state) Py_RETURN_NONE; } +static void +rangeiter_dealloc(_PyRangeIterObject *r) +{ + _Py_FREELIST_FREE(range_iters, r, PyObject_Free); +} + PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); PyDoc_STRVAR(setstate_doc, "Set state information for unpickling."); @@ -899,7 +908,7 @@ PyTypeObject PyRangeIter_Type = { sizeof(_PyRangeIterObject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ - (destructor)PyObject_Free, /* tp_dealloc */ + (destructor)rangeiter_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ @@ -960,9 +969,15 @@ get_len_of_range(long lo, long hi, long step) static PyObject * fast_range_iter(long start, long stop, long step, long len) { - _PyRangeIterObject *it = PyObject_New(_PyRangeIterObject, &PyRangeIter_Type); - if (it == NULL) - return NULL; + _PyRangeIterObject *it = _Py_FREELIST_POP(_PyRangeIterObject, range_iters); + if (it == NULL) { + it = PyObject_New(_PyRangeIterObject, &PyRangeIter_Type); + if (it == NULL) + return NULL; + } + else { + Py_SET_TYPE(it, &PyRangeIter_Type); + } it->start = start; it->step = step; it->len = len; diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index 49977726eadca9..d2a18f8f7ac11b 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -994,7 +994,8 @@ tupleiter_dealloc(_PyTupleIterObject *it) { _PyObject_GC_UNTRACK(it); Py_XDECREF(it->it_seq); - PyObject_GC_Del(it); + assert(sizeof(_PyTupleIterObject)==sizeof(_PyListIterObject)); + _Py_FREELIST_FREE(shared_iters, it, PyObject_GC_Del); } static int @@ -1122,9 +1123,15 @@ tuple_iter(PyObject *seq) PyErr_BadInternalCall(); return NULL; } - it = PyObject_GC_New(_PyTupleIterObject, &PyTupleIter_Type); - if (it == NULL) - return NULL; + it = _Py_FREELIST_POP(_PyTupleIterObject, shared_iters); + + if (it == NULL) { + it = PyObject_GC_New(_PyTupleIterObject, &PyTupleIter_Type); + if (it == NULL) + return NULL; + } else { + Py_SET_TYPE(it, &PyTupleIter_Type); + } it->it_index = 0; it->it_seq = (PyTupleObject *)Py_NewRef(seq); _PyObject_GC_TRACK(it); 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