@@ -31,96 +31,8 @@ get_list_freelist(void)
31
31
}
32
32
#endif
33
33
34
- #ifdef Py_GIL_DISABLED
35
- static size_t
36
- list_good_size (Py_ssize_t size )
37
- {
38
- // 4, 8, 16, 24, 32, 40, 48, 64, 80, ...
39
- // NOTE: we add one here so that the rounding accounts for the "allocated"
40
- size_t reqsize = (size_t )size + 1 ;
41
- if (reqsize <= 4 ) {
42
- reqsize = 4 ;
43
- }
44
- else if (reqsize <= 48 ) {
45
- reqsize = (reqsize + 7 ) & ~7 ;
46
- }
47
- else {
48
- reqsize = (reqsize + 15 ) & ~15 ;
49
- if (reqsize <= MI_MEDIUM_OBJ_WSIZE_MAX ) {
50
- reqsize = mi_good_size (reqsize * sizeof (PyObject * ))/sizeof (PyObject * );
51
- }
52
- else {
53
- // ensure geometric spacing for large arrays
54
- size_t shift = mi_bsr (reqsize ) - 2 ;
55
- reqsize = ((reqsize >> shift ) + 1 ) << shift ;
56
- }
57
- }
58
- return reqsize - 1 ;
59
- }
60
-
61
- static PyObject * *
62
- list_allocate_items (size_t capacity )
63
- {
64
- if (capacity > PY_SSIZE_T_MAX / sizeof (PyObject * ) - 1 ) {
65
- return NULL ;
66
- }
67
- PyObject * * items = PyMem_Malloc (capacity * sizeof (PyObject * ));
68
- return items ;
69
- }
70
-
71
- /* Ensure ob_item has room for at least newsize elements, and set
72
- * ob_size to newsize. If newsize > ob_size on entry, the content
73
- * of the new slots at exit is undefined heap trash; it's the caller's
74
- * responsibility to overwrite them with sane values.
75
- * The number of allocated elements may grow, shrink, or stay the same.
76
- * Note that self->ob_item may change, and even if newsize is less
77
- * than ob_size on entry.
78
- */
79
- static int
80
- list_ensure_capacity_slow (PyListObject * self , Py_ssize_t base , Py_ssize_t extra )
81
- {
82
- if (base > PY_SSIZE_T_MAX /(Py_ssize_t )sizeof (PyObject * ) - extra ) {
83
- PyErr_NoMemory ();
84
- return -1 ;
85
- }
86
-
87
- Py_ssize_t reqsize = base + extra ;
88
- Py_ssize_t allocated = self -> allocated ;
89
- if (allocated >= reqsize ) {
90
- assert (self -> ob_item != NULL || reqsize == 0 );
91
- return 0 ;
92
- }
93
-
94
- if (!_Py_IsOwnedByCurrentThread ((PyObject * )self )) {
95
- _PyObject_GC_SET_SHARED (self );
96
- }
97
-
98
- size_t capacity = list_good_size (reqsize );
99
- PyObject * * items = list_allocate_items (capacity );
100
- if (items == NULL ) {
101
- PyErr_NoMemory ();
102
- return -1 ;
103
- }
104
- PyObject * * old = self -> ob_item ;
105
- if (self -> ob_item ) {
106
- memcpy (items , self -> ob_item , allocated * sizeof (PyObject * ));
107
- }
108
- _Py_atomic_store_ptr_release (& self -> ob_item , items );
109
- self -> allocated = capacity ;
110
- if (old ) {
111
- if (_PyObject_GC_IS_SHARED (self )) {
112
- _PyMem_FreeDelayed (old );
113
- }
114
- else {
115
- PyMem_Free (old );
116
- }
117
- }
118
- return 0 ;
119
- }
120
- #endif
121
-
122
34
static PyListObject *
123
- list_new (Py_ssize_t size )
35
+ list_new_prealloc (Py_ssize_t size )
124
36
{
125
37
PyListObject * op ;
126
38
assert (size >= 0 );
@@ -145,13 +57,8 @@ list_new(Py_ssize_t size)
145
57
op -> allocated = 0 ;
146
58
}
147
59
else {
148
- #ifdef Py_GIL_DISABLED
149
- size_t capacity = list_good_size (size );
150
- PyObject * * items = list_allocate_items (capacity );
151
- #else
152
60
size_t capacity = size ;
153
61
PyObject * * items = (PyObject * * ) PyMem_Calloc (size , sizeof (PyObject * ));
154
- #endif
155
62
if (items == NULL ) {
156
63
op -> ob_item = NULL ;
157
64
Py_DECREF (op );
@@ -234,14 +141,8 @@ list_resize(PyListObject *self, Py_ssize_t newsize)
234
141
}
235
142
236
143
static int
237
- list_ensure_capacity (PyListObject * self , Py_ssize_t base , Py_ssize_t extra )
144
+ list_preallocate_exact (PyListObject * self , Py_ssize_t size )
238
145
{
239
- #ifdef Py_GIL_DISABLED
240
- if (base > self -> allocated - extra ) {
241
- return list_ensure_capacity_slow (self , base , extra );
242
- }
243
- #else
244
- Py_ssize_t size = extra ;
245
146
assert (self -> ob_item == NULL );
246
147
assert (size > 0 );
247
148
@@ -258,7 +159,6 @@ list_ensure_capacity(PyListObject *self, Py_ssize_t base, Py_ssize_t extra)
258
159
}
259
160
self -> ob_item = items ;
260
161
self -> allocated = size ;
261
- #endif
262
162
return 0 ;
263
163
}
264
164
@@ -297,7 +197,7 @@ PyList_New(Py_ssize_t size)
297
197
PyErr_BadInternalCall ();
298
198
return NULL ;
299
199
}
300
- PyListObject * op = list_new (size );
200
+ PyListObject * op = list_new_prealloc (size );
301
201
if (op && op -> ob_item ) {
302
202
PyObject * * items = op -> ob_item ;
303
203
for (Py_ssize_t i = 0 , n = op -> allocated ; i < n ; i ++ ) {
@@ -446,7 +346,7 @@ PyList_Insert(PyObject *op, Py_ssize_t where, PyObject *newitem)
446
346
int
447
347
_PyList_AppendTakeRefListResize (PyListObject * self , PyObject * newitem )
448
348
{
449
- Py_ssize_t len = PyList_GET_SIZE (self );
349
+ Py_ssize_t len = Py_SIZE (self );
450
350
assert (self -> allocated == -1 || self -> allocated == len );
451
351
if (list_resize (self , len + 1 ) < 0 ) {
452
352
Py_DECREF (newitem );
@@ -624,7 +524,7 @@ list_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh)
624
524
if (len <= 0 ) {
625
525
return PyList_New (0 );
626
526
}
627
- np = (PyListObject * ) list_new (len );
527
+ np = (PyListObject * ) list_new_prealloc (len );
628
528
if (np == NULL )
629
529
return NULL ;
630
530
@@ -676,7 +576,7 @@ list_concat_lock_held(PyListObject *a, PyListObject *b)
676
576
if (size == 0 ) {
677
577
return PyList_New (0 );
678
578
}
679
- np = (PyListObject * ) list_new (size );
579
+ np = (PyListObject * ) list_new_prealloc (size );
680
580
if (np == NULL ) {
681
581
return NULL ;
682
582
}
@@ -726,7 +626,7 @@ list_repeat_lock_held(PyListObject *a, Py_ssize_t n)
726
626
return PyErr_NoMemory ();
727
627
Py_ssize_t output_size = input_size * n ;
728
628
729
- PyListObject * np = (PyListObject * ) list_new (output_size );
629
+ PyListObject * np = (PyListObject * ) list_new_prealloc (output_size );
730
630
if (np == NULL )
731
631
return NULL ;
732
632
@@ -1093,7 +993,7 @@ list_extend_fast(PyListObject *self, PyObject *iterable)
1093
993
// an overflow on any relevant platform.
1094
994
assert (m < PY_SSIZE_T_MAX - n );
1095
995
if (self -> ob_item == NULL ) {
1096
- if (list_ensure_capacity (self , m , n ) < 0 ) {
996
+ if (list_preallocate_exact (self , n ) < 0 ) {
1097
997
return -1 ;
1098
998
}
1099
999
Py_SET_SIZE (self , n );
@@ -1141,7 +1041,7 @@ list_extend_iter(PyListObject *self, PyObject *iterable)
1141
1041
*/
1142
1042
}
1143
1043
else if (self -> ob_item == NULL ) {
1144
- if (n && list_ensure_capacity (self , m , n ) < 0 )
1044
+ if (n && list_preallocate_exact (self , n ) < 0 )
1145
1045
goto error ;
1146
1046
}
1147
1047
else {
@@ -3218,7 +3118,7 @@ list_subscript(PyObject* _self, PyObject* item)
3218
3118
return list_slice (self , start , stop );
3219
3119
}
3220
3120
else {
3221
- result = (PyObject * )list_new (slicelength );
3121
+ result = (PyObject * )list_new_prealloc (slicelength );
3222
3122
if (!result ) return NULL ;
3223
3123
3224
3124
src = self -> ob_item ;
0 commit comments