summaryrefslogtreecommitdiffstats
path: root/Objects/tupleobject.c
diff options
context:
space:
mode:
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 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;
}
}