Skip to content

Commit eb18574

Browse files
authored
GH-120024: Tidy up pycore_stackref.h, splitting into GIL and free-threading sections (GH-125095)
1 parent 440632a commit eb18574

File tree

1 file changed

+65
-101
lines changed

1 file changed

+65
-101
lines changed

Include/internal/pycore_stackref.h

+65-101
Original file line numberDiff line numberDiff line change
@@ -60,54 +60,22 @@ typedef union _PyStackRef {
6060
#define Py_TAG_BITS ((uintptr_t)1)
6161

6262
#ifdef Py_GIL_DISABLED
63-
static const _PyStackRef PyStackRef_NULL = { .bits = 0 | Py_TAG_DEFERRED};
64-
#else
65-
static const _PyStackRef PyStackRef_NULL = { .bits = 0 };
66-
#endif
6763

64+
static const _PyStackRef PyStackRef_NULL = { .bits = Py_TAG_DEFERRED};
6865
#define PyStackRef_IsNull(stackref) ((stackref).bits == PyStackRef_NULL.bits)
66+
#define PyStackRef_True ((_PyStackRef){.bits = ((uintptr_t)&_Py_TrueStruct) | Py_TAG_DEFERRED })
67+
#define PyStackRef_False ((_PyStackRef){.bits = ((uintptr_t)&_Py_FalseStruct) | Py_TAG_DEFERRED })
68+
#define PyStackRef_None ((_PyStackRef){.bits = ((uintptr_t)&_Py_NoneStruct) | Py_TAG_DEFERRED })
6969

70-
71-
#ifdef Py_GIL_DISABLED
72-
# define PyStackRef_True ((_PyStackRef){.bits = ((uintptr_t)&_Py_TrueStruct) | Py_TAG_DEFERRED })
73-
#else
74-
# define PyStackRef_True ((_PyStackRef){.bits = ((uintptr_t)&_Py_TrueStruct) })
75-
#endif
76-
77-
#ifdef Py_GIL_DISABLED
78-
# define PyStackRef_False ((_PyStackRef){.bits = ((uintptr_t)&_Py_FalseStruct) | Py_TAG_DEFERRED })
79-
#else
80-
# define PyStackRef_False ((_PyStackRef){.bits = ((uintptr_t)&_Py_FalseStruct) })
81-
#endif
82-
83-
#ifdef Py_GIL_DISABLED
84-
# define PyStackRef_None ((_PyStackRef){.bits = ((uintptr_t)&_Py_NoneStruct) | Py_TAG_DEFERRED })
85-
#else
86-
# define PyStackRef_None ((_PyStackRef){.bits = ((uintptr_t)&_Py_NoneStruct) })
87-
#endif
88-
89-
// Note: the following are all macros because MSVC (Windows) has trouble inlining them.
90-
91-
#define PyStackRef_Is(a, b) ((a).bits == (b).bits)
92-
93-
#define PyStackRef_IsDeferred(ref) (((ref).bits & Py_TAG_BITS) == Py_TAG_DEFERRED)
94-
95-
96-
#ifdef Py_GIL_DISABLED
97-
// Gets a PyObject * from a _PyStackRef
9870
static inline PyObject *
9971
PyStackRef_AsPyObjectBorrow(_PyStackRef stackref)
10072
{
10173
PyObject *cleared = ((PyObject *)((stackref).bits & (~Py_TAG_BITS)));
10274
return cleared;
10375
}
104-
#else
105-
# define PyStackRef_AsPyObjectBorrow(stackref) ((PyObject *)(stackref).bits)
106-
#endif
10776

108-
// Converts a PyStackRef back to a PyObject *, stealing the
109-
// PyStackRef.
110-
#ifdef Py_GIL_DISABLED
77+
#define PyStackRef_IsDeferred(ref) (((ref).bits & Py_TAG_BITS) == Py_TAG_DEFERRED)
78+
11179
static inline PyObject *
11280
PyStackRef_AsPyObjectSteal(_PyStackRef stackref)
11381
{
@@ -117,18 +85,7 @@ PyStackRef_AsPyObjectSteal(_PyStackRef stackref)
11785
}
11886
return PyStackRef_AsPyObjectBorrow(stackref);
11987
}
120-
#else
121-
# define PyStackRef_AsPyObjectSteal(stackref) PyStackRef_AsPyObjectBorrow(stackref)
122-
#endif
123-
124-
// Converts a PyStackRef back to a PyObject *, converting the
125-
// stackref to a new reference.
126-
#define PyStackRef_AsPyObjectNew(stackref) Py_NewRef(PyStackRef_AsPyObjectBorrow(stackref))
127-
128-
#define PyStackRef_TYPE(stackref) Py_TYPE(PyStackRef_AsPyObjectBorrow(stackref))
12988

