Skip to content

Commit 3bbef7e

Browse files
committed
gh-152235: Defer GC tracking in set.union and set.difference
1 parent 1cbe460 commit 3bbef7e

2 files changed

Lines changed: 30 additions & 12 deletions

File tree

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Defer GC tracking in :meth:`set.union`, :meth:`set.difference` and
2+
:meth:`set.__sub__`. Patch by Donghee Na.

Objects/setobject.c

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1577,6 +1577,23 @@ _PySet_Freeze(PyObject *set)
15771577
return Py_NewRef(set);
15781578
}
15791579

1580+
// Shallow copy of `so` left GC-untracked; the caller must _PyObject_GC_TRACK()
1581+
// it once any further filling is done.
1582+
static PyObject *
1583+
set_copy_untracked_lock_held(PySetObject *so)
1584+
{
1585+
_Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(so);
1586+
PyObject *copy = make_new_set_basetype_untracked(Py_TYPE(so), NULL);
1587+
if (copy == NULL) {
1588+
return NULL;
1589+
}
1590+
if (set_merge_lock_held((PySetObject *)copy, (PyObject *)so) < 0) {
1591+
Py_DECREF(copy);
1592+
return NULL;
1593+
}
1594+
return copy;
1595+
}
1596+
15801597
/*[clinic input]
15811598
@critical_section
15821599
set.copy
@@ -1589,14 +1606,9 @@ static PyObject *
15891606
set_copy_impl(PySetObject *so)
15901607
/*[clinic end generated code: output=c9223a1e1cc6b041 input=c169a4fbb8209257]*/
15911608
{
1592-
_Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(so);
1593-
PyObject *copy = make_new_set_basetype(Py_TYPE(so), NULL);
1594-
if (copy == NULL) {
1595-
return NULL;
1596-
}
1597-
if (set_merge_lock_held((PySetObject *)copy, (PyObject *)so) < 0) {
1598-
Py_DECREF(copy);
1599-
return NULL;
1609+
PyObject *copy = set_copy_untracked_lock_held(so);
1610+
if (copy != NULL) {
1611+
_PyObject_GC_TRACK(copy);
16001612
}
16011613
return copy;
16021614
}
@@ -1652,7 +1664,8 @@ set_union_impl(PySetObject *so, PyObject * const *others,
16521664
PyObject *other;
16531665
Py_ssize_t i;
16541666

1655-
result = (PySetObject *)set_copy((PyObject *)so, NULL);
1667+
result = (PySetObject *)make_new_set_basetype_untracked(Py_TYPE(so),
1668+
(PyObject *)so);
16561669
if (result == NULL)
16571670
return NULL;
16581671

@@ -1665,6 +1678,7 @@ set_union_impl(PySetObject *so, PyObject * const *others,
16651678
return NULL;
16661679
}
16671680
}
1681+
_PyObject_GC_TRACK(result);
16681682
return (PyObject *)result;
16691683
}
16701684

@@ -2059,7 +2073,7 @@ set_copy_and_difference(PySetObject *so, PyObject *other)
20592073
{
20602074
PyObject *result;
20612075

2062-
result = set_copy_impl(so);
2076+
result = set_copy_untracked_lock_held(so);
20632077
if (result == NULL)
20642078
return NULL;
20652079
if (set_difference_update_internal((PySetObject *) result, other) == 0)
@@ -2118,7 +2132,6 @@ set_difference(PySetObject *so, PyObject *other)
21182132
}
21192133
Py_DECREF(key);
21202134
}
2121-
_PyObject_GC_TRACK(result);
21222135
return result;
21232136
}
21242137

@@ -2142,7 +2155,6 @@ set_difference(PySetObject *so, PyObject *other)
21422155
}
21432156
Py_DECREF(key);
21442157
}
2145-
_PyObject_GC_TRACK(result);
21462158
return result;
21472159
}
21482160

@@ -2185,6 +2197,7 @@ set_difference_multi_impl(PySetObject *so, PyObject * const *others,
21852197
return NULL;
21862198
}
21872199
}
2200+
_PyObject_GC_TRACK(result);
21882201
return result;
21892202
}
21902203

@@ -2199,6 +2212,9 @@ set_sub(PyObject *self, PyObject *other)
21992212
Py_BEGIN_CRITICAL_SECTION2(so, other);
22002213
rv = set_difference(so, other);
22012214
Py_END_CRITICAL_SECTION2();
2215+
if (rv != NULL) {
2216+
_PyObject_GC_TRACK(rv);
2217+
}
22022218
return rv;
22032219
}
22042220

0 commit comments

Comments
 (0)