gh-130706: Add a fast path to _Py_Dealloc() for non-GC objects. (gh-158645)

This commit is contained in:
Donghee Na authored and GitHub committed 2026-10-05 21:18:22 +09:00
1 parent fc3cd8e3f5
commit 9112daed90
2 files changed
+26 -2

No files matched your search

@@ -0,0 +1,2 @@
Add a fast path to ``_Py_Dealloc()`` for non-GC objects. Patch by Donghee
Na.
+24 -2
View File
@@ -3306,8 +3306,8 @@ next" object in the chain to 0. This can easily lead to stack overflows.
To avoid that, if the C stack is nearing its limit, instead of calling
dealloc on the object, it is added to a queue to be freed later when the
stack is shallower */
void
_Py_Dealloc(PyObject *op)
static Py_NO_INLINE void
py_dealloc(PyObject *op)
{
PyTypeObject *type = Py_TYPE(op);
unsigned long gc_flag = type->tp_flags & Py_TPFLAGS_HAVE_GC;
@@ -3372,6 +3372,28 @@ _Py_Dealloc(PyObject *op)
}
}
/*
* gh-130706: Keep the GC/reftracer path in the non-inlined py_dealloc().
* Inlining it makes the compiler save callee-saved registers at entry,
* so the non-GC objects path would have unnecessary register spills.
*/
void
_Py_Dealloc(PyObject *op)
{
#if !defined(Py_DEBUG) && !defined(Py_TRACE_REFS)
// gh-130706: Avoid unnecessary register spills for non-GC objects.
PyTypeObject *type = Py_TYPE(op);
if (_PyRuntime.ref_tracer.tracer_func == NULL
&& !(type->tp_flags & Py_TPFLAGS_HAVE_GC))
{
type->tp_dealloc(op);
return;
}
#endif
// GC objects (trashcan), reftracer set, or debug builds.
py_dealloc(op);
}
PyObject **
PyObject_GET_WEAKREFS_LISTPTR(PyObject *op)