@@ -14,28 +14,6 @@ class tuple "PyTupleObject *" "&PyTuple_Type"
14
14
15
15
#include "clinic/tupleobject.c.h"
16
16
17
- /* Speed optimization to avoid frequent malloc/free of small tuples */
18
- #ifndef PyTuple_MAXSAVESIZE
19
- #define PyTuple_MAXSAVESIZE 20 /* Largest tuple to save on free list */
20
- #endif
21
- #ifndef PyTuple_MAXFREELIST
22
- #define PyTuple_MAXFREELIST 2000 /* Maximum number of tuples of each size to save */
23
- #endif
24
-
25
- /* bpo-40521: tuple free lists are shared by all interpreters. */
26
- #ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
27
- # undef PyTuple_MAXSAVESIZE
28
- # define PyTuple_MAXSAVESIZE 0
29
- #endif
30
-
31
- #if PyTuple_MAXSAVESIZE > 0
32
- /* Entries 1 up to PyTuple_MAXSAVESIZE are free lists, entry 0 is the empty
33
- tuple () of which at most one instance will be allocated.
34
- */
35
- static PyTupleObject * free_list [PyTuple_MAXSAVESIZE ];
36
- static int numfree [PyTuple_MAXSAVESIZE ];
37
- #endif
38
-
39
17
static inline void
40
18
tuple_gc_track (PyTupleObject * op )
41
19
{
47
25
_PyTuple_DebugMallocStats (FILE * out )
48
26
{
49
27
#if PyTuple_MAXSAVESIZE > 0
50
- int i ;
51
- char buf [128 ];
52
- for (i = 1 ; i < PyTuple_MAXSAVESIZE ; i ++ ) {
28
+ PyInterpreterState * interp = _PyInterpreterState_GET ();
29
+ struct _Py_tuple_state * state = & interp -> tuple ;
30
+ for (int i = 1 ; i < PyTuple_MAXSAVESIZE ; i ++ ) {
31
+ char buf [128 ];
53
32
PyOS_snprintf (buf , sizeof (buf ),
54
33
"free %d-sized PyTupleObject" , i );
55
- _PyDebugAllocatorStats (out ,
56
- buf ,
57
- numfree [i ], _PyObject_VAR_SIZE (& PyTuple_Type , i ));
34
+ _PyDebugAllocatorStats (out , buf , state -> numfree [i ],
35
+ _PyObject_VAR_SIZE (& PyTuple_Type , i ));
58
36
}
59
37
#endif
60
38
}
@@ -68,18 +46,18 @@ _PyTuple_DebugMallocStats(FILE *out)
68
46
which wraps this function).
69
47
*/
70
48
static PyTupleObject *
71
- tuple_alloc (Py_ssize_t size )
49
+ tuple_alloc (struct _Py_tuple_state * state , Py_ssize_t size )
72
50
{
73
51
PyTupleObject * op ;
74
52
if (size < 0 ) {
75
53
PyErr_BadInternalCall ();
76
54
return NULL ;
77
55
}
78
56
#if PyTuple_MAXSAVESIZE > 0
79
- if (size < PyTuple_MAXSAVESIZE && (op = free_list [size ]) != NULL ) {
57
+ if (size < PyTuple_MAXSAVESIZE && (op = state -> free_list [size ]) != NULL ) {
80
58
assert (size != 0 );
81
- free_list [size ] = (PyTupleObject * ) op -> ob_item [0 ];
82
- numfree [size ]-- ;
59
+ state -> free_list [size ] = (PyTupleObject * ) op -> ob_item [0 ];
60
+ state -> numfree [size ]-- ;
83
61
/* Inline PyObject_InitVar */
84
62
#ifdef Py_TRACE_REFS
85
63
Py_SET_SIZE (op , size );
@@ -107,13 +85,15 @@ PyTuple_New(Py_ssize_t size)
107
85
{
108
86
PyTupleObject * op ;
109
87
#if PyTuple_MAXSAVESIZE > 0
110
- if (size == 0 && free_list [0 ]) {
111
- op = free_list [0 ];
88
+ PyInterpreterState * interp = _PyInterpreterState_GET ();
89
+ struct _Py_tuple_state * state = & interp -> tuple ;
90
+ if (size == 0 && state -> free_list [0 ]) {
91
+ op = state -> free_list [0 ];
112
92
Py_INCREF (op );
113
93
return (PyObject * ) op ;
114
94
}
115
95
#endif
116
- op = tuple_alloc (size );
96
+ op = tuple_alloc (state , size );
117
97
if (op == NULL ) {
118
98
return NULL ;
119
99
}
@@ -122,8 +102,8 @@ PyTuple_New(Py_ssize_t size)
122
102
}
123
103
#if PyTuple_MAXSAVESIZE > 0
124
104
if (size == 0 ) {
125
- free_list [0 ] = op ;
126
- ++ numfree [0 ];
105
+ state -> free_list [0 ] = op ;
106
+ ++ state -> numfree [0 ];
127
107
Py_INCREF (op ); /* extra INCREF so that this is never freed */
128
108
}
129
109
#endif
@@ -210,8 +190,11 @@ PyTuple_Pack(Py_ssize_t n, ...)
210
190
return PyTuple_New (0 );
211
191
}
212
192
193
+ PyInterpreterState * interp = _PyInterpreterState_GET ();
194
+ struct _Py_tuple_state * state = & interp -> tuple ;
195
+
213
196
va_start (vargs , n );
214
- PyTupleObject * result = tuple_alloc (n );
197
+ PyTupleObject * result = tuple_alloc (state , n );
215
198
if (result == NULL ) {
216
199
va_end (vargs );
217
200
return NULL ;
@@ -233,22 +216,24 @@ PyTuple_Pack(Py_ssize_t n, ...)
233
216
static void
234
217
tupledealloc (PyTupleObject * op )
235
218
{
236
- Py_ssize_t i ;
237
219
Py_ssize_t len = Py_SIZE (op );
238
220
PyObject_GC_UnTrack (op );
239
221
Py_TRASHCAN_BEGIN (op , tupledealloc )
240
222
if (len > 0 ) {
241
- i = len ;
242
- while (-- i >= 0 )
223
+ Py_ssize_t i = len ;
224
+ while (-- i >= 0 ) {
243
225
Py_XDECREF (op -> ob_item [i ]);
226
+ }
244
227
#if PyTuple_MAXSAVESIZE > 0
228
+ PyInterpreterState * interp = _PyInterpreterState_GET ();
229
+ struct _Py_tuple_state * state = & interp -> tuple ;
245
230
if (len < PyTuple_MAXSAVESIZE &&
246
- numfree [len ] < PyTuple_MAXFREELIST &&
231
+ state -> numfree [len ] < PyTuple_MAXFREELIST &&
247
232
Py_IS_TYPE (op , & PyTuple_Type ))
248
233
{
249
- op -> ob_item [0 ] = (PyObject * ) free_list [len ];
250
- numfree [len ]++ ;
251
- free_list [len ] = op ;
234
+ op -> ob_item [0 ] = (PyObject * ) state -> free_list [len ];
235
+ state -> numfree [len ]++ ;
236
+ state -> free_list [len ] = op ;
252
237
goto done ; /* return */
253
238
}
254
239
#endif
@@ -423,7 +408,9 @@ _PyTuple_FromArray(PyObject *const *src, Py_ssize_t n)
423
408
return PyTuple_New (0 );
424
409
}
425
410
426
- PyTupleObject * tuple = tuple_alloc (n );
411
+ PyInterpreterState * interp = _PyInterpreterState_GET ();
412
+ struct _Py_tuple_state * state = & interp -> tuple ;
413
+ PyTupleObject * tuple = tuple_alloc (state , n );
427
414
if (tuple == NULL ) {
428
415
return NULL ;
429
416
}
@@ -481,7 +468,8 @@ tupleconcat(PyTupleObject *a, PyObject *bb)
481
468
Py_TYPE (bb )-> tp_name );
482
469
return NULL ;
483
470
}
484
- #define b ((PyTupleObject *)bb)
471
+ PyTupleObject * b = (PyTupleObject * )bb ;
472
+
485
473
if (Py_SIZE (b ) == 0 && PyTuple_CheckExact (a )) {
486
474
Py_INCREF (a );
487
475
return (PyObject * )a ;
@@ -492,7 +480,9 @@ tupleconcat(PyTupleObject *a, PyObject *bb)
492
480
return PyTuple_New (0 );
493
481
}
494
482
495
- np = tuple_alloc (size );
483
+ PyInterpreterState * interp = _PyInterpreterState_GET ();
484
+ struct _Py_tuple_state * state = & interp -> tuple ;
485
+ np = tuple_alloc (state , size );
496
486
if (np == NULL ) {
497
487
return NULL ;
498
488
}
@@ -512,7 +502,6 @@ tupleconcat(PyTupleObject *a, PyObject *bb)
512
502
}
513
503
tuple_gc_track (np );
514
504
return (PyObject * )np ;
515
- #undef b
516
505
}
517
506
518
507
static PyObject *
@@ -536,7 +525,9 @@ tuplerepeat(PyTupleObject *a, Py_ssize_t n)
536
525
if (n > PY_SSIZE_T_MAX / Py_SIZE (a ))
537
526
return PyErr_NoMemory ();
538
527
size = Py_SIZE (a ) * n ;
539
- np = tuple_alloc (size );
528
+ PyInterpreterState * interp = _PyInterpreterState_GET ();
529
+ struct _Py_tuple_state * state = & interp -> tuple ;
530
+ np = tuple_alloc (state , size );
540
531
if (np == NULL )
541
532
return NULL ;
542
533
p = np -> ob_item ;
@@ -801,7 +792,9 @@ tuplesubscript(PyTupleObject* self, PyObject* item)
801
792
return (PyObject * )self ;
802
793
}
803
794
else {
804
- PyTupleObject * result = tuple_alloc (slicelength );
795
+ PyInterpreterState * interp = _PyInterpreterState_GET ();
796
+ struct _Py_tuple_state * state = & interp -> tuple ;
797
+ PyTupleObject * result = tuple_alloc (state , slicelength );
805
798
if (!result ) return NULL ;
806
799
807
800
src = self -> ob_item ;
@@ -963,13 +956,14 @@ _PyTuple_Resize(PyObject **pv, Py_ssize_t newsize)
963
956
}
964
957
965
958
void
966
- _PyTuple_ClearFreeList (void )
959
+ _PyTuple_ClearFreeList (PyThreadState * tstate )
967
960
{
968
961
#if PyTuple_MAXSAVESIZE > 0
962
+ struct _Py_tuple_state * state = & tstate -> interp -> tuple ;
969
963
for (Py_ssize_t i = 1 ; i < PyTuple_MAXSAVESIZE ; i ++ ) {
970
- PyTupleObject * p = free_list [i ];
971
- free_list [i ] = NULL ;
972
- numfree [i ] = 0 ;
964
+ PyTupleObject * p = state -> free_list [i ];
965
+ state -> free_list [i ] = NULL ;
966
+ state -> numfree [i ] = 0 ;
973
967
while (p ) {
974
968
PyTupleObject * q = p ;
975
969
p = (PyTupleObject * )(p -> ob_item [0 ]);
@@ -981,14 +975,15 @@ _PyTuple_ClearFreeList(void)
981
975
}
982
976
983
977
void
984
- _PyTuple_Fini (void )
978
+ _PyTuple_Fini (PyThreadState * tstate )
985
979
{
986
980
#if PyTuple_MAXSAVESIZE > 0
981
+ struct _Py_tuple_state * state = & tstate -> interp -> tuple ;
987
982
/* empty tuples are used all over the place and applications may
988
983
* rely on the fact that an empty tuple is a singleton. */
989
- Py_CLEAR (free_list [0 ]);
984
+ Py_CLEAR (state -> free_list [0 ]);
990
985
991
- _PyTuple_ClearFreeList ();
986
+ _PyTuple_ClearFreeList (tstate );
992
987
#endif
993
988
}
994
989
0 commit comments