]> granicus.if.org Git - python/commitdiff
bpo-37340: remove free_list for bound method objects (GH-14232)
authorInada Naoki <songofacandy@gmail.com>
Fri, 26 Jul 2019 06:05:50 +0000 (15:05 +0900)
committerGitHub <noreply@github.com>
Fri, 26 Jul 2019 06:05:50 +0000 (15:05 +0900)
Include/methodobject.h
Misc/NEWS.d/next/Core and Builtins/2019-07-25-11-06-57.bpo-37340.5ktLEg.rst [new file with mode: 0644]
Objects/classobject.c
Objects/methodobject.c
Objects/object.c

index ab66b03f7a97dbdb15b456a184c45bde8d0612b0..9f5f7c482c878bad251e10233ac5730c5a848287 100644 (file)
@@ -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
diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-07-25-11-06-57.bpo-37340.5ktLEg.rst b/Misc/NEWS.d/next/Core and Builtins/2019-07-25-11-06-57.bpo-37340.5ktLEg.rst
new file mode 100644 (file)
index 0000000..e61146b
--- /dev/null
@@ -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.
index 46525a737bc9ea1c019ecf6c18d1635a42112e29..40cbeaa9f2aaca7d5cdc1b52a9af16abc537316c 100644 (file)
@@ -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
  */
index 3494f11d80fe75967ce0601b08ab4e1ce1598963..b9977467ac08d546188e14a47197615987d19ae9 100644 (file)
@@ -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
index 585a9748c8467187642faaae2d0426371378a554..ee2050656a04a13ecff341e354def4c087d5ce2b 100644 (file)
@@ -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);
 }