bpo-40521: Always create the empty tuple singleton (GH-21116) · python/cpython@0430dfa
@@ -2,10 +2,10 @@
22/* Tuple object implementation */
3344#include "Python.h"
5-#include "pycore_abstract.h" // _PyIndex_Check()
6-#include "pycore_accu.h"
7-#include "pycore_gc.h" // _PyObject_GC_IS_TRACKED()
8-#include "pycore_object.h"
5+#include "pycore_abstract.h" // _PyIndex_Check()
6+#include "pycore_gc.h" // _PyObject_GC_IS_TRACKED()
7+#include "pycore_initconfig.h" // _PyStatus_OK()
8+#include "pycore_object.h" // _PyObject_GC_TRACK()
991010/*[clinic input]
1111class tuple "PyTupleObject *" "&PyTuple_Type"
@@ -15,12 +15,14 @@ class tuple "PyTupleObject *" "&PyTuple_Type"
1515#include "clinic/tupleobject.c.h"
1616171718+#if PyTuple_MAXSAVESIZE > 0
1819static struct _Py_tuple_state *
1920get_tuple_state(void)
2021{
2122PyInterpreterState *interp = _PyInterpreterState_GET();
2223return &interp->tuple;
2324}
25+#endif
242625272628static inline void
@@ -55,14 +57,21 @@ _PyTuple_DebugMallocStats(FILE *out)
5557 which wraps this function).
5658*/
5759static PyTupleObject *
58-tuple_alloc(struct _Py_tuple_state *state, Py_ssize_t size)
60+tuple_alloc(Py_ssize_t size)
5961{
6062PyTupleObject *op;
63+#if PyTuple_MAXSAVESIZE > 0
64+// If Python is built with the empty tuple singleton,
65+// tuple_alloc(0) must not be called.
66+assert(size != 0);
67+#endif
6168if (size < 0) {
6269PyErr_BadInternalCall();
6370return NULL;
6471 }
72+6573#if PyTuple_MAXSAVESIZE > 0
74+struct _Py_tuple_state *state = get_tuple_state();
6675#ifdef Py_DEBUG
6776// tuple_alloc() must not be called after _PyTuple_Fini()
6877assert(state->numfree[0] != -1);
@@ -93,36 +102,65 @@ tuple_alloc(struct _Py_tuple_state *state, Py_ssize_t size)
93102return op;
94103}
95104105+static int
106+tuple_create_empty_tuple_singleton(struct _Py_tuple_state *state)
107+{
108+#if PyTuple_MAXSAVESIZE > 0
109+assert(state->free_list[0] == NULL);
110+111+PyTupleObject *op = PyObject_GC_NewVar(PyTupleObject, &PyTuple_Type, 0);
112+if (op == NULL) {
113+return -1;
114+ }
115+// The empty tuple singleton is not tracked by the GC.
116+// It does not contain any Python object.
117+118+state->free_list[0] = op;
119+state->numfree[0]++;
120+121+assert(state->numfree[0] == 1);
122+#endif
123+return 0;
124+}
125+126+127+static PyObject *
128+tuple_get_empty(void)
129+{
130+#if PyTuple_MAXSAVESIZE > 0
131+struct _Py_tuple_state *state = get_tuple_state();
132+PyTupleObject *op = state->free_list[0];
133+// tuple_get_empty() must not be called before _PyTuple_Init()
134+// or after _PyTuple_Fini()
135+assert(op != NULL);
136+#ifdef Py_DEBUG
137+assert(state->numfree[0] != -1);
138+#endif
139+140+Py_INCREF(op);
141+return (PyObject *) op;
142+#else
143+return PyTuple_New(0);
144+#endif
145+}
146+147+96148PyObject *
97149PyTuple_New(Py_ssize_t size)
98150{
99151PyTupleObject *op;
100152#if PyTuple_MAXSAVESIZE > 0
101-struct _Py_tuple_state *state = get_tuple_state();
102-if (size == 0 && state->free_list[0]) {
103-op = state->free_list[0];
104-Py_INCREF(op);
105-return (PyObject *) op;
153+if (size == 0) {
154+return tuple_get_empty();
106155 }
107156#endif
108-op = tuple_alloc(state, size);
157+op = tuple_alloc(size);
109158if (op == NULL) {
110159return NULL;
111160 }
112161for (Py_ssize_t i = 0; i < size; i++) {
113162op->ob_item[i] = NULL;
114163 }
115-#if PyTuple_MAXSAVESIZE > 0
116-if (size == 0) {
117-#ifdef Py_DEBUG
118-// PyTuple_New() must not be called after _PyTuple_Fini()
119-assert(state->numfree[0] != -1);
120-#endif
121-state->free_list[0] = op;
122-++state->numfree[0];
123-Py_INCREF(op); /* extra INCREF so that this is never freed */
124- }
125-#endif
126164tuple_gc_track(op);
127165return (PyObject *) op;
128166}
@@ -203,13 +241,11 @@ PyTuple_Pack(Py_ssize_t n, ...)
203241va_list vargs;
204242205243if (n == 0) {
206-return PyTuple_New(0);
244+return tuple_get_empty();
207245 }
208246209-struct _Py_tuple_state *state = get_tuple_state();
210-211247va_start(vargs, n);
212-PyTupleObject *result = tuple_alloc(state, n);
248+PyTupleObject *result = tuple_alloc(n);
213249if (result == NULL) {
214250va_end(vargs);
215251return NULL;
@@ -245,9 +281,9 @@ tupledealloc(PyTupleObject *op)
245281// tupledealloc() must not be called after _PyTuple_Fini()
246282assert(state->numfree[0] != -1);
247283#endif
248-if (len < PyTuple_MAXSAVESIZE &&
249-state->numfree[len] < PyTuple_MAXFREELIST &&
250-Py_IS_TYPE(op, &PyTuple_Type))
284+if (len < PyTuple_MAXSAVESIZE
285+&& state->numfree[len] < PyTuple_MAXFREELIST
286+&& Py_IS_TYPE(op, &PyTuple_Type))
251287 {
252288op->ob_item[0] = (PyObject *) state->free_list[len];
253289state->numfree[len]++;
@@ -257,6 +293,7 @@ tupledealloc(PyTupleObject *op)
257293#endif
258294 }
259295Py_TYPE(op)->tp_free((PyObject *)op);
296+260297#if PyTuple_MAXSAVESIZE > 0
261298done:
262299#endif
@@ -423,11 +460,10 @@ PyObject *
423460_PyTuple_FromArray(PyObject *const *src, Py_ssize_t n)
424461{
425462if (n == 0) {
426-return PyTuple_New(0);
463+return tuple_get_empty();
427464 }
428465429-struct _Py_tuple_state *state = get_tuple_state();
430-PyTupleObject *tuple = tuple_alloc(state, n);
466+PyTupleObject *tuple = tuple_alloc(n);
431467if (tuple == NULL) {
432468return NULL;
433469 }
@@ -494,11 +530,10 @@ tupleconcat(PyTupleObject *a, PyObject *bb)
494530assert((size_t)Py_SIZE(a) + (size_t)Py_SIZE(b) < PY_SSIZE_T_MAX);
495531size = Py_SIZE(a) + Py_SIZE(b);
496532if (size == 0) {
497-return PyTuple_New(0);
533+return tuple_get_empty();
498534 }
499535500-struct _Py_tuple_state *state = get_tuple_state();
501-np = tuple_alloc(state, size);
536+np = tuple_alloc(size);
502537if (np == NULL) {
503538return NULL;
504539 }
@@ -536,13 +571,12 @@ tuplerepeat(PyTupleObject *a, Py_ssize_t n)
536571 }
537572 }
538573if (Py_SIZE(a) == 0 || n <= 0) {
539-return PyTuple_New(0);
574+return tuple_get_empty();
540575 }
541576if (n > PY_SSIZE_T_MAX / Py_SIZE(a))
542577return PyErr_NoMemory();
543578size = Py_SIZE(a) * n;
544-struct _Py_tuple_state *state = get_tuple_state();
545-np = tuple_alloc(state, size);
579+np = tuple_alloc(size);
546580if (np == NULL)
547581return NULL;
548582p = np->ob_item;
@@ -713,10 +747,12 @@ tuple_new_impl(PyTypeObject *type, PyObject *iterable)
713747if (type != &PyTuple_Type)
714748return tuple_subtype_new(type, iterable);
715749716-if (iterable == NULL)
717-return PyTuple_New(0);
718-else
750+if (iterable == NULL) {
751+return tuple_get_empty();
752+ }
753+else {
719754return PySequence_Tuple(iterable);
755+ }
720756}
721757722758static PyObject *
@@ -735,7 +771,9 @@ tuple_vectorcall(PyObject *type, PyObject * const*args,
735771if (nargs) {
736772return tuple_new_impl((PyTypeObject *)type, args[0]);
737773 }
738-return PyTuple_New(0);
774+else {
775+return tuple_get_empty();
776+ }
739777}
740778741779static PyObject *
@@ -798,7 +836,7 @@ tuplesubscript(PyTupleObject* self, PyObject* item)
798836&stop, step);
799837800838if (slicelength <= 0) {
801-return PyTuple_New(0);
839+return tuple_get_empty();
802840 }
803841else if (start == 0 && step == 1 &&
804842slicelength == PyTuple_GET_SIZE(self) &&
@@ -807,8 +845,7 @@ tuplesubscript(PyTupleObject* self, PyObject* item)
807845return (PyObject *)self;
808846 }
809847else {
810-struct _Py_tuple_state *state = get_tuple_state();
811-PyTupleObject* result = tuple_alloc(state, slicelength);
848+PyTupleObject* result = tuple_alloc(slicelength);
812849if (!result) return NULL;
813850814851src = self->ob_item;
@@ -988,15 +1025,26 @@ _PyTuple_ClearFreeList(PyThreadState *tstate)
9881025#endif
9891026}
99010271028+1029+PyStatus
1030+_PyTuple_Init(PyThreadState *tstate)
1031+{
1032+struct _Py_tuple_state *state = &tstate->interp->tuple;
1033+if (tuple_create_empty_tuple_singleton(state) < 0) {
1034+return _PyStatus_NO_MEMORY();
1035+ }
1036+return _PyStatus_OK();
1037+}
1038+1039+9911040void
9921041_PyTuple_Fini(PyThreadState *tstate)
9931042{
9941043#if PyTuple_MAXSAVESIZE > 0
9951044struct _Py_tuple_state *state = &tstate->interp->tuple;
996-/* empty tuples are used all over the place and applications may
997- * rely on the fact that an empty tuple is a singleton. */
1045+// The empty tuple singleton must not be tracked by the GC
1046+assert(!_PyObject_GC_IS_TRACKED(state->free_list[0]));
9981047Py_CLEAR(state->free_list[0]);
999-10001048_PyTuple_ClearFreeList(tstate);
10011049#ifdef Py_DEBUG
10021050state->numfree[0] = -1;