Skip to content

Commit 0d7eff1

Browse files
Helper function is added
1 parent 5c117a7 commit 0d7eff1

File tree

2 files changed

+28
-26
lines changed

2 files changed

+28
-26
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Do not track immutable tuples in GC. Count only tracked objects in GC young
2+
objects counter. Patch by Sergey Miryanov and Mikhail Efimov

Objects/tupleobject.c

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,22 @@ _PyTuple_MaybeUntrack(PyObject *op)
156156
_PyObject_GC_UNTRACK(op);
157157
}
158158

159+
static bool
160+
tuple_need_tracking(PyTupleObject *t)
161+
{
162+
Py_ssize_t i = 0, n = Py_SIZE(t);
163+
for (; i < n; i++) {
164+
PyObject *elt = PyTuple_GET_ITEM(t, i);
165+
/* Tuple with NULL elements aren't
166+
fully constructed, we should track them. */
167+
if (!elt ||
168+
_PyObject_GC_MAY_BE_TRACKED(elt)) {
169+
return true;
170+
}
171+
}
172+
return false;
173+
}
174+
159175
PyObject *
160176
PyTuple_Pack(Py_ssize_t n, ...)
161177
{
@@ -169,25 +185,21 @@ PyTuple_Pack(Py_ssize_t n, ...)
169185
}
170186

171187
va_start(vargs, n);
172-
PyTupleObject *result = tuple_alloc(n);
173-
if (result == NULL) {
188+
PyTupleObject *tuple = tuple_alloc(n);
189+
if (tuple == NULL) {
174190
va_end(vargs);
175191
return NULL;
176192
}
177-
items = result->ob_item;
178-
bool track = false;
193+
items = tuple->ob_item;
179194
for (i = 0; i < n; i++) {
180195
o = va_arg(vargs, PyObject *);
181196
items[i] = Py_NewRef(o);
182-
if (!track && _PyObject_GC_MAY_BE_TRACKED(items[i])) {
183-
track = true;
184-
}
185197
}
186198
va_end(vargs);
187-
if (track) {
188-
_PyObject_GC_TRACK(result);
199+
if (tuple_need_tracking(tuple)) {
200+
_PyObject_GC_TRACK(tuple);
189201
}
190-
return (PyObject *)result;
202+
return (PyObject *)tuple;
191203
}
192204

193205

@@ -382,16 +394,12 @@ PyTuple_FromArray(PyObject *const *src, Py_ssize_t n)
382394
if (tuple == NULL) {
383395
return NULL;
384396
}
385-
bool track = false;
386397
PyObject **dst = tuple->ob_item;
387398
for (Py_ssize_t i = 0; i < n; i++) {
388399
PyObject *item = src[i];
389400
dst[i] = Py_NewRef(item);
390-
if (!track && _PyObject_GC_MAY_BE_TRACKED(dst[i])) {
391-
track = true;
392-
}
393401
}
394-
if (track) {
402+
if (tuple_need_tracking(tuple)) {
395403
_PyObject_GC_TRACK(tuple);
396404
}
397405
return (PyObject *)tuple;
@@ -407,15 +415,11 @@ _PyTuple_FromStackRefStealOnSuccess(const _PyStackRef *src, Py_ssize_t n)
407415
if (tuple == NULL) {
408416
return NULL;
409417
}
410-
bool track = false;
411418
PyObject **dst = tuple->ob_item;
412419
for (Py_ssize_t i = 0; i < n; i++) {
413420
dst[i] = PyStackRef_AsPyObjectSteal(src[i]);
414-
if (!track && _PyObject_GC_MAY_BE_TRACKED(dst[i])) {
415-
track = true;
416-
}
417421
}
418-
if (track) {
422+
if (tuple_need_tracking(tuple)) {
419423
_PyObject_GC_TRACK(tuple);
420424
}
421425
return (PyObject *)tuple;
@@ -434,16 +438,12 @@ _PyTuple_FromArraySteal(PyObject *const *src, Py_ssize_t n)
434438
}
435439
return NULL;
436440
}
437-
bool track = false;
438441
PyObject **dst = tuple->ob_item;
439442
for (Py_ssize_t i = 0; i < n; i++) {
440443
PyObject *item = src[i];
441444
dst[i] = item;
442-
if (!track && _PyObject_GC_MAY_BE_TRACKED(item)) {
443-
track = true;
444-
}
445445
}
446-
if (track) {
446+
if (tuple_need_tracking(tuple)) {
447447
_PyObject_GC_TRACK(tuple);
448448
}
449449
return (PyObject *)tuple;
@@ -572,7 +572,7 @@ tuple_repeat(PyObject *self, Py_ssize_t n)
572572
if (_PyObject_GC_IS_TRACKED(a)) {
573573
_PyObject_GC_TRACK(np);
574574
}
575-
return (PyObject *) np;
575+
return (PyObject *)np;
576576
}
577577

578578
/*[clinic input]

0 commit comments

Comments
 (0)