mirror of
https://github.com/python/cpython.git
synced 2025-07-07 19:35:27 +00:00
[3.14] GH-133932: Tagged ints are heap safe (GH-134244) (#134494)
Co-authored-by: Mark Shannon <mark@hotpy.org>
This commit is contained in:
parent
46a7981f45
commit
41d1683e05
1 changed files with 7 additions and 13 deletions
|
@ -239,6 +239,7 @@ PyStackRef_IsNullOrInt(_PyStackRef ref);
|
|||
#else
|
||||
|
||||
#define Py_INT_TAG 3
|
||||
#define Py_TAG_REFCNT 1
|
||||
|
||||
static inline bool
|
||||
PyStackRef_IsTaggedInt(_PyStackRef i)
|
||||
|
@ -264,7 +265,7 @@ PyStackRef_UntagInt(_PyStackRef i)
|
|||
|
||||
#ifdef Py_GIL_DISABLED
|
||||
|
||||
#define Py_TAG_DEFERRED (1)
|
||||
#define Py_TAG_DEFERRED Py_TAG_REFCNT
|
||||
|
||||
#define Py_TAG_PTR ((uintptr_t)0)
|
||||
#define Py_TAG_BITS ((uintptr_t)1)
|
||||
|
@ -442,14 +443,13 @@ PyStackRef_AsStrongReference(_PyStackRef stackref)
|
|||
/* References to immortal objects always have their tag bit set to Py_TAG_REFCNT
|
||||
* as they can (must) have their reclamation deferred */
|
||||
|
||||
#define Py_TAG_BITS 1
|
||||
#define Py_TAG_REFCNT 1
|
||||
#define Py_TAG_BITS 3
|
||||
#if _Py_IMMORTAL_FLAGS != Py_TAG_REFCNT
|
||||
# error "_Py_IMMORTAL_FLAGS != Py_TAG_REFCNT"
|
||||
#endif
|
||||
|
||||
#define BITS_TO_PTR(REF) ((PyObject *)((REF).bits))
|
||||
#define BITS_TO_PTR_MASKED(REF) ((PyObject *)(((REF).bits) & (~Py_TAG_BITS)))
|
||||
#define BITS_TO_PTR_MASKED(REF) ((PyObject *)(((REF).bits) & (~Py_TAG_REFCNT)))
|
||||
|
||||
#define PyStackRef_NULL_BITS Py_TAG_REFCNT
|
||||
static const _PyStackRef PyStackRef_NULL = { .bits = PyStackRef_NULL_BITS };
|
||||
|
@ -529,7 +529,7 @@ PyStackRef_FromPyObjectSteal(PyObject *obj)
|
|||
{
|
||||
assert(obj != NULL);
|
||||
#if SIZEOF_VOID_P > 4
|
||||
unsigned int tag = obj->ob_flags & Py_TAG_BITS;
|
||||
unsigned int tag = obj->ob_flags & Py_TAG_REFCNT;
|
||||
#else
|
||||
unsigned int tag = _Py_IsImmortal(obj) ? Py_TAG_REFCNT : 0;
|
||||
#endif
|
||||
|
@ -548,12 +548,6 @@ PyStackRef_FromPyObjectStealMortal(PyObject *obj)
|
|||
return ref;
|
||||
}
|
||||
|
||||
// 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)
|
||||
|
||||
static inline _PyStackRef
|
||||
_PyStackRef_FromPyObjectNew(PyObject *obj)
|
||||
{
|
||||
|
@ -606,7 +600,7 @@ PyStackRef_DUP(_PyStackRef ref)
|
|||
static inline bool
|
||||
PyStackRef_IsHeapSafe(_PyStackRef ref)
|
||||
{
|
||||
return (ref.bits & Py_TAG_BITS) == 0 || ref.bits == PyStackRef_NULL_BITS || _Py_IsImmortal(BITS_TO_PTR_MASKED(ref));
|
||||
return (ref.bits & Py_TAG_BITS) != Py_TAG_REFCNT || ref.bits == PyStackRef_NULL_BITS || _Py_IsImmortal(BITS_TO_PTR_MASKED(ref));
|
||||
}
|
||||
|
||||
static inline _PyStackRef
|
||||
|
@ -681,7 +675,7 @@ PyStackRef_XCLOSE(_PyStackRef ref)
|
|||
|
||||
// Note: this is a macro because MSVC (Windows) has trouble inlining it.
|
||||
|
||||
#define PyStackRef_Is(a, b) (((a).bits & (~Py_TAG_BITS)) == ((b).bits & (~Py_TAG_BITS)))
|
||||
#define PyStackRef_Is(a, b) (((a).bits & (~Py_TAG_REFCNT)) == ((b).bits & (~Py_TAG_REFCNT)))
|
||||
|
||||
|
||||
#endif // !defined(Py_GIL_DISABLED) && defined(Py_STACKREF_DEBUG)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue