Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Include/internal/pycore_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,13 @@ extern void _PyList_Fini(_PyFreeListState *);
extern int
_PyList_AppendTakeRefListResize(PyListObject *self, PyObject *newitem);

// In free-threaded build: self should be locked by the caller, if it should be thread-safe.
static inline int
_PyList_AppendTakeRef(PyListObject *self, PyObject *newitem)
{
assert(self != NULL && newitem != NULL);
assert(PyList_Check(self));
Py_ssize_t len = PyList_GET_SIZE(self);
Py_ssize_t len = Py_SIZE(self);
Py_ssize_t allocated = self->allocated;
assert((size_t)len + 1 < PY_SSIZE_T_MAX);
if (allocated > len) {
Expand Down
4 changes: 4 additions & 0 deletions Include/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,11 @@ static inline void Py_SET_TYPE(PyObject *ob, PyTypeObject *type) {
static inline void Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size) {
assert(ob->ob_base.ob_type != &PyLong_Type);
assert(ob->ob_base.ob_type != &PyBool_Type);
#ifdef Py_GIL_DISABLED
_Py_atomic_store_ssize_relaxed(&(_PyVarObject_CAST(ob)->ob_size), size);
#else
ob->ob_size = size;
#endif
}
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
# define Py_SET_SIZE(ob, size) Py_SET_SIZE(_PyVarObject_CAST(ob), (size))
Expand Down
36 changes: 25 additions & 11 deletions Objects/listobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ get_list_state(void)
}
#endif

#ifdef Py_GIL_DISABLED
#define _Py_SET_ITEMREF(op, i, v) _Py_atomic_store_ptr_relaxed(&((PyListObject *)(op))->ob_item[i], Py_NewRef(v))
#else
#define _Py_SET_ITEMREF(op, i, v) ((PyListObject *)(op))->ob_item[i] = Py_NewRef(v)
#endif


/* Ensure ob_item has room for at least newsize elements, and set
* ob_size to newsize. If newsize > ob_size on entry, the content
Expand Down Expand Up @@ -221,8 +227,9 @@ PyList_Size(PyObject *op)
PyErr_BadInternalCall();
return -1;
}
else
return Py_SIZE(op);
else {
return PyList_GET_SIZE(op);
}
}

static inline int
Expand All @@ -245,7 +252,7 @@ PyList_GetItem(PyObject *op, Py_ssize_t i)
PyErr_BadInternalCall();
return NULL;
}
if (!valid_index(i, Py_SIZE(op))) {
if (!valid_index(i, PyList_GET_SIZE(op))) {
_Py_DECLARE_STR(list_err, "list index out of range");
PyErr_SetObject(PyExc_IndexError, &_Py_STR(list_err));
return NULL;
Expand Down Expand Up @@ -328,7 +335,7 @@ PyList_Insert(PyObject *op, Py_ssize_t where, PyObject *newitem)
int
_PyList_AppendTakeRefListResize(PyListObject *self, PyObject *newitem)
{
Py_ssize_t len = PyList_GET_SIZE(self);
Py_ssize_t len = Py_SIZE(self);
Copy link
Member Author

@corona10 corona10 Jan 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is only called by _PyList_AppendTakeRef, so it's safe.

assert(self->allocated == -1 || self->allocated == len);
if (list_resize(self, len + 1) < 0) {
Py_DECREF(newitem);
Expand All @@ -341,11 +348,15 @@ _PyList_AppendTakeRefListResize(PyListObject *self, PyObject *newitem)
int
PyList_Append(PyObject *op, PyObject *newitem)
{
int ret = -1;
if (PyList_Check(op) && (newitem != NULL)) {
return _PyList_AppendTakeRef((PyListObject *)op, Py_NewRef(newitem));
Py_BEGIN_CRITICAL_SECTION(op);
ret = _PyList_AppendTakeRef((PyListObject *)op, Py_NewRef(newitem));
Py_END_CRITICAL_SECTION();
return ret;
}
PyErr_BadInternalCall();
return -1;
return ret;
}

/* Methods */
Expand Down Expand Up @@ -473,7 +484,7 @@ static PyObject *
list_item(PyObject *aa, Py_ssize_t i)
{
PyListObject *a = (PyListObject *)aa;
if (!valid_index(i, Py_SIZE(a))) {
if (!valid_index(i, PyList_GET_SIZE(a))) {
PyErr_SetObject(PyExc_IndexError, &_Py_STR(list_err));
return NULL;
}
Expand All @@ -484,7 +495,7 @@ static PyObject *
list_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh)
{
PyListObject *np;
PyObject **src, **dest;
PyObject **src;
Py_ssize_t i, len;
len = ihigh - ilow;
if (len <= 0) {
Expand All @@ -495,10 +506,9 @@ list_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh)
return NULL;

src = a->ob_item + ilow;
dest = np->ob_item;
for (i = 0; i < len; i++) {
PyObject *v = src[i];
dest[i] = Py_NewRef(v);
_Py_SET_ITEMREF(np, i, v);
}
Py_SET_SIZE(np, len);
return (PyObject *)np;
Expand All @@ -511,6 +521,8 @@ PyList_GetSlice(PyObject *a, Py_ssize_t ilow, Py_ssize_t ihigh)
PyErr_BadInternalCall();
return NULL;
}
PyObject *ret;
Py_BEGIN_CRITICAL_SECTION(a);
if (ilow < 0) {
ilow = 0;
}
Expand All @@ -523,7 +535,9 @@ PyList_GetSlice(PyObject *a, Py_ssize_t ilow, Py_ssize_t ihigh)
else if (ihigh > Py_SIZE(a)) {
ihigh = Py_SIZE(a);
}
return list_slice((PyListObject *)a, ilow, ihigh);
ret = list_slice((PyListObject *)a, ilow, ihigh);
Py_END_CRITICAL_SECTION();
return ret;
}

static PyObject *
Expand Down