https://github.com/python/cpython/commit/ce841a9a02b9a28367b52b7b0c9606b5bdeacada
commit: ce841a9a02b9a28367b52b7b0c9606b5bdeacada
branch: main
author: Victor Stinner <[email protected]>
committer: vstinner <[email protected]>
date: 2026-11-03T18:30:48+01:00
summary:

gh-160147: Inline PyObject_IS_GC() in _PyObject_GC_MAY_BE_TRACKED() (#161189)

Move _PyType_IS_GC() and _PyObject_IS_GC() from pycore_object.h to
pycore_gc.h. Replace PyObject_IS_GC() call with _PyObject_IS_GC() in
_PyObject_GC_MAY_BE_TRACKED().

Help the compiler to inline _PyObject_IS_GC() code in
_PyObject_GC_MAY_BE_TRACKED(), especially when LTO is not used.

files:
M Include/internal/pycore_gc.h
M Include/internal/pycore_object.h

diff --git a/Include/internal/pycore_gc.h b/Include/internal/pycore_gc.h
index 84cbb56a919215..33f94c0a0ad0b0 100644
--- a/Include/internal/pycore_gc.h
+++ b/Include/internal/pycore_gc.h
@@ -80,10 +80,26 @@ static inline int _PyObject_GC_IS_TRACKED(PyObject *op) {
 }
 #define _PyObject_GC_IS_TRACKED(op) 
_PyObject_GC_IS_TRACKED(_Py_CAST(PyObject*, op))
 
+// Fast inlined version of PyType_IS_GC()
+static inline int
+_PyType_IS_GC(PyTypeObject *type)
+{
+    return (type->tp_flags & Py_TPFLAGS_HAVE_GC) != 0;
+}
+
+// Fast inlined version of PyObject_IS_GC()
+static inline int
+_PyObject_IS_GC(PyObject *obj)
+{
+    PyTypeObject *type = Py_TYPE(obj);
+    return (_PyType_IS_GC(type)
+            && (type->tp_is_gc == NULL || type->tp_is_gc(obj)));
+}
+
 /* True if the object may be tracked by the GC in the future, or already is.
    This can be useful to implement some optimizations. */
 static inline int _PyObject_GC_MAY_BE_TRACKED(PyObject *obj) {
-    if (!PyObject_IS_GC(obj)) {
+    if (!_PyObject_IS_GC(obj)) {
         return 0;
     }
     if (PyTuple_CheckExact(obj)) {
diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h
index dbc0ebf994fd1e..f6a71fe0417601 100644
--- a/Include/internal/pycore_object.h
+++ b/Include/internal/pycore_object.h
@@ -816,18 +816,6 @@ _PyObject_GET_WEAKREFS_LISTPTR_FROM_OFFSET(PyObject *op)
     return (PyWeakReference **)((char *)op + offset);
 }
 
-// Fast inlined version of PyType_IS_GC()
-#define _PyType_IS_GC(t) _PyType_HasFeature((t), Py_TPFLAGS_HAVE_GC)
-
-// Fast inlined version of PyObject_IS_GC()
-static inline int
-_PyObject_IS_GC(PyObject *obj)
-{
-    PyTypeObject *type = Py_TYPE(obj);
-    return (_PyType_IS_GC(type)
-            && (type->tp_is_gc == NULL || type->tp_is_gc(obj)));
-}
-
 // Fast inlined version of PyObject_Hash(). Dictionaries are very
 // likely to include string keys (class and instance attributes,
 // json, ...) so we include a fast path for strings.

_______________________________________________
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