Skip to content

Commit

Permalink
pythongh-115605 Use QSBR technique for list_new/free
Browse files Browse the repository at this point in the history
  • Loading branch information
corona10 committed Feb 24, 2024
1 parent 32da182 commit de49474
Showing 1 changed file with 21 additions and 5 deletions.
26 changes: 21 additions & 5 deletions Objects/listobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ get_list_freelist(void)
}
#endif

#ifdef Py_GIL_DISABLED
static size_t
list_good_size(Py_ssize_t size)
{
// 4, 8, 16, 24, 32, 40, 48, 64, 80, ...
// NOTE: we add one here so that the rounding accounts for the "allocated"
// field in _PyListArray.
size_t reqsize = (size_t)size + 1;
if (reqsize <= 4) {
reqsize = 4;
Expand Down Expand Up @@ -67,6 +67,7 @@ list_allocate_items(size_t capacity)
PyObject **items = PyMem_Malloc(capacity * sizeof(PyObject *));
return items;
}
#endif

static PyListObject *
list_new(Py_ssize_t size)
Expand Down Expand Up @@ -699,7 +700,7 @@ list_repeat(PyObject *aa, Py_ssize_t n)
}

static void
list_clear(PyListObject *a)
list_clear_impl(PyListObject *a, bool is_resize)
{
PyObject **items = a->ob_item;
if (items == NULL) {
Expand All @@ -716,16 +717,31 @@ list_clear(PyListObject *a)
Py_XDECREF(items[i]);
}
// TODO: Use QSBR technique, if the list is shared between threads,
PyMem_Free(items);

#ifdef Py_GIL_DISABLED
bool use_qsbr = is_resize && _PyObject_GC_IS_SHARED(a);
#else
bool use_qsbr = false;
#endif
if (use_qsbr) {
_PyMem_FreeDelayed(items);
}
else {
PyMem_Free(items);
}
// Note that there is no guarantee that the list is actually empty
// at this point, because XDECREF may have populated it indirectly again!
}

static void
list_clear(PyListObject *a)
{
list_clear_impl(a, true);
}

static int
list_clear_slot(PyObject *self)
{
list_clear((PyListObject *)self);
list_clear_impl((PyListObject *)self, false);
return 0;
}

Expand Down

0 comments on commit de49474

Please sign in to comment.