Skip to content

Commit f03f745

Browse files
committed
Make making heap safe more efficient
1 parent 7e6deef commit f03f745

File tree

2 files changed

+19
-12
lines changed

2 files changed

+19
-12
lines changed

Include/internal/pycore_stackref.h

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -195,25 +195,32 @@ PyStackRef_AsStrongReference(_PyStackRef stackref)
195195

196196
// With GIL
197197

198-
#define Py_TAG_BITS 1
198+
#define Py_TAG_BITS 3
199199
#define Py_TAG_REFCNT 1
200+
#define Py_TAG_IMMORTAL 3
200201
#define BITS_TO_PTR(REF) ((PyObject *)((REF).bits))
201202
#define BITS_TO_PTR_MASKED(REF) ((PyObject *)(((REF).bits) & (~Py_TAG_BITS)))
202203

203-
#define PyStackRef_NULL_BITS Py_TAG_REFCNT
204+
#define PyStackRef_NULL_BITS Py_TAG_IMMORTAL
204205
static const _PyStackRef PyStackRef_NULL = { .bits = PyStackRef_NULL_BITS };
205206

206207
#define PyStackRef_IsNull(ref) ((ref).bits == PyStackRef_NULL_BITS)
207-
#define PyStackRef_True ((_PyStackRef){.bits = ((uintptr_t)&_Py_TrueStruct) | Py_TAG_REFCNT })
208-
#define PyStackRef_False ((_PyStackRef){.bits = ((uintptr_t)&_Py_FalseStruct) | Py_TAG_REFCNT })
209-
#define PyStackRef_None ((_PyStackRef){.bits = ((uintptr_t)&_Py_NoneStruct) | Py_TAG_REFCNT })
208+
#define PyStackRef_True ((_PyStackRef){.bits = ((uintptr_t)&_Py_TrueStruct) | Py_TAG_IMMORTAL })
209+
#define PyStackRef_False ((_PyStackRef){.bits = ((uintptr_t)&_Py_FalseStruct) | Py_TAG_IMMORTAL })
210+
#define PyStackRef_None ((_PyStackRef){.bits = ((uintptr_t)&_Py_NoneStruct) | Py_TAG_IMMORTAL })
210211

211212
static inline int
212213
PyStackRef_HasCount(_PyStackRef ref)
213214
{
214215
return ref.bits & Py_TAG_REFCNT;
215216
}
216217

218+
static inline int
219+
PyStackRef_HasCountAndMortal(_PyStackRef ref)
220+
{
221+
return (ref.bits & Py_TAG_BITS) == Py_TAG_REFCNT;
222+
}
223+
217224
static inline PyObject *
218225
PyStackRef_AsPyObjectBorrow(_PyStackRef ref)
219226
{
@@ -238,7 +245,7 @@ static inline _PyStackRef
238245
PyStackRef_FromPyObjectSteal(PyObject *obj)
239246
{
240247
assert(obj != NULL);
241-
unsigned int tag = _Py_IsDeferrable(obj) ? Py_TAG_REFCNT : 0;
248+
unsigned int tag = _Py_IsImmortal(obj) ? Py_TAG_IMMORTAL : 0;
242249
_PyStackRef ref = ((_PyStackRef){.bits = ((uintptr_t)(obj)) | tag});
243250
return ref;
244251
}
@@ -289,12 +296,10 @@ PyStackRef_IsHeapSafe(_PyStackRef ref)
289296
static inline _PyStackRef
290297
PyStackRef_HeapSafe(_PyStackRef ref)
291298
{
292-
if (PyStackRef_HasCount(ref)) {
299+
if (PyStackRef_HasCountAndMortal(ref)) {
293300
PyObject *obj = BITS_TO_PTR_MASKED(ref);
294-
if (obj != NULL && !_Py_IsImmortal(obj)) {
295-
Py_INCREF_MORTAL(obj);
296-
ref.bits = (uintptr_t)obj;
297-
}
301+
Py_INCREF_MORTAL(obj);
302+
ref.bits = (uintptr_t)obj;
298303
}
299304
return ref;
300305
}

Include/refcount.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,9 @@ static inline void Py_DECREF_MORTAL(const char *filename, int lineno, PyObject *
377377
_Py_NegativeRefcount(filename, lineno, op);
378378
}
379379
_Py_DECREF_STAT_INC();
380-
_Py_DECREF_DecRefTotal();
380+
if (!_Py_IsImmortal(op)) {
381+
_Py_DECREF_DecRefTotal();
382+
}
381383
if (--op->ob_refcnt == 0) {
382384
_Py_Dealloc(op);
383385
}

0 commit comments

Comments
 (0)