130-
// Converts a PyObject * to a PyStackRef, stealing the reference
131-
#ifdef Py_GIL_DISABLED
13289
static inline _PyStackRef
13390
_PyStackRef_FromPyObjectSteal(PyObject *obj)
13491
{
@@ -139,13 +96,7 @@ _PyStackRef_FromPyObjectSteal(PyObject *obj)
13996
return ((_PyStackRef){.bits = ((uintptr_t)(obj)) | tag});
14097
}
14198
# define PyStackRef_FromPyObjectSteal(obj) _PyStackRef_FromPyObjectSteal(_PyObject_CAST(obj))
142-
#else
143-
# define PyStackRef_FromPyObjectSteal(obj) ((_PyStackRef){.bits = ((uintptr_t)(obj))})
144-
#endif
145-
14699

147-
// Converts a PyObject * to a PyStackRef, with a new reference
148-
#ifdef Py_GIL_DISABLED
149100
static inline _PyStackRef
150101
PyStackRef_FromPyObjectNew(PyObject *obj)
151102
{
@@ -159,13 +110,8 @@ PyStackRef_FromPyObjectNew(PyObject *obj)
159110
return (_PyStackRef){ .bits = (uintptr_t)(Py_NewRef(obj)) | Py_TAG_PTR };
160111
}
161112
}
162-
# define PyStackRef_FromPyObjectNew(obj) PyStackRef_FromPyObjectNew(_PyObject_CAST(obj))
163-
#else
164-
# define PyStackRef_FromPyObjectNew(obj) ((_PyStackRef){ .bits = (uintptr_t)(Py_NewRef(obj)) })
165-
#endif
113+
#define PyStackRef_FromPyObjectNew(obj) PyStackRef_FromPyObjectNew(_PyObject_CAST(obj))
166114

167-
#ifdef Py_GIL_DISABLED
168-
// Same as PyStackRef_FromPyObjectNew but only for immortal objects.
169115
static inline _PyStackRef
170116
PyStackRef_FromPyObjectImmortal(PyObject *obj)
171117
{
@@ -175,45 +121,17 @@ PyStackRef_FromPyObjectImmortal(PyObject *obj)
175121
assert(_Py_IsImmortal(obj));
176122
return (_PyStackRef){ .bits = (uintptr_t)obj | Py_TAG_DEFERRED };
177123
}
178-
# define PyStackRef_FromPyObjectImmortal(obj) PyStackRef_FromPyObjectImmortal(_PyObject_CAST(obj))
179-
#else
180-
# define PyStackRef_FromPyObjectImmortal(obj) ((_PyStackRef){ .bits = (uintptr_t)(obj) })
181-
#endif
182-
183-
184-
#define PyStackRef_CLEAR(op) \
185-
do { \
186-
_PyStackRef *_tmp_op_ptr = &(op); \
187-
_PyStackRef _tmp_old_op = (*_tmp_op_ptr); \
188-
if (!PyStackRef_IsNull(_tmp_old_op)) { \
189-
*_tmp_op_ptr = PyStackRef_NULL; \
190-
PyStackRef_CLOSE(_tmp_old_op); \
191-
} \
192-
} while (0)
124+
#define PyStackRef_FromPyObjectImmortal(obj) PyStackRef_FromPyObjectImmortal(_PyObject_CAST(obj))
193125

194-
#ifdef Py_GIL_DISABLED
195-
# define PyStackRef_CLOSE(REF) \
126+
#define PyStackRef_CLOSE(REF) \
196127
do { \
197128
_PyStackRef _close_tmp = (REF); \
198129
assert(!PyStackRef_IsNull(_close_tmp)); \
199130
if (!PyStackRef_IsDeferred(_close_tmp)) { \
200131
Py_DECREF(PyStackRef_AsPyObjectBorrow(_close_tmp)); \
201132
} \
202133
} while (0)
203-
#else
204-
# define PyStackRef_CLOSE(stackref) Py_DECREF(PyStackRef_AsPyObjectBorrow(stackref))
205-
#endif
206134

207-
#define PyStackRef_XCLOSE(stackref) \
208-
do { \
209-
_PyStackRef _tmp = (stackref); \
210-
if (!PyStackRef_IsNull(_tmp)) { \
211-
PyStackRef_CLOSE(_tmp); \
212-
} \
213-
} while (0);
214-
215-
216-
#ifdef Py_GIL_DISABLED
217135
static inline _PyStackRef
218136
PyStackRef_DUP(_PyStackRef stackref)
219137
{
@@ -227,9 +145,6 @@ PyStackRef_DUP(_PyStackRef stackref)
227145
Py_INCREF(PyStackRef_AsPyObjectBorrow(stackref));
228146
return stackref;
229147
}
230-
#else
231-
# define PyStackRef_DUP(stackref) PyStackRef_FromPyObjectSteal(Py_NewRef(PyStackRef_AsPyObjectBorrow(stackref)))
232-
#endif
233148

234149
// Convert a possibly deferred reference to a strong reference.
235150
static inline _PyStackRef
@@ -238,13 +153,62 @@ PyStackRef_AsStrongReference(_PyStackRef stackref)
238153
return PyStackRef_FromPyObjectSteal(PyStackRef_AsPyObjectSteal(stackref));
239154
}
240155

241-
static inline void
242-
_PyObjectStack_FromStackRefStack(PyObject **dst, const _PyStackRef *src, size_t length)
243-
{
244-
for (size_t i = 0; i < length; i++) {
245-
dst[i] = PyStackRef_AsPyObjectBorrow(src[i]);
246-
}
247-
}
156+
157+
#else // Py_GIL_DISABLED
158+
159+
// With GIL
160+
static const _PyStackRef PyStackRef_NULL = { .bits = 0 };
161+
#define PyStackRef_IsNull(stackref) ((stackref).bits == 0)
162+
#define PyStackRef_True ((_PyStackRef){.bits = (uintptr_t)&_Py_TrueStruct })
163+
#define PyStackRef_False ((_PyStackRef){.bits = ((uintptr_t)&_Py_FalseStruct) })
164+
#define PyStackRef_None ((_PyStackRef){.bits = ((uintptr_t)&_Py_NoneStruct) })
165+
166+
#define PyStackRef_AsPyObjectBorrow(stackref) ((PyObject *)(stackref).bits)
167+
168+
#define PyStackRef_AsPyObjectSteal(stackref) PyStackRef_AsPyObjectBorrow(stackref)
169+
170+
#define PyStackRef_FromPyObjectSteal(obj) ((_PyStackRef){.bits = ((uintptr_t)(obj))})
171+
172+
#define PyStackRef_FromPyObjectNew(obj) ((_PyStackRef){ .bits = (uintptr_t)(Py_NewRef(obj)) })
173+
174+
#define PyStackRef_FromPyObjectImmortal(obj) ((_PyStackRef){ .bits = (uintptr_t)(obj) })
175+
176+
#define PyStackRef_CLOSE(stackref) Py_DECREF(PyStackRef_AsPyObjectBorrow(stackref))
177+
178+
#define PyStackRef_DUP(stackref) PyStackRef_FromPyObjectSteal(Py_NewRef(PyStackRef_AsPyObjectBorrow(stackref)))
179+
180+
181+
#endif // Py_GIL_DISABLED
182+
183+
// Note: this is a macro because MSVC (Windows) has trouble inlining it.
184+
185+
#define PyStackRef_Is(a, b) ((a).bits == (b).bits)
186+
187+
// Converts a PyStackRef back to a PyObject *, converting the
188+
// stackref to a new reference.
189+
#define PyStackRef_AsPyObjectNew(stackref) Py_NewRef(PyStackRef_AsPyObjectBorrow(stackref))
190+
191+
#define PyStackRef_TYPE(stackref) Py_TYPE(PyStackRef_AsPyObjectBorrow(stackref))
192+
193+
#define PyStackRef_CLEAR(op) \
194+
do { \
195+
_PyStackRef *_tmp_op_ptr = &(op); \
196+
_PyStackRef _tmp_old_op = (*_tmp_op_ptr); \
197+
if (!PyStackRef_IsNull(_tmp_old_op)) { \
198+
*_tmp_op_ptr = PyStackRef_NULL; \
199+
PyStackRef_CLOSE(_tmp_old_op); \
200+
} \
201+
} while (0)
202+
203+
#define PyStackRef_XCLOSE(stackref) \
204+
do { \
205+
_PyStackRef _tmp = (stackref); \
206+
if (!PyStackRef_IsNull(_tmp)) { \
207+
PyStackRef_CLOSE(_tmp); \
208+
} \
209+
} while (0);
210+
211+
248212

249213
// StackRef type checks
250214

0 commit comments

Comments
 (0)