Commit 3c452404 authored by INADA Naoki's avatar INADA Naoki Committed by GitHub

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.
parent d8cba5d1
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, ...@@ -523,23 +523,31 @@ func_new_impl(PyTypeObject *type, PyCodeObject *code, PyObject *globals,
return (PyObject *)newfunc; 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 static void
func_dealloc(PyFunctionObject *op) func_dealloc(PyFunctionObject *op)
{ {
_PyObject_GC_UNTRACK(op); _PyObject_GC_UNTRACK(op);
if (op->func_weakreflist != NULL) if (op->func_weakreflist != NULL) {
PyObject_ClearWeakRefs((PyObject *) op); PyObject_ClearWeakRefs((PyObject *) op);
Py_DECREF(op->func_code); }
Py_DECREF(op->func_globals); (void)func_clear(op);
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);
PyObject_GC_Del(op); PyObject_GC_Del(op);
} }
...@@ -612,7 +620,7 @@ PyTypeObject PyFunction_Type = { ...@@ -612,7 +620,7 @@ PyTypeObject PyFunction_Type = {
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
func_new__doc__, /* tp_doc */ func_new__doc__, /* tp_doc */
(traverseproc)func_traverse, /* tp_traverse */ (traverseproc)func_traverse, /* tp_traverse */
0, /* tp_clear */ (inquiry)func_clear, /* tp_clear */
0, /* tp_richcompare */ 0, /* tp_richcompare */
offsetof(PyFunctionObject, func_weakreflist), /* tp_weaklistoffset */ offsetof(PyFunctionObject, func_weakreflist), /* tp_weaklistoffset */
0, /* tp_iter */ 0, /* tp_iter */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment