@@ -263,6 +263,65 @@ PyList_GetItemRef(PyObject *op, Py_ssize_t i)
263
263
return Py_NewRef (PyList_GET_ITEM (op , i ));
264
264
}
265
265
266
+ #ifdef Py_GIL_DISABLED
267
+
268
+ static PyObject *
269
+ list_item_impl (PyListObject * self , Py_ssize_t idx , PyObject * dead )
270
+ {
271
+ PyObject * item = NULL ;
272
+ Py_BEGIN_CRITICAL_SECTION (self );
273
+ if (!_PyObject_GC_IS_SHARED (self )) {
274
+ _PyObject_GC_SET_SHARED (self );
275
+ }
276
+ Py_ssize_t size = Py_SIZE (self );
277
+ if (!valid_index (idx , size )) {
278
+ goto exit ;
279
+ }
280
+ item = Py_NewRef (self -> ob_item [idx ]);
281
+ exit :
282
+ Py_END_CRITICAL_SECTION ();
283
+ return item ;
284
+ }
285
+
286
+ static inline PyObject *
287
+ list_get_item_ref (PyListObject * op , Py_ssize_t i )
288
+ {
289
+ if (!_Py_IsOwnedByCurrentThread ((PyObject * )op ) && !_PyObject_GC_IS_SHARED (op )) {
290
+ return list_item_impl (op , i , NULL );
291
+ }
292
+ // Need atomic operation for the getting size.
293
+ Py_ssize_t size = _Py_atomic_load_ssize_relaxed (& _PyVarObject_CAST (op )-> ob_size );
294
+ if (!valid_index (i , size )) {
295
+ return NULL ;
296
+ }
297
+ PyObject * * ob_item = _Py_atomic_load_ptr (& op -> ob_item );
298
+ if (ob_item == NULL ) {
299
+ return NULL ;
300
+ }
301
+ Py_ssize_t cap = _Py_atomic_load_ssize_relaxed (& op -> allocated );
302
+ if (!valid_index (i , cap )) {
303
+ return NULL ;
304
+ }
305
+ PyObject * item = _Py_atomic_load_ptr (& ob_item [i ]);
306
+ if (mi_unlikely (!item )) {
307
+ return list_item_impl (op , i , NULL );
308
+ }
309
+ if (mi_likely (_Py_TryIncrefFast (item ))) {
310
+ goto compare_ob_item ;
311
+ }
312
+ if (!_Py_TryIncRefShared (item )) {
313
+ return list_item_impl (op , i , item );
314
+ }
315
+ if (mi_unlikely (item != _Py_atomic_load_ptr (& ob_item [i ]))) {
316
+ return list_item_impl (op , i , item );
317
+ }
318
+ compare_ob_item :
319
+ if (mi_unlikely (ob_item != _Py_atomic_load_ptr (& op -> ob_item ))) {
320
+ return list_item_impl (op , i , item );
321
+ }
322
+ return item ;
323
+ }
324
+ #else
266
325
static inline PyObject *
267
326
list_get_item_ref (PyListObject * op , Py_ssize_t i )
268
327
{
@@ -271,6 +330,7 @@ list_get_item_ref(PyListObject *op, Py_ssize_t i)
271
330
}
272
331
return Py_NewRef (PyList_GET_ITEM (op , i ));
273
332
}
333
+ #endif
274
334
275
335
int
276
336
PyList_SetItem (PyObject * op , Py_ssize_t i ,
0 commit comments