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]

Reply via email to