8000 GH-133932: Tagged ints are heap safe (GH-134244) · python/cpython@29f6dc6 · GitHub
[go: up one dir, main page]

Skip to content

Commit 29f6dc6

Browse files
authored
GH-133932: Tagged ints are heap safe (GH-134244)
1 parent 1f0a294 commit 29f6dc6

File tree

1 file changed

+7
-13
lines changed

1 file changed

+7
-13
lines changed

Include/internal/pycore_stackref.h

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ PyStackRef_IsNullOrInt(_PyStackRef ref);
238238
#else
239239

240240
#define Py_INT_TAG 3
241+
#define Py_TAG_REFCNT 1
241242

242243
static inline bool
243244
PyStackRef_IsTaggedInt(_PyStackRef i)
@@ -263,7 +264,7 @@ PyStackRef_UntagInt(_PyStackRef i)
263264

264265
#ifdef Py_GIL_DISABLED
265266

266-
#define Py_TAG_DEFERRED (1)
267+
#define Py_TAG_DEFERRED Py_TAG_REFCNT
267268

268269
#define Py_TAG_PTR ((uintptr_t)0)
269270
#define Py_TAG_BITS ((uintptr_t)1)
@@ -441,14 +442,13 @@ PyStackRef_AsStrongReference(_PyStackRef stackref)
441442
/* References to immortal objects always have their tag bit set to Py_TAG_REFCNT
442443
* as they can (must) have their reclamation deferred */
443444

444-
#define Py_TAG_BITS 1
445-
#define Py_TAG_REFCNT 1
445+
#define Py_TAG_BITS 3
446446
#if _Py_IMMORTAL_FLAGS != Py_TAG_REFCNT
447447
# error "_Py_IMMORTAL_FLAGS != Py_TAG_REFCNT"
448448
#endif
449449

450450
#define BITS_TO_PTR(REF) ((PyObject *)((REF).bits))
451-
#define BITS_TO_PTR_MASKED(REF) ((PyObject *)(((REF).bits) & (~Py_TAG_BITS)))
451+
#define BITS_TO_PTR_MASKED(REF) ((PyObject *)(((REF).bits) & (~Py_TAG_REFCNT)))
452452

453453
#define PyStackRef_NULL_BITS Py_TAG_REFCNT
454454
static const _PyStackRef PyStackRef_NULL = { .bits = PyStackRef_NULL_BITS };
@@ -528,7 +528,7 @@ PyStackRef_FromPyObjectSteal(PyObject *obj)
528528
{
529529
assert(obj != NULL);
530530
#if SIZEOF_VOID_P > 4
531-
unsigned int tag = obj->ob_flags & Py_TAG_BITS;
531+
unsigned int tag = obj->ob_flags & Py_TAG_REFCNT;
532532
#else
533533
unsigned int tag = _Py_IsImmortal(obj) ? Py_TAG_REFCNT : 0;
534534
#endif
@@ -547,12 +547,6 @@ PyStackRef_FromPyObjectStealMortal(PyObject *obj)
547547
return ref;
548548
}
549549

550-
// Check if a stackref is exactly the same as another stackref, including the
551-
// the deferred bit. This can only be used safely if you know that the deferred
552-
// bits of `a` and `b` match.
553-
#define PyStackRef_IsExactly(a, b) \
554-
(assert(((a).bits & Py_TAG_BITS) == ((b).bits & Py_TAG_BITS)), (a).bits == (b).bits)
555-
556550
static inline _PyStackRef
557551
_PyStackRef_FromPyObjectNew(PyObject *obj)
558552
{
@@ -604,7 +598,7 @@ PyStackRef_DUP(_PyStackRef ref)
604598
static inline bool
605599
PyStackRef_IsHeapSafe(_PyStackRef ref)
606600
{
607-
return (ref.bits & Py_TAG_BITS) == 0 || ref.bits == PyStackRef_NULL_BITS || _Py_IsImmortal(BITS_TO_PTR_MASKED(ref));
601+
return (ref.bits & Py_TAG_BITS) != Py_TAG_REFCNT || ref.bits == PyStackRef_NULL_BITS || _Py_IsImmortal(BITS_TO_PTR_MASKED(ref));
608602
}
609603

610604
static inline _PyStackRef
@@ -679,7 +673,7 @@ PyStackRef_XCLOSE(_PyStackRef ref)
679673

680674
// Note: this is a macro because MSVC (Windows) has trouble inlining it.
681675

682-
#define PyStackRef_Is(a, b) (((a).bits & (~Py_TAG_BITS)) == ((b).bits & (~Py_TAG_BITS)))
676+
#define PyStackRef_Is(a, b) (((a).bits & (~Py_TAG_REFCNT)) == ((b).bits & (~Py_TAG_REFCNT)))
683677

684678

685679
#endif // !defined(Py_GIL_DISABLED) && defined(Py_STACKREF_DEBUG)

0 commit comments

Comments
 (0)
0