summaryrefslogtreecommitdiff
path: root/Objects/tupleobject.c
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2021-07-01 02:30:46 +0200
committerGitHub <noreply@github.com>2021-07-01 02:30:46 +0200
commit818628c2da99ba0376313971816d472c65c9a9fc (patch)
tree60d50461785e6ddc16f35a047ece9dc83890eef8 /Objects/tupleobject.c
parent1b28187a0e3e914ee48de8032cbba0a965dd5563 (diff)
downloadcpython-git-818628c2da99ba0376313971816d472c65c9a9fc.tar.gz
bpo-44531: Add _PyType_AllocNoTrack() function (GH-26947)
Add an internal _PyType_AllocNoTrack() function to allocate an object without tracking it in the GC. Modify dict_new() to use _PyType_AllocNoTrack(): dict subclasses are now only tracked once all PyDictObject members are initialized. Calling _PyObject_GC_UNTRACK() is no longer needed for the dict type. Similar change in tuple_subtype_new() for tuple subclasses. Replace tuple_gc_track() with _PyObject_GC_TRACK().
Diffstat (limited to 'Objects/tupleobject.c')
-rw-r--r--Objects/tupleobject.c35
1 files changed, 19 insertions, 16 deletions
diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c
index 6b1ab74012..b7fd421196 100644
--- a/Objects/tupleobject.c
+++ b/Objects/tupleobject.c
@@ -25,13 +25,6 @@ get_tuple_state(void)
#endif
-static inline void
-tuple_gc_track(PyTupleObject *op)
-{
- _PyObject_GC_TRACK(op);
-}
-
-
/* Print summary info about the state of the optimized allocator */
void
_PyTuple_DebugMallocStats(FILE *out)
@@ -48,10 +41,12 @@ _PyTuple_DebugMallocStats(FILE *out)
#endif
}
-/* Allocate an uninitialized tuple object. Before making it public following
+/* Allocate an uninitialized tuple object. Before making it public, following
steps must be done:
- - initialize its items
- - call tuple_gc_track() on it
+
+ - Initialize its items.
+ - Call _PyObject_GC_TRACK() on it.
+
Because the empty tuple is always reused and it's already tracked by GC,
this function must not be called with size == 0 (unless from PyTuple_New()
which wraps this function).
@@ -161,7 +156,7 @@ PyTuple_New(Py_ssize_t size)
for (Py_ssize_t i = 0; i < size; i++) {
op->ob_item[i] = NULL;
}
- tuple_gc_track(op);
+ _PyObject_GC_TRACK(op);
return (PyObject *) op;
}
@@ -257,7 +252,7 @@ PyTuple_Pack(Py_ssize_t n, ...)
items[i] = o;
}
va_end(vargs);
- tuple_gc_track(result);
+ _PyObject_GC_TRACK(result);
return (PyObject *)result;
}
@@ -473,7 +468,7 @@ _PyTuple_FromArray(PyObject *const *src, Py_ssize_t n)
Py_INCREF(item);
dst[i] = item;
}
- tuple_gc_track(tuple);
+ _PyObject_GC_TRACK(tuple);
return (PyObject *)tuple;
}
@@ -551,7 +546,7 @@ tupleconcat(PyTupleObject *a, PyObject *bb)
Py_INCREF(v);
dest[i] = v;
}
- tuple_gc_track(np);
+ _PyObject_GC_TRACK(np);
return (PyObject *)np;
}
@@ -588,7 +583,7 @@ tuplerepeat(PyTupleObject *a, Py_ssize_t n)
p++;
}
}
- tuple_gc_track(np);
+ _PyObject_GC_TRACK(np);
return (PyObject *) np;
}
@@ -783,6 +778,9 @@ tuple_subtype_new(PyTypeObject *type, PyObject *iterable)
Py_ssize_t i, n;
assert(PyType_IsSubtype(type, &PyTuple_Type));
+ // tuple subclasses must implement the GC protocol
+ assert(_PyType_IS_GC(type));
+
tmp = tuple_new_impl(&PyTuple_Type, iterable);
if (tmp == NULL)
return NULL;
@@ -798,6 +796,11 @@ tuple_subtype_new(PyTypeObject *type, PyObject *iterable)
PyTuple_SET_ITEM(newobj, i, item);
}
Py_DECREF(tmp);
+
+ // Don't track if a subclass tp_alloc is PyType_GenericAlloc()
+ if (!_PyObject_GC_IS_TRACKED(newobj)) {
+ _PyObject_GC_TRACK(newobj);
+ }
return newobj;
}
@@ -857,7 +860,7 @@ tuplesubscript(PyTupleObject* self, PyObject* item)
dest[i] = it;
}
- tuple_gc_track(result);
+ _PyObject_GC_TRACK(result);
return (PyObject *)result;
}
}