diff options
author | Sam Gross <colesbury@gmail.com> | 2024-11-22 17:55:33 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-11-22 17:55:33 (GMT) |
commit | 4759ba6eec9f0b36b24b8eb7e7b120d471c67e82 (patch) | |
tree | ccadc7b0918507133e2f4ec4abff6d517f2b618e /Include/internal/pycore_stackref.h | |
parent | 8214e0f709010a0e1fa06dc2ce004b5f6103cc6b (diff) | |
download | cpython-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.h | 14 |
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. |