summaryrefslogtreecommitdiffstats
path: root/Include/internal/pycore_stackref.h
diff options
context:
space:
mode:
authorSam Gross <colesbury@gmail.com>2024-11-22 17:55:33 (GMT)
committerGitHub <noreply@github.com>2024-11-22 17:55:33 (GMT)
commit4759ba6eec9f0b36b24b8eb7e7b120d471c67e82 (patch)
treeccadc7b0918507133e2f4ec4abff6d517f2b618e /Include/internal/pycore_stackref.h
parent8214e0f709010a0e1fa06dc2ce004b5f6103cc6b (diff)
downloadcpython-4759ba6eec9f0b36b24b8eb7e7b120d471c67e82.zip
cpython-4759ba6eec9f0b36b24b8eb7e7b120d471c67e82.tar.gz
cpython-4759ba6eec9f0b36b24b8eb7e7b120d471c67e82.tar.bz2
gh-127022: Simplify `PyStackRef_FromPyObjectSteal` (#127024)
This gets rid of the immortal check in `PyStackRef_FromPyObjectSteal()`. Overall, this improves performance about 2% in the free threading build. This also renames `PyStackRef_Is()` to `PyStackRef_IsExactly()` because the macro requires that the tag bits of the arguments match, which is only true in certain special cases.
Diffstat (limited to 'Include/internal/pycore_stackref.h')
-rw-r--r--Include/internal/pycore_stackref.h14
1 files changed, 10 insertions, 4 deletions
diff --git a/Include/internal/pycore_stackref.h b/Include/internal/pycore_stackref.h
index 588e57f..90a3118 100644
--- a/Include/internal/pycore_stackref.h
+++ b/Include/internal/pycore_stackref.h
@@ -99,8 +99,7 @@ _PyStackRef_FromPyObjectSteal(PyObject *obj)
assert(obj != NULL);
// Make sure we don't take an already tagged value.
assert(((uintptr_t)obj & Py_TAG_BITS) == 0);
- unsigned int tag = _Py_IsImmortal(obj) ? (Py_TAG_DEFERRED) : Py_TAG_PTR;
- return ((_PyStackRef){.bits = ((uintptr_t)(obj)) | tag});
+ return (_PyStackRef){ .bits = (uintptr_t)obj };
}
# define PyStackRef_FromPyObjectSteal(obj) _PyStackRef_FromPyObjectSteal(_PyObject_CAST(obj))
@@ -190,9 +189,16 @@ static const _PyStackRef PyStackRef_NULL = { .bits = 0 };
#endif // Py_GIL_DISABLED
-// Note: this is a macro because MSVC (Windows) has trouble inlining it.
+// Check if a stackref is exactly the same as another stackref, including the
+// the deferred bit. This can only be used safely if you know that the deferred
+// bits of `a` and `b` match.
+#define PyStackRef_IsExactly(a, b) \
+ (assert(((a).bits & Py_TAG_BITS) == ((b).bits & Py_TAG_BITS)), (a).bits == (b).bits)
-#define PyStackRef_Is(a, b) ((a).bits == (b).bits)
+// Checks that mask out the deferred bit in the free threading build.
+#define PyStackRef_IsNone(ref) (PyStackRef_AsPyObjectBorrow(ref) == Py_None)
+#define PyStackRef_IsTrue(ref) (PyStackRef_AsPyObjectBorrow(ref) == Py_True)
+#define PyStackRef_IsFalse(ref) (PyStackRef_AsPyObjectBorrow(ref) == Py_False)
// Converts a PyStackRef back to a PyObject *, converting the
// stackref to a new reference.