diff options
Diffstat (limited to 'Objects/tupleobject.c')
-rw-r--r-- | Objects/tupleobject.c | 35 |
1 files changed, 19 insertions, 16 deletions
diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index 6b1ab74..b7fd421 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; } } |