summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2024-10-10 17:19:08 (GMT)
committerGitHub <noreply@github.com>2024-10-10 17:19:08 (GMT)
commitc9014374c50d6ef64786d3e7d9c7e99053d5c9e2 (patch)
tree0aa842abbebaa90dfbafe985f2ab1fb5688ce45f /Objects
parent01fc3b34cc6994bc83b6540da3a8573e79dfbb56 (diff)
downloadcpython-c9014374c50d6ef64786d3e7d9c7e99053d5c9e2.zip
cpython-c9014374c50d6ef64786d3e7d9c7e99053d5c9e2.tar.gz
cpython-c9014374c50d6ef64786d3e7d9c7e99053d5c9e2.tar.bz2
GH-125174: Make immortal objects more robust, following design from PEP 683 (GH-125251)
Diffstat (limited to 'Objects')
-rw-r--r--Objects/bytesobject.c6
-rw-r--r--Objects/dictobject.c10
-rw-r--r--Objects/object.c2
-rw-r--r--Objects/structseq.c2
-rw-r--r--Objects/typeobject.c8
5 files changed, 16 insertions, 12 deletions
diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c
index bf58e55..dcc1aba 100644
--- a/Objects/bytesobject.c
+++ b/Objects/bytesobject.c
@@ -46,7 +46,7 @@ Py_LOCAL_INLINE(Py_ssize_t) _PyBytesWriter_GetSize(_PyBytesWriter *writer,
static inline PyObject* bytes_get_empty(void)
{
PyObject *empty = &EMPTY->ob_base.ob_base;
- assert(_Py_IsImmortalLoose(empty));
+ assert(_Py_IsImmortal(empty));
return empty;
}
@@ -119,7 +119,7 @@ PyBytes_FromStringAndSize(const char *str, Py_ssize_t size)
}
if (size == 1 && str != NULL) {
op = CHARACTER(*str & 255);
- assert(_Py_IsImmortalLoose(op));
+ assert(_Py_IsImmortal(op));
return (PyObject *)op;
}
if (size == 0) {
@@ -155,7 +155,7 @@ PyBytes_FromString(const char *str)
}
else if (size == 1) {
op = CHARACTER(*str & 255);
- assert(_Py_IsImmortalLoose(op));
+ assert(_Py_IsImmortal(op));
return (PyObject *)op;
}
diff --git a/Objects/dictobject.c b/Objects/dictobject.c
index adfd91d..12722ec 100644
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -416,6 +416,8 @@ _PyDict_DebugMallocStats(FILE *out)
#define DK_MASK(dk) (DK_SIZE(dk)-1)
+#define _Py_DICT_IMMORTAL_INITIAL_REFCNT PY_SSIZE_T_MIN
+
static void free_keys_object(PyDictKeysObject *keys, bool use_qsbr);
/* PyDictKeysObject has refcounts like PyObject does, so we have the
@@ -428,7 +430,8 @@ static void free_keys_object(PyDictKeysObject *keys, bool use_qsbr);
static inline void
dictkeys_incref(PyDictKeysObject *dk)
{
- if (FT_ATOMIC_LOAD_SSIZE_RELAXED(dk->dk_refcnt) == _Py_IMMORTAL_REFCNT) {
+ if (FT_ATOMIC_LOAD_SSIZE_RELAXED(dk->dk_refcnt) < 0) {
+ assert(FT_ATOMIC_LOAD_SSIZE_RELAXED(dk->dk_refcnt) == _Py_DICT_IMMORTAL_INITIAL_REFCNT);
return;
}
#ifdef Py_REF_DEBUG
@@ -440,7 +443,8 @@ dictkeys_incref(PyDictKeysObject *dk)
static inline void
dictkeys_decref(PyInterpreterState *interp, PyDictKeysObject *dk, bool use_qsbr)
{
- if (FT_ATOMIC_LOAD_SSIZE_RELAXED(dk->dk_refcnt) == _Py_IMMORTAL_REFCNT) {
+ if (FT_ATOMIC_LOAD_SSIZE_RELAXED(dk->dk_refcnt) < 0) {
+ assert(FT_ATOMIC_LOAD_SSIZE_RELAXED(dk->dk_refcnt) == _Py_DICT_IMMORTAL_INITIAL_REFCNT);
return;
}
assert(FT_ATOMIC_LOAD_SSIZE(dk->dk_refcnt) > 0);
@@ -586,7 +590,7 @@ estimate_log2_keysize(Py_ssize_t n)
* (which cannot fail and thus can do no allocation).
*/
static PyDictKeysObject empty_keys_struct = {
- _Py_IMMORTAL_REFCNT, /* dk_refcnt */
+ _Py_DICT_IMMORTAL_INITIAL_REFCNT, /* dk_refcnt */
0, /* dk_log2_size */
0, /* dk_log2_index_bytes */
DICT_KEYS_UNICODE, /* dk_kind */
diff --git a/Objects/object.c b/Objects/object.c
index a97a900..27d06cc 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -2453,7 +2453,7 @@ _Py_SetImmortalUntracked(PyObject *op)
op->ob_ref_local = _Py_IMMORTAL_REFCNT_LOCAL;
op->ob_ref_shared = 0;
#else
- op->ob_refcnt = _Py_IMMORTAL_REFCNT;
+ op->ob_refcnt = _Py_IMMORTAL_INITIAL_REFCNT;
#endif
}
diff --git a/Objects/structseq.c b/Objects/structseq.c
index 60927428..56a7851 100644
--- a/Objects/structseq.c
+++ b/Objects/structseq.c
@@ -708,7 +708,7 @@ _PyStructSequence_FiniBuiltin(PyInterpreterState *interp, PyTypeObject *type)
assert(type->tp_name != NULL);
assert(type->tp_base == &PyTuple_Type);
assert((type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN));
- assert(_Py_IsImmortalLoose(type));
+ assert(_Py_IsImmortal(type));
// Cannot delete a type if it still has subclasses
if (_PyType_HasSubclasses(type)) {
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 5380633..d90bb58 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -476,7 +476,7 @@ set_tp_bases(PyTypeObject *self, PyObject *bases, int initial)
assert(PyTuple_GET_SIZE(bases) == 1);
assert(PyTuple_GET_ITEM(bases, 0) == (PyObject *)self->tp_base);
assert(self->tp_base->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN);
- assert(_Py_IsImmortalLoose(self->tp_base));
+ assert(_Py_IsImmortal(self->tp_base));
}
_Py_SetImmortal(bases);
}
@@ -493,7 +493,7 @@ clear_tp_bases(PyTypeObject *self, int final)
Py_CLEAR(self->tp_bases);
}
else {
- assert(_Py_IsImmortalLoose(self->tp_bases));
+ assert(_Py_IsImmortal(self->tp_bases));
_Py_ClearImmortal(self->tp_bases);
}
}
@@ -558,7 +558,7 @@ clear_tp_mro(PyTypeObject *self, int final)
Py_CLEAR(self->tp_mro);
}
else {
- assert(_Py_IsImmortalLoose(self->tp_mro));
+ assert(_Py_IsImmortal(self->tp_mro));
_Py_ClearImmortal(self->tp_mro);
}
}
@@ -5966,7 +5966,7 @@ fini_static_type(PyInterpreterState *interp, PyTypeObject *type,
int isbuiltin, int final)
{
assert(type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN);
- assert(_Py_IsImmortalLoose((PyObject *)type));
+ assert(_Py_IsImmortal((PyObject *)type));
type_dealloc_common(type);