https://github.com/python/cpython/commit/9112daed900c3314fa522043fc64ddbb2ecd4ca5
commit: 9112daed900c3314fa522043fc64ddbb2ecd4ca5
branch: main
author: Donghee Na <[email protected]>
committer: corona10 <[email protected]>
date: 2026-10-05T21:18:22+09:00
summary:
gh-130706: Add a fast path to _Py_Dealloc() for non-GC objects. (gh-158645)
files:
A
Misc/NEWS.d/next/Core_and_Builtins/2026-10-03-19-11-03.gh-issue-130706.01-O6U.rst
M Objects/object.c
diff --git
a/Misc/NEWS.d/next/Core_and_Builtins/2026-10-03-19-11-03.gh-issue-130706.01-O6U.rst
b/Misc/NEWS.d/next/Core_and_Builtins/2026-10-03-19-11-03.gh-issue-130706.01-O6U.rst
new file mode 100644
index 00000000000000..3351513347daec
--- /dev/null
+++
b/Misc/NEWS.d/next/Core_and_Builtins/2026-10-03-19-11-03.gh-issue-130706.01-O6U.rst
@@ -0,0 +1,2 @@
+Add a fast path to ``_Py_Dealloc()`` for non-GC objects. Patch by Donghee
+Na.
diff --git a/Objects/object.c b/Objects/object.c
index c7aeba0cee22c6..e334097d31c432 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -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)
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]