@@ -33,7 +33,6 @@ static inline int maybe_freelist_push(PyTupleObject *);
33
33
static PyTupleObject *
34
34
tuple_alloc (Py_ssize_t size )
35
35
{
36
- assert (size != 0 ); // The empty tuple is statically allocated.
37
36
if (size < 0 ) {
38
37
PyErr_BadInternalCall ();
39
38
return NULL ;
@@ -53,13 +52,23 @@ tuple_alloc(Py_ssize_t size)
53
52
return op ;
54
53
}
55
54
55
+ static inline PyTupleObject * maybe_freelist_get_empty_singleton (void );
56
+
56
57
static inline PyObject *
57
58
tuple_get_empty (void )
58
59
{
59
- Py_INCREF (& _Py_SINGLETON (tuple_empty ));
60
- return (PyObject * )& _Py_SINGLETON (tuple_empty );
60
+ PyTupleObject * op = maybe_freelist_get_empty_singleton ();
61
+ if (op != NULL ) {
62
+ Py_INCREF (op );
63
+ }
64
+ else {
65
+ op = PyObject_GC_NewVar (PyTupleObject , & PyTuple_Type , 0 );
66
+ _PyObject_GC_TRACK (op );
67
+ }
68
+ return (PyObject * )op ;
61
69
}
62
70
71
+ // Note that tuple subclasses have their own empty instances.
63
72
64
73
PyObject *
65
74
PyTuple_New (Py_ssize_t size )
@@ -181,26 +190,14 @@ PyTuple_Pack(Py_ssize_t n, ...)
181
190
static void
182
191
tupledealloc (PyTupleObject * op )
183
192
{
184
- if (Py_SIZE (op ) == 0 ) {
185
- /* The empty tuple is statically allocated. */
186
- if (op == & _Py_SINGLETON (tuple_empty )) {
187
- #ifdef Py_DEBUG
188
- _Py_FatalRefcountError ("deallocating the empty tuple singleton" );
189
- #else
190
- return ;
191
- #endif
192
- }
193
- /* tuple subclasses have their own empty instances. */
194
- assert (!PyTuple_CheckExact (op ));
195
- }
196
-
197
193
PyObject_GC_UnTrack (op );
198
194
Py_TRASHCAN_BEGIN (op , tupledealloc )
199
195
200
196
Py_ssize_t i = Py_SIZE (op );
201
197
while (-- i >= 0 ) {
202
198
Py_XDECREF (op -> ob_item [i ]);
203
199
}
200
+ // This will abort on the empty singleton (if there is one).
204
201
if (!maybe_freelist_push (op )) {
205
202
Py_TYPE (op )-> tp_free ((PyObject * )op );
206
203
}
@@ -931,9 +928,6 @@ _PyTuple_Resize(PyObject **pv, Py_ssize_t newsize)
931
928
return 0 ;
932
929
}
933
930
if (oldsize == 0 ) {
934
- #ifdef Py_DEBUG
935
- assert (v == & _Py_SINGLETON (tuple_empty ));
936
- #endif
937
931
/* The empty tuple is statically allocated so we never
938
932
resize it in-place. */
939
933
Py_DECREF (v );
@@ -990,20 +984,29 @@ _PyTuple_InitTypes(PyInterpreterState *interp)
990
984
return _PyStatus_OK ();
991
985
}
992
986
993
- static void maybe_freelist_clear (PyInterpreterState * );
994
- static void maybe_freelist_fini (PyInterpreterState * );
987
+ static int maybe_freelist_init_empty_tuple (PyInterpreterState * );
988
+
989
+ PyStatus
990
+ _PyTuple_InitGlobalObjects (PyInterpreterState * interp )
991
+ {
992
+ if (maybe_freelist_init_empty_tuple (interp ) < 0 ) {
993
+ return _PyStatus_NO_MEMORY ();
994
+ }
995
+ return _PyStatus_OK ();
996
+ }
997
+
998
+ static void maybe_freelist_clear (PyInterpreterState * , int );
995
999
996
1000
void
997
1001
_PyTuple_Fini (PyInterpreterState * interp )
998
1002
{
999
- maybe_freelist_clear (interp );
1000
- maybe_freelist_fini (interp );
1003
+ maybe_freelist_clear (interp , 1 );
1001
1004
}
1002
1005
1003
1006
void
1004
1007
_PyTuple_ClearFreeList (PyInterpreterState * interp )
1005
1008
{
1006
- maybe_freelist_clear (interp );
1009
+ maybe_freelist_clear (interp , 0 );
1007
1010
}
1008
1011
1009
1012
/*********************** Tuple Iterator **************************/
@@ -1160,17 +1163,56 @@ tuple_iter(PyObject *seq)
1160
1163
#define STATE (interp->tuple)
1161
1164
#define FREELIST_FINALIZED (STATE.numfree[0] < 0)
1162
1165
1166
+ static int
1167
+ maybe_freelist_init_empty_tuple (PyInterpreterState * interp )
1168
+ {
1169
+ #if PyTuple_NFREELISTS > 0
1170
+ assert (STATE .free_list [0 ] == NULL );
1171
+
1172
+ PyTupleObject * op = PyObject_GC_NewVar (PyTupleObject , & PyTuple_Type , 0 );
1173
+ if (op == NULL ) {
1174
+ return -1 ;
1175
+ }
1176
+ // The empty tuple singleton is not tracked by the GC.
1177
+ // It does not contain any Python object.
1178
+
1179
+ STATE .free_list [0 ] = op ;
1180
+ assert (STATE .numfree [0 ] == 0 );
1181
+ STATE .numfree [0 ] = 1 ;
1182
+ #endif
1183
+ return 0 ;
1184
+ }
1185
+
1186
+ static inline PyTupleObject *
1187
+ maybe_freelist_get_empty_singleton (void )
1188
+ {
1189
+ #if PyTuple_NFREELISTS > 0
1190
+ PyTupleObject * op = STATE .free_list [0 ];
1191
+ // maybe_freelist_get_empty_singleton() must not be called
1192
+ // before maybe_freelist_init_empty_tuple()
1193
+ // or after maybe_freelist_clear(fini=1).
1194
+ assert (op != NULL );
1195
+ #ifdef Py_DEBUG
1196
+ assert (STATE .numfree [0 ] == 1 );
1197
+ #endif
1198
+ return (PyObject * ) op ;
1199
+ #else
1200
+ return NULL ;
1201
+ #endif
1202
+ }
1203
+
1163
1204
static inline PyTupleObject *
1164
1205
maybe_freelist_pop (Py_ssize_t size )
1165
1206
{
1166
- #if PyTuple_MAXSAVESIZE > 0
1207
+ #if PyTuple_NFREELISTS > 0
1167
1208
PyInterpreterState * interp = _PyInterpreterState_GET ();
1168
1209
#ifdef Py_DEBUG
1169
1210
/* maybe_freelist_pop() must not be called after maybe_freelist_fini(). */
1170
1211
assert (!FREELIST_FINALIZED );
1171
1212
#endif
1172
- Py_ssize_t index = size - 1 ;
1173
- if (index < PyTuple_MAXSAVESIZE ) {
1213
+ assert (size > 0 );
1214
+ if (size < PyTuple_MAXSAVESIZE ) {
1215
+ Py_ssize_t index = size ;
1174
1216
PyTupleObject * op = STATE .free_list [index ];
1175
1217
if (op != NULL ) {
1176
1218
/* op is the head of a linked list, with the first item
@@ -1196,14 +1238,24 @@ maybe_freelist_pop(Py_ssize_t size)
1196
1238
static inline int
1197
1239
maybe_freelist_push (PyTupleObject * op )
1198
1240
{
1199
- #if PyTuple_MAXSAVESIZE > 0
1241
+ #if PyTuple_NFREELISTS > 0
1200
1242
PyInterpreterState * interp = _PyInterpreterState_GET ();
1201
1243
#ifdef Py_DEBUG
1202
1244
/* maybe_freelist_push() must not be called after maybe_freelist_fini(). */
1203
1245
assert (!FREELIST_FINALIZED );
1204
1246
#endif
1205
- Py_ssize_t index = Py_SIZE (op ) - 1 ;
1206
- if (index < PyTuple_MAXSAVESIZE
1247
+ if (Py_SIZE (op ) == 0 ) {
1248
+ #ifdef Py_DEBUG
1249
+ // The empty tuple singleton must only be deallocated by
1250
+ // maybe_freelist_fini(): not before, not after.
1251
+ if (op == STATE .free_list [0 ] && STATE .numfree [0 ] < 0 ) {
1252
+ _Py_FatalRefcountError ("deallocating the empty tuple singleton" );
1253
+ }
1254
+ #endif
1255
+ return 1 ;
1256
+ }
1257
+ Py_ssize_t index = Py_SIZE (op );
1258
+ if (index < PyTuple_NFREELISTS
1207
1259
&& STATE .numfree [index ] < PyTuple_MAXFREELIST
1208
1260
&& Py_IS_TYPE (op , & PyTuple_Type ))
1209
1261
{
@@ -1219,13 +1271,26 @@ maybe_freelist_push(PyTupleObject *op)
1219
1271
}
1220
1272
1221
1273
static void
1222
- maybe_freelist_clear (PyInterpreterState * interp )
1274
+ maybe_freelist_clear (PyInterpreterState * interp , int fini )
1223
1275
{
1224
- #if PyTuple_MAXSAVESIZE > 0
1225
- for (Py_ssize_t i = 0 ; i < PyTuple_MAXSAVESIZE ; i ++ ) {
1276
+ #if PyTuple_NFREELISTS > 0
1277
+ // The empty tuple singleton is only cleared during finalization.
1278
+ if (fini ) {
1279
+ assert (!_PyObject_GC_IS_TRACKED (STATE .free_list [0 ]));
1280
+ // XXX Is this right?
1281
+ assert (STATE .free_list [0 ].ob_item [0 ] == NULL );
1282
+ #ifdef Py_DEBUG
1283
+ STATE .numfree [0 ] = 0 ;
1284
+ #endif
1285
+ Py_CLEAR (STATE .free_list [0 ]);
1286
+ #ifdef Py_DEBUG
1287
+ STATE .numfree [0 ] = -1 ;
1288
+ #endif
1289
+ }
1290
+ for (Py_ssize_t i = 1 ; i < PyTuple_NFREELISTS ; i ++ ) {
1226
1291
PyTupleObject * p = STATE .free_list [i ];
1227
1292
STATE .free_list [i ] = NULL ;
1228
- STATE .numfree [i ] = 0 ;
1293
+ STATE .numfree [i ] = fini ? -1 : 0 ;
1229
1294
while (p ) {
1230
1295
PyTupleObject * q = p ;
1231
1296
p = (PyTupleObject * )(p -> ob_item [0 ]);
@@ -1235,24 +1300,14 @@ maybe_freelist_clear(PyInterpreterState *interp)
1235
1300
#endif
1236
1301
}
1237
1302
1238
- static void
1239
- maybe_freelist_fini (PyInterpreterState * interp )
1240
- {
1241
- #if PyTuple_MAXSAVESIZE > 0
1242
- for (Py_ssize_t i = 0 ; i < PyTuple_MAXSAVESIZE ; i ++ ) {
1243
- STATE .numfree [i ] = -1 ;
1244
- }
1245
- #endif
1246
- }
1247
-
1248
1303
/* Print summary info about the state of the optimized allocator */
1249
1304
void
1250
1305
_PyTuple_DebugMallocStats (FILE * out )
1251
1306
{
1252
- #if PyTuple_MAXSAVESIZE > 0
1307
+ #if PyTuple_NFREELISTS > 0
1253
1308
PyInterpreterState * interp = _PyInterpreterState_GET ();
1254
- for (int i = 0 ; i < PyTuple_MAXSAVESIZE ; i ++ ) {
1255
- int len = i + 1 ;
1309
+ for (int i = 0 ; i < PyTuple_NFREELISTS ; i ++ ) {
1310
+ int len = i ;
1256
1311
char buf [128 ];
1257
1312
PyOS_snprintf (buf , sizeof (buf ),
1258
1313
"free %d-sized PyTupleObject" , len );
0 commit comments