@@ -233,17 +233,14 @@ static inline int
233233maybe_small_list_freelist_push (PyObject * self )
234234{
235235 assert (PyList_CheckExact (self ));
236- assert (0 );
237236
238237 PyListObject * op = (PyListObject * )self ;
239238 PyObject * * ob_item = _Py_atomic_load_ptr (& op -> ob_item );
240239
241-
242- Py_ssize_t cap = op -> allocated ; // what is the difference between allocated and capacity in the FT build?
243-
244- printf ("maybe_small_list_freelist_push: cap %d\n" , cap );
245- if (cap < PyList_MAXSAVESIZE ) {
246- return _Py_FREELIST_PUSH (small_lists [cap ], self , Py_small_lists_MAXFREELIST );
240+ Py_ssize_t allocated = op -> allocated ;
241+ if (allocated < PyList_MAXSAVESIZE ) {
242+ return _Py_FREELIST_PUSH (small_lists [allocated ], self , Py_small_lists_MAXFREELIST );
243+ //printf("maybe_small_list_freelist_push: allocated %d (mod %d), size %d, id %p\n", (int)allocated, op->allocated, (int)PyList_Size(self), (void *)self);
247244 }
248245 return 0 ;
249246}
@@ -257,19 +254,23 @@ PyList_New(Py_ssize_t size)
257254 return NULL ;
258255 }
259256
260- PyListObject * op ;
257+ PyListObject * op = 0 ;
261258
262- if (size < PyList_MAXSAVESIZE ) {
263- op = 0 ;
264- //op = (PyListObject *)_Py_FREELIST_POP(PyLongObject, small_lists[size]);
265- }
266- if (op ) {
267- // allocated with ob_item still allocated. we do need to set to zero?
268- if ( size > 0 ) {
269- memset (& op -> ob_item , 0 , size * sizeof (PyObject * ));
259+ if (size < PyList_MAXSAVESIZE ) {
260+ op = (PyListObject * )_Py_FREELIST_POP (PyLongObject , small_lists [size ]);
261+ if (op ) {
262+ // allocated with ob_item still allocated, but we need to set the other fields
263+ Py_SET_SIZE (op , size );
264+ if ( size > 0 ) {
265+ memset (op -> ob_item , 0 , size * sizeof (PyObject * ));
266+ }
267+ //printf("obtained list from small_lists[%d] (id %p, op->allocated %d, size %d, PyList_Size %d)\n", (int) size, op, (int)op->allocated, (int)size, (int)PyList_Size( (PyObject*)op));
268+ assert (op -> allocated >= size );
270269 }
270+ op = 0 ;
271271 }
272- else {
272+ if (!op ) {
273+ // do we still need this freelist? if so, we could store it at small_lists[PyList_MAXSAVESIZE-1] with some special casing
273274 op = _Py_FREELIST_POP (PyListObject , lists );
274275 if (op == NULL ) {
275276 op = PyObject_GC_New (PyListObject , & PyList_Type );
@@ -551,12 +552,13 @@ PyList_Append(PyObject *op, PyObject *newitem)
551552
552553/* Methods */
553554
554- void small_list_freelist_free (PyObject * self )
555+ void small_list_freelist_free (void * obj )
555556{
556- assert ( 0 ) ;
557- printf ( "small_list_freelist_free\n" );
558- assert (PyLong_CheckExact (self ));
557+ PyObject * self = ( PyObject * ) obj ;
558+
559+ assert (PyList_CheckExact (self ));
559560 PyListObject * op = (PyListObject * )self ;
561+ //printf("small_list_freelist_free: (op->allocated %d, size %d)\n", (int)op->allocated, (int)PyList_Size(self));
560562 if (op -> ob_item != NULL ) {
561563 free_list_items (op -> ob_item , false);
562564 }
@@ -580,19 +582,22 @@ list_dealloc(PyObject *self)
580582 Py_XDECREF (op -> ob_item [i ]);
581583 }
582584 }
583- if (0 && maybe_small_list_freelist_push (self ) ) {
584- return ;
585+ if (PyList_CheckExact (op )) {
586+ if ( maybe_small_list_freelist_push (self ) ) {
587+ goto end ;
588+ }
585589 }
586-
587590 if (op -> ob_item != NULL ) {
588591 free_list_items (op -> ob_item , false);
589592 }
590593 if (PyList_CheckExact (op )) {
591- _Py_FREELIST_FREE (lists , op , PyObject_GC_Del );
594+ _Py_FREELIST_FREE (lists , op , PyObject_GC_Del );
592595 }
593596 else {
594597 PyObject_GC_Del (op );
595598 }
599+
600+ end :
596601 Py_TRASHCAN_END
597602}
598603
0 commit comments