Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 29f6dc6

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

File tree

1 file changed

+7
-13
lines changed
Filter options

1 file changed

+7
-13
lines changed

‎Include/internal/pycore_stackref.h

Copy file name to clipboardExpand all lines: Include/internal/pycore_stackref.h
+7-13Lines 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)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.