mirror of
https://github.com/python/cpython.git
synced 2026-06-27 19:36:07 +00:00
[3.15] gh-152235: Defer GC tracking in set.union and set.difference (gh-152290) (gh-152316)
(cherry picked from commit 5a549e82b8)
This commit is contained in:
parent
52bdfcc141
commit
073b658dd3
2 changed files with 35 additions and 20 deletions
|
|
@ -1,2 +1,3 @@
|
|||
Defer GC tracking of :meth:`set.intersection`, :meth:`set.difference` and
|
||||
:meth:`set.symmetric_difference`. Patch by Donghee Na.
|
||||
Defer GC tracking of :meth:`set.intersection`, :meth:`set.difference`,
|
||||
:meth:`set.symmetric_difference`, :meth:`set.union` and ``set.__sub__``.
|
||||
Patch by Donghee Na.
|
||||
|
|
|
|||
|
|
@ -1567,6 +1567,21 @@ set_swap_bodies(PySetObject *a, PySetObject *b)
|
|||
FT_ATOMIC_STORE_PTR_RELEASE(b->table, b_table);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
set_copy_untracked_lock_held(PySetObject *so)
|
||||
{
|
||||
_Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(so);
|
||||
PyObject *copy = make_new_set_basetype_untracked(Py_TYPE(so), NULL);
|
||||
if (copy == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (set_merge_lock_held((PySetObject *)copy, (PyObject *)so) < 0) {
|
||||
Py_DECREF(copy);
|
||||
return NULL;
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
/*[clinic input]
|
||||
@critical_section
|
||||
set.copy
|
||||
|
|
@ -1579,14 +1594,9 @@ static PyObject *
|
|||
set_copy_impl(PySetObject *so)
|
||||
/*[clinic end generated code: output=c9223a1e1cc6b041 input=c169a4fbb8209257]*/
|
||||
{
|
||||
_Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(so);
|
||||
PyObject *copy = make_new_set_basetype(Py_TYPE(so), NULL);
|
||||
if (copy == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (set_merge_lock_held((PySetObject *)copy, (PyObject *)so) < 0) {
|
||||
Py_DECREF(copy);
|
||||
return NULL;
|
||||
PyObject *copy = set_copy_untracked_lock_held(so);
|
||||
if (copy != NULL) {
|
||||
_PyObject_GC_TRACK(copy);
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
|
@ -1642,7 +1652,8 @@ set_union_impl(PySetObject *so, PyObject * const *others,
|
|||
PyObject *other;
|
||||
Py_ssize_t i;
|
||||
|
||||
result = (PySetObject *)set_copy((PyObject *)so, NULL);
|
||||
result = (PySetObject *)make_new_set_basetype_untracked(Py_TYPE(so),
|
||||
(PyObject *)so);
|
||||
if (result == NULL)
|
||||
return NULL;
|
||||
|
||||
|
|
@ -1655,6 +1666,7 @@ set_union_impl(PySetObject *so, PyObject * const *others,
|
|||
return NULL;
|
||||
}
|
||||
}
|
||||
_PyObject_GC_TRACK(result);
|
||||
return (PyObject *)result;
|
||||
}
|
||||
|
||||
|
|
@ -2045,11 +2057,11 @@ set_difference_update_impl(PySetObject *so, PyObject * const *others,
|
|||
}
|
||||
|
||||
static PyObject *
|
||||
set_copy_and_difference(PySetObject *so, PyObject *other)
|
||||
set_copy_and_difference_untracked(PySetObject *so, PyObject *other)
|
||||
{
|
||||
PyObject *result;
|
||||
|
||||
result = set_copy_impl(so);
|
||||
result = set_copy_untracked_lock_held(so);
|
||||
if (result == NULL)
|
||||
return NULL;
|
||||
if (set_difference_update_internal((PySetObject *) result, other) == 0)
|
||||
|
|
@ -2059,7 +2071,7 @@ set_copy_and_difference(PySetObject *so, PyObject *other)
|
|||
}
|
||||
|
||||
static PyObject *
|
||||
set_difference(PySetObject *so, PyObject *other)
|
||||
set_difference_untracked(PySetObject *so, PyObject *other)
|
||||
{
|
||||
PyObject *result;
|
||||
PyObject *key;
|
||||
|
|
@ -2075,13 +2087,13 @@ set_difference(PySetObject *so, PyObject *other)
|
|||
other_size = PyDict_GET_SIZE(other);
|
||||
}
|
||||
else {
|
||||
return set_copy_and_difference(so, other);
|
||||
return set_copy_and_difference_untracked(so, other);
|
||||
}
|
||||
|
||||
/* If len(so) much more than len(other), it's more efficient to simply copy
|
||||
* so and then iterate other looking for common elements. */
|
||||
if ((PySet_GET_SIZE(so) >> 2) > other_size) {
|
||||
return set_copy_and_difference(so, other);
|
||||
return set_copy_and_difference_untracked(so, other);
|
||||
}
|
||||
|
||||
result = make_new_set_basetype_untracked(Py_TYPE(so), NULL);
|
||||
|
|
@ -2108,7 +2120,6 @@ set_difference(PySetObject *so, PyObject *other)
|
|||
}
|
||||
Py_DECREF(key);
|
||||
}
|
||||
_PyObject_GC_TRACK(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -2132,7 +2143,6 @@ set_difference(PySetObject *so, PyObject *other)
|
|||
}
|
||||
Py_DECREF(key);
|
||||
}
|
||||
_PyObject_GC_TRACK(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -2159,7 +2169,7 @@ set_difference_multi_impl(PySetObject *so, PyObject * const *others,
|
|||
|
||||
other = others[0];
|
||||
Py_BEGIN_CRITICAL_SECTION2(so, other);
|
||||
result = set_difference(so, other);
|
||||
result = set_difference_untracked(so, other);
|
||||
Py_END_CRITICAL_SECTION2();
|
||||
if (result == NULL)
|
||||
return NULL;
|
||||
|
|
@ -2175,6 +2185,7 @@ set_difference_multi_impl(PySetObject *so, PyObject * const *others,
|
|||
return NULL;
|
||||
}
|
||||
}
|
||||
_PyObject_GC_TRACK(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -2187,8 +2198,11 @@ set_sub(PyObject *self, PyObject *other)
|
|||
|
||||
PyObject *rv;
|
||||
Py_BEGIN_CRITICAL_SECTION2(so, other);
|
||||
rv = set_difference(so, other);
|
||||
rv = set_difference_untracked(so, other);
|
||||
Py_END_CRITICAL_SECTION2();
|
||||
if (rv != NULL) {
|
||||
_PyObject_GC_TRACK(rv);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue