@@ -515,7 +515,7 @@ list_item(PyObject *aa, Py_ssize_t i)
515
515
}
516
516
517
517
static PyObject *
518
- list_slice (PyListObject * a , Py_ssize_t ilow , Py_ssize_t ihigh )
518
+ list_slice_lock_held (PyListObject * a , Py_ssize_t ilow , Py_ssize_t ihigh )
519
519
{
520
520
PyListObject * np ;
521
521
PyObject * * src , * * dest ;
@@ -559,7 +559,7 @@ PyList_GetSlice(PyObject *a, Py_ssize_t ilow, Py_ssize_t ihigh)
559
559
else if (ihigh > Py_SIZE (a )) {
560
560
ihigh = Py_SIZE (a );
561
561
}
562
- ret = list_slice ((PyListObject * )a , ilow , ihigh );
562
+ ret = list_slice_lock_held ((PyListObject * )a , ilow , ihigh );
563
563
Py_END_CRITICAL_SECTION ();
564
564
return ret ;
565
565
}
@@ -584,13 +584,13 @@ list_concat_lock_held(PyListObject *a, PyListObject *b)
584
584
dest = np -> ob_item ;
585
585
for (i = 0 ; i < Py_SIZE (a ); i ++ ) {
586
586
PyObject * v = src [i ];
587
- FT_ATOMIC_STORE_PTR_RELAXED ( dest [i ], Py_NewRef (v ) );
587
+ dest [i ] = Py_NewRef (v );
588
588
}
589
589
src = b -> ob_item ;
590
590
dest = np -> ob_item + Py_SIZE (a );
591
591
for (i = 0 ; i < Py_SIZE (b ); i ++ ) {
592
592
PyObject * v = src [i ];
593
- FT_ATOMIC_STORE_PTR_RELAXED ( dest [i ], Py_NewRef (v ) );
593
+ dest [i ] = Py_NewRef (v );
594
594
}
595
595
Py_SET_SIZE (np , size );
596
596
return (PyObject * )np ;
@@ -636,15 +636,15 @@ list_repeat_lock_held(PyListObject *a, Py_ssize_t n)
636
636
_Py_RefcntAdd (elem , n );
637
637
PyObject * * dest_end = dest + output_size ;
638
638
while (dest < dest_end ) {
639
- FT_ATOMIC_STORE_PTR_RELAXED ( * dest ++ , elem ) ;
639
+ * dest ++ = elem ;
640
640
}
641
641
}
642
642
else {
643
643
PyObject * * src = a -> ob_item ;
644
644
PyObject * * src_end = src + input_size ;
645
645
while (src < src_end ) {
646
646
_Py_RefcntAdd (* src , n );
647
- FT_ATOMIC_STORE_PTR_RELAXED ( * dest ++ , * src ++ ) ;
647
+ * dest ++ = * src ++ ;
648
648
}
649
649
650
650
_Py_memory_repeat ((char * )np -> ob_item , sizeof (PyObject * )* output_size ,
@@ -718,7 +718,7 @@ list_clear_slot(PyObject *self)
718
718
* guaranteed the call cannot fail.
719
719
*/
720
720
static int
721
- list_ass_slice (PyListObject * a , Py_ssize_t ilow , Py_ssize_t ihigh , PyObject * v )
721
+ list_ass_slice_lock_held (PyListObject * a , Py_ssize_t ilow , Py_ssize_t ihigh , PyObject * v )
722
722
{
723
723
/* Because [X]DECREF can recursively invoke list operations on
724
724
this list, we must postpone all [X]DECREF activity until
@@ -741,15 +741,6 @@ list_ass_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v)
741
741
if (v == NULL )
742
742
n = 0 ;
743
743
else {
744
- if (a == b ) {
745
- /* Special case "a[i:j] = a" -- copy b first */
746
- v = list_slice (b , 0 , Py_SIZE (b ));
747
- if (v == NULL )
748
- return result ;
749
- result = list_ass_slice (a , ilow , ihigh , v );
750
- Py_DECREF (v );
751
- return result ;
752
- }
753
744
v_as_SF = PySequence_Fast (v , "can only assign an iterable" );
754
745
if (v_as_SF == NULL )
755
746
goto Error ;
@@ -823,6 +814,34 @@ list_ass_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v)
823
814
#undef b
824
815
}
825
816
817
+ static int
818
+ list_ass_slice (PyListObject * a , Py_ssize_t ilow , Py_ssize_t ihigh , PyObject * v )
819
+ {
820
+ int ret ;
821
+ if (a == (PyListObject * )v ) {
822
+ Py_BEGIN_CRITICAL_SECTION (a );
823
+ Py_ssize_t n = PyList_GET_SIZE (a );
824
+ PyObject * copy = list_slice_lock_held (a , 0 , n );
825
+ if (copy == NULL ) {
826
+ return -1 ;
827
+ }
828
+ ret = list_ass_slice_lock_held (a , ilow , ihigh , copy );
829
+ Py_DECREF (copy );
830
+ Py_END_CRITICAL_SECTION ();
831
+ }
832
+ else if (v != NULL && PyList_CheckExact (v )) {
833
+ Py_BEGIN_CRITICAL_SECTION2 (a , v );
834
+ ret = list_ass_slice_lock_held (a , ilow , ihigh , v );
835
+ Py_END_CRITICAL_SECTION2 ();
836
+ }
837
+ else {
838
+ Py_BEGIN_CRITICAL_SECTION (a );
839
+ ret = list_ass_slice_lock_held (a , ilow , ihigh , v );
840
+ Py_END_CRITICAL_SECTION ();
841
+ }
842
+ return ret ;
843
+ }
844
+
826
845
int
827
846
PyList_SetSlice (PyObject * a , Py_ssize_t ilow , Py_ssize_t ihigh , PyObject * v )
828
847
{
@@ -956,7 +975,7 @@ static PyObject *
956
975
list_copy_impl (PyListObject * self )
957
976
/*[clinic end generated code: output=ec6b72d6209d418e input=81c54b0c7bb4f73d]*/
958
977
{
959
- return list_slice (self , 0 , Py_SIZE (self ));
978
+ return list_slice_lock_held (self , 0 , Py_SIZE (self ));
960
979
}
961
980
962
981
/*[clinic input]
@@ -2884,8 +2903,7 @@ list_remove_impl(PyListObject *self, PyObject *value)
2884
2903
int cmp = PyObject_RichCompareBool (obj , value , Py_EQ );
2885
2904
Py_DECREF (obj );
2886
2905
if (cmp > 0 ) {
2887
- if (list_ass_slice (self , i , i + 1 ,
2888
- (PyObject * )NULL ) == 0 )
2906
+ if (list_ass_slice_lock_held (self , i , i + 1 , NULL ) == 0 )
2889
2907
Py_RETURN_NONE ;
2890
2908
return NULL ;
2891
2909
}
@@ -3085,6 +3103,45 @@ static PySequenceMethods list_as_sequence = {
3085
3103
list_inplace_repeat , /* sq_inplace_repeat */
3086
3104
};
3087
3105
3106
+ static inline PyObject *
3107
+ list_slice_step_lock_held (PyListObject * a , Py_ssize_t start , Py_ssize_t step , Py_ssize_t len )
3108
+ {
3109
+ PyListObject * np = (PyListObject * )list_new_prealloc (len );
3110
+ if (np == NULL ) {
3111
+ return NULL ;
3112
+ }
3113
+ size_t cur ;
3114
+ Py_ssize_t i ;
3115
+ PyObject * * src = a -> ob_item ;
3116
+ PyObject * * dest = np -> ob_item ;
3117
+ for (cur = start , i = 0 ; i < len ;
3118
+ cur += (size_t )step , i ++ ) {
3119
+ PyObject * v = src [cur ];
3120
+ dest [i ] = Py_NewRef (v );
3121
+ }
3122
+ Py_SET_SIZE (np , len );
3123
+ return (PyObject * )np ;
3124
+ }
3125
+
3126
+ static PyObject *
3127
+ list_slice_wrap (PyListObject * aa , Py_ssize_t start , Py_ssize_t stop , Py_ssize_t step )
3128
+ {
3129
+ PyObject * res = NULL ;
3130
+ Py_BEGIN_CRITICAL_SECTION (aa );
3131
+ Py_ssize_t len = PySlice_AdjustIndices (Py_SIZE (aa ), & start , & stop , step );
3132
+ if (len <= 0 ) {
3133
+ res = PyList_New (0 );
3134
+ }
3135
+ else if (step == 1 ) {
3136
+ res = list_slice_lock_held (aa , start , stop );
3137
+ }
3138
+ else {
3139
+ res = list_slice_step_lock_held (aa , start , step , len );
3140
+ }
3141
+ Py_END_CRITICAL_SECTION ();
3142
+ return res ;
3143
+ }
3144
+
3088
3145
static PyObject *
3089
3146
list_subscript (PyObject * _self , PyObject * item )
3090
3147
{
@@ -3099,38 +3156,11 @@ list_subscript(PyObject* _self, PyObject* item)
3099
3156
return list_item ((PyObject * )self , i );
3100
3157
}
3101
3158
else if (PySlice_Check (item )) {
3102
- Py_ssize_t start , stop , step , slicelength , i ;
3103
- size_t cur ;
3104
- PyObject * result ;
3105
- PyObject * it ;
3106
- PyObject * * src , * * dest ;
3107
-
3159
+ Py_ssize_t start , stop , step ;
3108
3160
if (PySlice_Unpack (item , & start , & stop , & step ) < 0 ) {
3109
3161
return NULL ;
3110
3162
}
3111
- slicelength = PySlice_AdjustIndices (Py_SIZE (self ), & start , & stop ,
3112
- step );
3113
-
3114
- if (slicelength <= 0 ) {
3115
- return PyList_New (0 );
3116
- }
3117
- else if (step == 1 ) {
3118
- return list_slice (self , start , stop );
3119
- }
3120
- else {
3121
- result = list_new_prealloc (slicelength );
3122
- if (!result ) return NULL ;
3123
-
3124
- src = self -> ob_item ;
3125
- dest = ((PyListObject * )result )-> ob_item ;
3126
- for (cur = start , i = 0 ; i < slicelength ;
3127
- cur += (size_t )step , i ++ ) {
3128
- it = Py_NewRef (src [cur ]);
3129
- dest [i ] = it ;
3130
- }
3131
- Py_SET_SIZE (result , slicelength );
3132
- return result ;
3133
- }
3163
+ return list_slice_wrap (self , start , stop , step );
3134
3164
}
3135
3165
else {
3136
3166
PyErr_Format (PyExc_TypeError ,
@@ -3241,8 +3271,10 @@ list_ass_subscript(PyObject* _self, PyObject* item, PyObject* value)
3241
3271
3242
3272
/* protect against a[::-1] = a */
3243
3273
if (self == (PyListObject * )value ) {
3244
- seq = list_slice ((PyListObject * )value , 0 ,
3245
- PyList_GET_SIZE (value ));
3274
+ Py_BEGIN_CRITICAL_SECTION (value );
3275
+ seq = list_slice_lock_held ((PyListObject * )value , 0 ,
3276
+ Py_SIZE (value ));
3277
+ Py_END_CRITICAL_SECTION ();
3246
3278
}
3247
3279
else {
3248
3280
seq = PySequence_Fast (value ,
0 commit comments