Skip to content

Commit adaaa26

Browse files
committed
Tagged ints are heap safe
1 parent 605022a commit adaaa26

File tree

1 file changed

+5
-11
lines changed

1 file changed

+5
-11
lines changed

Include/internal/pycore_stackref.h

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -443,14 +443,14 @@ PyStackRef_AsStrongReference(_PyStackRef stackref)
443443
/* References to immortal objects always have their tag bit set to Py_TAG_REFCNT
444444
* as they can (must) have their reclamation deferred */
445445

446-
#define Py_TAG_BITS 1
446+
#define Py_TAG_BITS 3
447447
#define Py_TAG_REFCNT 1
448448
#if _Py_IMMORTAL_FLAGS != Py_TAG_REFCNT
449449
# error "_Py_IMMORTAL_FLAGS != Py_TAG_REFCNT"
450450
#endif
451451

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

455455
#define PyStackRef_NULL_BITS Py_TAG_REFCNT
456456
static const _PyStackRef PyStackRef_NULL = { .bits = PyStackRef_NULL_BITS };
@@ -530,7 +530,7 @@ PyStackRef_FromPyObjectSteal(PyObject *obj)
530530
{
531531
assert(obj != NULL);
532532
#if SIZEOF_VOID_P > 4
533-
unsigned int tag = obj->ob_flags & Py_TAG_BITS;
533+
unsigned int tag = obj->ob_flags & Py_TAG_REFCNT;
534534
#else
535535
unsigned int tag = _Py_IsImmortal(obj) ? Py_TAG_REFCNT : 0;
536536
#endif
@@ -549,12 +549,6 @@ PyStackRef_FromPyObjectStealMortal(PyObject *obj)
549549
return ref;
550550
}
551551

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

613607
static inline _PyStackRef
@@ -682,7 +676,7 @@ PyStackRef_XCLOSE(_PyStackRef ref)
682676

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

685-
#define PyStackRef_Is(a, b) (((a).bits & (~Py_TAG_BITS)) == ((b).bits & (~Py_TAG_BITS)))
679+
#define PyStackRef_Is(a, b) (((a).bits & (~Py_TAG_REFCNT)) == ((b).bits & (~Py_TAG_REFCNT)))
686680

687681

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

0 commit comments

Comments
 (0)