mirror of https://github.com/python/cpython
bpo-33418: Add tp_clear for function object (GH-8058)
Without tp_clear, GC can't break cyclic reference. It will cause memory leak when cyclic reference is created intentionally.
This commit is contained in:
parent
d8cba5d16f
commit
3c452404ae
|
@ -0,0 +1,2 @@
|
|||
Fix potential memory leak in function object when it creates reference
|
||||
cycle.
|
|
@ -523,23 +523,31 @@ func_new_impl(PyTypeObject *type, PyCodeObject *code, PyObject *globals,
|
|||
return (PyObject *)newfunc;
|
||||
}
|
||||
|
||||
static int
|
||||
func_clear(PyFunctionObject *op)
|
||||
{
|
||||
Py_CLEAR(op->func_code);
|
||||
Py_CLEAR(op->func_globals);
|
||||
Py_CLEAR(op->func_module);
|
||||
Py_CLEAR(op->func_name);
|
||||
Py_CLEAR(op->func_defaults);
|
||||
Py_CLEAR(op->func_kwdefaults);
|
||||
Py_CLEAR(op->func_doc);
|
||||
Py_CLEAR(op->func_dict);
|
||||
Py_CLEAR(op->func_closure);
|
||||
Py_CLEAR(op->func_annotations);
|
||||
Py_CLEAR(op->func_qualname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
func_dealloc(PyFunctionObject *op)
|
||||
{
|
||||
_PyObject_GC_UNTRACK(op);
|
||||
if (op->func_weakreflist != NULL)
|
||||
if (op->func_weakreflist != NULL) {
|
||||
PyObject_ClearWeakRefs((PyObject *) op);
|
||||
Py_DECREF(op->func_code);
|
||||
Py_DECREF(op->func_globals);
|
||||
Py_XDECREF(op->func_module);
|
||||
Py_DECREF(op->func_name);
|
||||
Py_XDECREF(op->func_defaults);
|
||||
Py_XDECREF(op->func_kwdefaults);
|
||||
Py_XDECREF(op->func_doc);
|
||||
Py_XDECREF(op->func_dict);
|
||||
Py_XDECREF(op->func_closure);
|
||||
Py_XDECREF(op->func_annotations);
|
||||
Py_XDECREF(op->func_qualname);
|
||||
}
|
||||
(void)func_clear(op);
|
||||
PyObject_GC_Del(op);
|
||||
}
|
||||
|
||||
|
@ -612,7 +620,7 @@ PyTypeObject PyFunction_Type = {
|
|||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
|
||||
func_new__doc__, /* tp_doc */
|
||||
(traverseproc)func_traverse, /* tp_traverse */
|
||||
0, /* tp_clear */
|
||||
(inquiry)func_clear, /* tp_clear */
|
||||
0, /* tp_richcompare */
|
||||
offsetof(PyFunctionObject, func_weakreflist), /* tp_weaklistoffset */
|
||||
0, /* tp_iter */
|
||||
|
|
Loading…
Reference in New Issue