Skip to content

Commit a2754b7

Browse files
Adoption after merge main, review addressed
1 parent 89cd750 commit a2754b7

File tree

2 files changed

+28
-25
lines changed

2 files changed

+28
-25
lines changed

Include/internal/pycore_stackref.h

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -50,28 +50,29 @@ extern "C" {
5050
CPython refcounting operations on it!
5151
*/
5252

53-
54-
#if !defined(Py_GIL_DISABLED) && defined(Py_STACKREF_DEBUG)
55-
5653
#define Py_INT_TAG 3
5754
#define Py_TAG_INVALID 2
5855
#define Py_TAG_REFCNT 1
5956
#define Py_TAG_BITS 3
6057

58+
#define Py_TAGGED_SHIFT 2
59+
60+
#if !defined(Py_GIL_DISABLED) && defined(Py_STACKREF_DEBUG)
61+
6162
PyAPI_FUNC(PyObject *) _Py_stackref_get_object(_PyStackRef ref);
6263
PyAPI_FUNC(PyObject *) _Py_stackref_close(_PyStackRef ref, const char *filename, int linenumber);
6364
PyAPI_FUNC(_PyStackRef) _Py_stackref_create(PyObject *obj, uint16_t flags, const char *filename, int linenumber);
6465
PyAPI_FUNC(void) _Py_stackref_record_borrow(_PyStackRef ref, const char *filename, int linenumber);
6566
extern void _Py_stackref_associate(PyInterpreterState *interp, PyObject *obj, _PyStackRef ref);
6667

6768
static const _PyStackRef PyStackRef_NULL = { .index = 0 };
68-
static const _PyStackRef PyStackRef_ERROR = { .index = 4 };
69+
static const _PyStackRef PyStackRef_ERROR = { .index = (1 << Py_TAGGED_SHIFT) };
6970

70-
#define PyStackRef_None ((_PyStackRef){ .index = 8 } )
71-
#define PyStackRef_False ((_PyStackRef){ .index = 12 })
72-
#define PyStackRef_True ((_PyStackRef){ .index = 16 })
71+
#define PyStackRef_None ((_PyStackRef){ .index = (2 << Py_TAGGED_SHIFT) } )
72+
#define PyStackRef_False ((_PyStackRef){ .index = (3 << Py_TAGGED_SHIFT) })
73+
#define PyStackRef_True ((_PyStackRef){ .index = (4 << Py_TAGGED_SHIFT) })
7374

74-
#define INITIAL_STACKREF_INDEX 20
75+
#define INITIAL_STACKREF_INDEX (5 << Py_TAGGED_SHIFT)
7576

7677
static inline _PyStackRef
7778
PyStackRef_Wrap(void *ptr)
@@ -111,7 +112,13 @@ PyStackRef_IsNull(_PyStackRef ref)
111112
static inline bool
112113
PyStackRef_IsError(_PyStackRef ref)
113114
{
114-
return ref.index == 4;
115+
return ref.index == (1 << Py_TAGGED_SHIFT);
116+
}
117+
118+
static inline bool
119+
PyStackRef_IsMalformed(_PyStackRef ref)
120+
{
121+
return (ref.index & Py_TAG_BITS) == Py_TAG_INVALID;
115122
}
116123

117124
static inline bool
@@ -315,6 +322,7 @@ _PyStackRef_MakeHeapSafe(_PyStackRef ref, const char *filename, int linenumber)
315322
static inline _PyStackRef
316323
_PyStackRef_FromPyObjectNewMortal(PyObject *obj, const char *filename, int linenumber)
317324
{
325+
assert(obj != NULL);
318326
assert(!_Py_IsStaticImmortal(obj));
319327
Py_XINCREF(obj);
320328
return _Py_stackref_create(obj, 0, filename, linenumber);
@@ -337,11 +345,6 @@ PyStackRef_IsNullOrInt(_PyStackRef ref);
337345

338346
#else
339347

340-
#define Py_INT_TAG 3
341-
#define Py_TAG_INVALID 2
342-
#define Py_TAG_REFCNT 1
343-
#define Py_TAG_BITS 3
344-
345348
static const _PyStackRef PyStackRef_ERROR = { .bits = Py_TAG_INVALID };
346349

347350
/* Wrap a pointer in a stack ref.
@@ -399,25 +402,25 @@ PyStackRef_IsTaggedInt(_PyStackRef i)
399402
static inline _PyStackRef
400403
PyStackRef_TagInt(intptr_t i)
401404
{
402-
assert(Py_ARITHMETIC_RIGHT_SHIFT(intptr_t, (i << 2), 2) == i);
403-
return (_PyStackRef){ .bits = ((((uintptr_t)i) << 2) | Py_INT_TAG) };
405+
assert(Py_ARITHMETIC_RIGHT_SHIFT(intptr_t, (i << Py_TAGGED_SHIFT), Py_TAGGED_SHIFT) == i);
406+
return (_PyStackRef){ .bits = ((((uintptr_t)i) << Py_TAGGED_SHIFT) | Py_INT_TAG) };
404407
}
405408

406409
static inline intptr_t
407410
PyStackRef_UntagInt(_PyStackRef i)
408411
{
409412
assert(PyStackRef_IsTaggedInt(i));
410413
intptr_t val = (intptr_t)i.bits;
411-
return Py_ARITHMETIC_RIGHT_SHIFT(intptr_t, val, 2);
414+
return Py_ARITHMETIC_RIGHT_SHIFT(intptr_t, val, Py_TAGGED_SHIFT);
412415
}
413416

414417

415418
static inline _PyStackRef
416419
PyStackRef_IncrementTaggedIntNoOverflow(_PyStackRef ref)
417420
{
418421
assert((ref.bits & Py_TAG_BITS) == Py_INT_TAG); // Is tagged int
419-
assert((ref.bits & (~Py_TAG_BITS)) != (INT_MAX & (~Py_TAG_BITS))); // Isn't about to overflow
420-
return (_PyStackRef){ .bits = ref.bits + 4 };
422+
assert((ref.bits & (~Py_TAG_BITS)) != (INTPTR_MAX & (~Py_TAG_BITS))); // Isn't about to overflow
423+
return (_PyStackRef){ .bits = ref.bits + (1 << Py_TAGGED_SHIFT) };
421424
}
422425

423426
#define PyStackRef_IsDeferredOrTaggedInt(ref) (((ref).bits & Py_TAG_REFCNT) != 0)

Python/stackrefs.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ _Py_stackref_create(PyObject *obj, uint16_t flags, const char *filename, int lin
116116
}
117117
PyInterpreterState *interp = PyInterpreterState_Get();
118118
uint64_t new_id = interp->next_stackref;
119-
interp->next_stackref = new_id + 4;
119+
interp->next_stackref = new_id + (1 << Py_TAGGED_SHIFT);
120120
TableEntry *entry = make_table_entry(obj, filename, linenumber);
121121
if (entry == NULL) {
122122
Py_FatalError("No memory left for stackref debug table");
@@ -197,16 +197,16 @@ _Py_stackref_report_leaks(PyInterpreterState *interp)
197197

198198
_PyStackRef PyStackRef_TagInt(intptr_t i)
199199
{
200-
assert(Py_ARITHMETIC_RIGHT_SHIFT(intptr_t, (i << 2), 2) == i);
201-
return (_PyStackRef){ .index = (i << 2) | Py_INT_TAG };
200+
assert(Py_ARITHMETIC_RIGHT_SHIFT(intptr_t, (i << Py_TAGGED_SHIFT), Py_TAGGED_SHIFT) == i);
201+
return (_PyStackRef){ .index = (i << Py_TAGGED_SHIFT) | Py_INT_TAG };
202202
}
203203

204204
intptr_t
205205
PyStackRef_UntagInt(_PyStackRef i)
206206
{
207207
assert(PyStackRef_IsTaggedInt(i));
208208
intptr_t val = (intptr_t)i.index;
209-
return Py_ARITHMETIC_RIGHT_SHIFT(intptr_t, val, 2);
209+
return Py_ARITHMETIC_RIGHT_SHIFT(intptr_t, val, Py_TAGGED_SHIFT);
210210
}
211211

212212
bool
@@ -219,8 +219,8 @@ _PyStackRef
219219
PyStackRef_IncrementTaggedIntNoOverflow(_PyStackRef ref)
220220
{
221221
assert(PyStackRef_IsTaggedInt(ref));
222-
assert((ref.index & (~Py_TAG_BITS)) != (INT_MAX & (~Py_TAG_BITS))); // Isn't about to overflow
223-
return (_PyStackRef){ .index = ref.index + 4 };
222+
assert((ref.index & (~Py_TAG_BITS)) != (INTPTR_MAX & (~Py_TAG_BITS))); // Isn't about to overflow
223+
return (_PyStackRef){ .index = ref.index + (1 << Py_TAGGED_SHIFT) };
224224
}
225225

226226

0 commit comments

Comments
 (0)