@@ -44,7 +44,7 @@ struct arraydescr {
4444
4545typedef struct {
4646 Py_ssize_t allocated ;
47- char items [];
47+ _Alignas( 8 ) char items [];
4848} arraydata ;
4949
5050typedef struct arrayobject {
@@ -73,7 +73,7 @@ typedef struct {
7373 PyObject * str_iter ;
7474} array_state ;
7575
76- static inline Py_ssize_t
76+ static Py_ssize_t
7777PyArray_GET_SIZE (PyObject * op ) {
7878 arrayobject * ao = (arrayobject * )op ;
7979#ifdef Py_GIL_DISABLED
@@ -152,9 +152,6 @@ enum machine_format_code {
152152static arraydata *
153153arraydata_alloc (Py_ssize_t size , int itemsize )
154154{
155- if ((size_t ) size > (PY_SSIZE_T_MAX - sizeof (arraydata ))/itemsize - 1 ) {
156- return NULL ;
157- }
158155 arraydata * data = (arraydata * )PyMem_Malloc (sizeof (arraydata ) + size * itemsize );
159156 if (data == NULL ) {
160157 return NULL ;
@@ -180,25 +177,11 @@ arraydata_free(arraydata *data, bool use_qsbr)
180177#endif
181178}
182179
183- static arraydata *
184- arraydata_set_items (arraydata * data , char * newitems , Py_ssize_t newsize , int itemsize , bool use_qsbr )
185- {
186- arraydata_free (data , use_qsbr );
187- data = arraydata_alloc (newsize , itemsize );
188- if (data != NULL ) {
189- memcpy (data -> items , newitems , newsize * itemsize );
190- }
191- return data ;
192- }
193-
194180#ifndef Py_GIL_DISABLED
195181
196182static arraydata *
197183arraydata_realloc (arraydata * data , Py_ssize_t size , int itemsize )
198184{
199- if ((size_t ) size > (PY_SSIZE_T_MAX - sizeof (arraydata ))/itemsize - 1 ) {
200- return NULL ;
201- }
202185 data = (arraydata * )PyMem_Realloc (data , sizeof (arraydata ) + size * itemsize );
203186 if (data == NULL ) {
204187 return NULL ;
@@ -209,7 +192,7 @@ arraydata_realloc(arraydata *data, Py_ssize_t size, int itemsize)
209192
210193#endif
211194
212- static inline char *
195+ static char *
213196array_items_ptr (arrayobject * self )
214197{
215198 return self -> data == NULL ? NULL : self -> data -> items ;
@@ -805,25 +788,25 @@ newarrayobject(PyTypeObject *type, Py_ssize_t size, const struct arraydescr *des
805788 return (PyObject * ) op ;
806789}
807790
808- static inline int
791+ static int
809792valid_index (Py_ssize_t i , Py_ssize_t limit )
810793{
811794 return (size_t ) i < (size_t ) limit ;
812795}
813796
814- static inline PyObject *
815- getarrayitem (arrayobject * ap , Py_ssize_t i , char * items )
797+ static PyObject *
798+ getarrayitem (arrayobject * ap , Py_ssize_t i , arraydata * data )
816799{
817800#ifndef NDEBUG
818801 array_state * state = find_array_state_by_type (Py_TYPE (ap ));
819802 assert (array_Check (ap , state ));
820803#ifdef Py_GIL_DISABLED
821- assert (valid_index (i , ( _Py_CONTAINER_OF ( items , arraydata , items )) -> allocated ));
804+ assert (valid_index (i , data -> allocated ));
822805#else
823806 assert (valid_index (i , Py_SIZE (ap )));
824807#endif
825808#endif
826- return (* ap -> ob_descr -> getitem )(items , i );
809+ return (* ap -> ob_descr -> getitem )(data -> items , i );
827810}
828811
829812static PyObject *
@@ -841,7 +824,7 @@ getarrayitem_locked(PyObject *op, Py_ssize_t i)
841824 }
842825 else {
843826 arrayobject * ap = (arrayobject * )op ;
844- ret = getarrayitem (ap , i , ap -> data -> items );
827+ ret = getarrayitem (ap , i , ap -> data );
845828 }
846829 Py_END_CRITICAL_SECTION ();
847830 return ret ;
@@ -850,7 +833,7 @@ getarrayitem_locked(PyObject *op, Py_ssize_t i)
850833#ifdef Py_GIL_DISABLED
851834
852835static PyObject *
853- getarrayitem_maybe_locked (PyObject * op , Py_ssize_t i )
836+ getarrayitem_threadsafe (PyObject * op , Py_ssize_t i )
854837{
855838 if (!_Py_IsOwnedByCurrentThread ((PyObject * )op ) && !_PyObject_GC_IS_SHARED (op )) {
856839 return getarrayitem_locked (op , i );
@@ -867,37 +850,34 @@ getarrayitem_maybe_locked(PyObject *op, Py_ssize_t i)
867850 if (!valid_index (i , data -> allocated )) {
868851 return NULL ;
869852 }
870- return getarrayitem (ap , i , data -> items );
871- /* Could check size again here to make sure it hasn't changed but since
872- there isn't a well defined order between unsynchronized thread
873- operations there's no point. */
853+ return getarrayitem (ap , i , data );
874854}
875855
876856#else // Py_GIL_DISABLED
877857
878858static PyObject *
879- getarrayitem_maybe_locked (PyObject * op , Py_ssize_t i )
859+ getarrayitem_threadsafe (PyObject * op , Py_ssize_t i )
880860{
881861 return getarrayitem_locked (op , i );
882862}
883863
884864#endif // Py_GIL_DISABLED
885865
886- static inline int
887- setarrayitem (arrayobject * ap , Py_ssize_t i , PyObject * v , char * items )
866+ static int
867+ setarrayitem (arrayobject * ap , Py_ssize_t i , PyObject * v , arraydata * data )
888868{
889869#ifndef NDEBUG
890870 array_state * state = find_array_state_by_type (Py_TYPE (ap ));
891871 assert (array_Check (ap , state ));
892- if (items != NULL ) {
872+ if (data != NULL ) {
893873#ifdef Py_GIL_DISABLED
894- assert (valid_index (i , ( _Py_CONTAINER_OF ( items , arraydata , items )) -> allocated ));
874+ assert (valid_index (i , data -> allocated ));
895875#else
896876 assert (valid_index (i , Py_SIZE (ap )));
897877#endif
898878 }
899879#endif
900- return (* ap -> ob_descr -> setitem )(items , i , v );
880+ return (* ap -> ob_descr -> setitem )(data -> items , i , v );
901881}
902882
903883static int
@@ -916,7 +896,7 @@ setarrayitem_locked(PyObject *op, Py_ssize_t i, PyObject *v)
916896 }
917897 else {
918898 arrayobject * ap = arrayobject_CAST (op );
919- ret = setarrayitem (ap , i , v , ap -> data -> items );
899+ ret = setarrayitem (ap , i , v , ap -> data );
920900 }
921901 Py_END_CRITICAL_SECTION ();
922902 return ret ;
@@ -925,7 +905,7 @@ setarrayitem_locked(PyObject *op, Py_ssize_t i, PyObject *v)
925905#ifdef Py_GIL_DISABLED
926906
927907static int
928- setarrayitem_maybe_locked (PyObject * op , Py_ssize_t i , PyObject * v )
908+ setarrayitem_threadsafe (PyObject * op , Py_ssize_t i , PyObject * v )
929909{
930910 if (!_Py_IsOwnedByCurrentThread ((PyObject * )op ) && !_PyObject_GC_IS_SHARED (op )) {
931911 return setarrayitem_locked (op , i , v );
@@ -942,7 +922,7 @@ setarrayitem_maybe_locked(PyObject *op, Py_ssize_t i, PyObject *v)
942922 if (!valid_index (i , data -> allocated )) {
943923 goto error ;
944924 }
945- return setarrayitem (ap , i , v , data -> items );
925+ return setarrayitem (ap , i , v , data );
946926
947927error :
948928 PyErr_SetString (PyExc_IndexError , "array index out of range" );
@@ -952,7 +932,7 @@ setarrayitem_maybe_locked(PyObject *op, Py_ssize_t i, PyObject *v)
952932#else // Py_GIL_DISABLED
953933
954934static int
955- setarrayitem_maybe_locked (PyObject * op , Py_ssize_t i , PyObject * v )
935+ setarrayitem_threadsafe (PyObject * op , Py_ssize_t i , PyObject * v )
956936{
957937 return setarrayitem_locked (op , i , v );
958938}
@@ -963,7 +943,6 @@ static int
963943ins1 (arrayobject * self , Py_ssize_t where , PyObject * v )
964944{
965945 _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED (self );
966- char * items ;
967946 Py_ssize_t n = Py_SIZE (self );
968947 if (v == NULL ) {
969948 PyErr_BadInternalCall ();
@@ -974,7 +953,6 @@ ins1(arrayobject *self, Py_ssize_t where, PyObject *v)
974953
975954 if (array_resize (self , n + 1 ) == -1 )
976955 return -1 ;
977- items = array_items_ptr (self );
978956 if (where < 0 ) {
979957 where += n ;
980958 if (where < 0 )
@@ -984,10 +962,10 @@ ins1(arrayobject *self, Py_ssize_t where, PyObject *v)
984962 where = n ;
985963 /* appends don't need to call memmove() */
986964 if (where != n )
987- memmove (items + (where + 1 )* self -> ob_descr -> itemsize ,
988- items + where * self -> ob_descr -> itemsize ,
965+ memmove (array_items_ptr ( self ) + (where + 1 )* self -> ob_descr -> itemsize ,
966+ array_items_ptr ( self ) + where * self -> ob_descr -> itemsize ,
989967 (n - where )* self -> ob_descr -> itemsize );
990- return setarrayitem (self , where , v , items );
968+ return setarrayitem (self , where , v , self -> data );
991969}
992970
993971/* Methods */
@@ -1075,11 +1053,11 @@ array_richcompare_lock_held(PyObject *v, PyObject *w, int op)
10751053 /* Search for the first index where items are different */
10761054 k = 1 ;
10771055 for (i = 0 ; i < Py_SIZE (va ) && i < Py_SIZE (wa ); i ++ ) {
1078- vi = getarrayitem (va , i , array_items_ptr ( va ) );
1056+ vi = getarrayitem (va , i , va -> data );
10791057 if (vi == NULL ) {
10801058 return NULL ;
10811059 }
1082- wi = getarrayitem (wa , i , array_items_ptr ( wa ) );
1060+ wi = getarrayitem (wa , i , wa -> data );
10831061 if (wi == NULL ) {
10841062 Py_DECREF (vi );
10851063 return NULL ;
@@ -1154,7 +1132,7 @@ array_length(PyObject *op)
11541132static PyObject *
11551133array_item (PyObject * op , Py_ssize_t i )
11561134{
1157- PyObject * item = getarrayitem_maybe_locked (op , i );
1135+ PyObject * item = getarrayitem_threadsafe (op , i );
11581136 if (item == NULL ) {
11591137 PyErr_SetString (PyExc_IndexError , "array index out of range" );
11601138 }
@@ -1363,7 +1341,7 @@ static int
13631341array_ass_item (PyObject * op , Py_ssize_t i , PyObject * v )
13641342{
13651343 if (v != NULL ) {
1366- return setarrayitem_maybe_locked (op , i , v );
1344+ return setarrayitem_threadsafe (op , i , v );
13671345 }
13681346 int ret ;
13691347 Py_BEGIN_CRITICAL_SECTION (op );
@@ -1517,7 +1495,7 @@ array_array_count_impl(arrayobject *self, PyObject *v)
15171495 PyObject * selfi ;
15181496 int cmp ;
15191497
1520- selfi = getarrayitem (self , i , array_items_ptr ( self ) );
1498+ selfi = getarrayitem (self , i , self -> data );
15211499 if (selfi == NULL )
15221500 return NULL ;
15231501 cmp = PyObject_RichCompareBool (selfi , v , Py_EQ );
@@ -1565,7 +1543,7 @@ array_array_index_impl(arrayobject *self, PyObject *v, Py_ssize_t start,
15651543 PyObject * selfi ;
15661544 int cmp ;
15671545
1568- selfi = getarrayitem (self , i , array_items_ptr ( self ) );
1546+ selfi = getarrayitem (self , i , self -> data );
15691547 if (selfi == NULL )
15701548 return NULL ;
15711549 cmp = PyObject_RichCompareBool (selfi , v , Py_EQ );
@@ -1589,7 +1567,7 @@ array_contains_lock_held(PyObject *op, PyObject *v)
15891567
15901568 for (i = 0 , cmp = 0 ; cmp == 0 && i < Py_SIZE (op ); i ++ ) {
15911569 arrayobject * ap = (arrayobject * )op ;
1592- PyObject * opi = getarrayitem (ap , i , ap -> data -> items );
1570+ PyObject * opi = getarrayitem (ap , i , ap -> data );
15931571 if (opi == NULL )
15941572 return -1 ;
15951573 cmp = PyObject_RichCompareBool (opi , v , Py_EQ );
@@ -1628,7 +1606,7 @@ array_array_remove_impl(arrayobject *self, PyObject *v)
16281606 PyObject * selfi ;
16291607 int cmp ;
16301608
1631- selfi = getarrayitem (self , i , array_items_ptr ( self ) );
1609+ selfi = getarrayitem (self , i , self -> data );
16321610 if (selfi == NULL )
16331611 return NULL ;
16341612 cmp = PyObject_RichCompareBool (selfi , v , Py_EQ );
@@ -1674,7 +1652,7 @@ array_array_pop_impl(arrayobject *self, Py_ssize_t i)
16741652 PyErr_SetString (PyExc_IndexError , "pop index out of range" );
16751653 return NULL ;
16761654 }
1677- v = getarrayitem (self , i , array_items_ptr ( self ) );
1655+ v = getarrayitem (self , i , self -> data );
16781656 if (v == NULL )
16791657 return NULL ;
16801658 if (array_del_slice (self , i , i + 1 ) != 0 ) {
@@ -2018,7 +1996,7 @@ array_array_fromlist_impl(arrayobject *self, PyObject *list)
20181996 return NULL ;
20191997 for (i = 0 ; i < n ; i ++ ) {
20201998 PyObject * v = PyList_GET_ITEM (list , i );
2021- if (setarrayitem (self , Py_SIZE (self ) - n + i , v , array_items_ptr ( self ) ) != 0 ) {
1999+ if (setarrayitem (self , Py_SIZE (self ) - n + i , v , self -> data ) != 0 ) {
20222000 array_resize (self , old_size );
20232001 return NULL ;
20242002 }
@@ -2050,7 +2028,7 @@ array_array_tolist_impl(arrayobject *self)
20502028 if (list == NULL )
20512029 return NULL ;
20522030 for (i = 0 ; i < Py_SIZE (self ); i ++ ) {
2053- PyObject * v = getarrayitem (self , i , array_items_ptr ( self ) );
2031+ PyObject * v = getarrayitem (self , i , self -> data );
20542032 if (v == NULL )
20552033 goto error ;
20562034 PyList_SET_ITEM (list , i , v );
@@ -2920,7 +2898,7 @@ array_ass_subscr_lock_held(PyObject *op, PyObject* item, PyObject* value)
29202898 slicelength = 1 ;
29212899 }
29222900 else
2923- return setarrayitem (self , i , value , array_items_ptr ( self ) );
2901+ return setarrayitem (self , i , value , self -> data );
29242902 }
29252903 else if (PySlice_Check (item )) {
29262904 if (PySlice_Unpack (item , & start , & stop , & step ) < 0 ) {
@@ -3069,7 +3047,7 @@ array_ass_subscr(PyObject *op, PyObject* item, PyObject* value)
30693047 return -1 ;
30703048 if (i < 0 )
30713049 i += PyArray_GET_SIZE (op );
3072- return setarrayitem_maybe_locked (op , i , value );
3050+ return setarrayitem_threadsafe (op , i , value );
30733051 }
30743052 }
30753053
@@ -3202,7 +3180,7 @@ array_new_internal_lock_held(PyTypeObject *type, PyObject *initial, int c)
32023180 Py_DECREF (a );
32033181 return NULL ;
32043182 }
3205- if (setarrayitem (ap , i , v , ap -> data -> items ) != 0 ) {
3183+ if (setarrayitem (ap , i , v , ap -> data ) != 0 ) {
32063184 Py_DECREF (v );
32073185 Py_DECREF (a );
32083186 return NULL ;
@@ -3231,14 +3209,16 @@ array_new_internal_lock_held(PyTypeObject *type, PyObject *initial, int c)
32313209
32323210 if (n > 0 ) {
32333211 arrayobject * self = (arrayobject * )a ;
3234- self -> data = arraydata_set_items (self -> data ,
3235- (char * )ustr , n , sizeof (wchar_t ), false);
3236- PyMem_Free (ustr );
3212+ assert (self -> data == NULL );
3213+ self -> data = arraydata_alloc (n , sizeof (wchar_t ));
32373214 if (self -> data == NULL ) {
3215+ PyMem_Free (ustr );
32383216 Py_DECREF (a );
32393217 PyErr_NoMemory ();
32403218 return NULL ;
32413219 }
3220+ memcpy (self -> data -> items , (char * )ustr , n * sizeof (wchar_t ));
3221+ PyMem_Free (ustr );
32423222 Py_SET_SIZE (self , n );
32433223 }
32443224 }
@@ -3251,14 +3231,16 @@ array_new_internal_lock_held(PyTypeObject *type, PyObject *initial, int c)
32513231 }
32523232
32533233 arrayobject * self = (arrayobject * )a ;
3254- self -> data = arraydata_set_items (self -> data ,
3255- (char * )ustr , n , sizeof (Py_UCS4 ), false);
3256- PyMem_Free (ustr );
3234+ assert (self -> data == NULL );
3235+ self -> data = arraydata_alloc (n , sizeof (Py_UCS4 ));
32573236 if (self -> data == NULL ) {
3237+ PyMem_Free (ustr );
32583238 Py_DECREF (a );
32593239 PyErr_NoMemory ();
32603240 return NULL ;
32613241 }
3242+ memcpy (self -> data -> items , (char * )ustr , n * sizeof (Py_UCS4 ));
3243+ PyMem_Free (ustr );
32623244 Py_SET_SIZE (self , n );
32633245 }
32643246 }
@@ -3508,7 +3490,7 @@ arrayiter_next(PyObject *op)
35083490 assert (PyObject_TypeCheck (it , state -> ArrayIterType ));
35093491 assert (array_Check (ao , state ));
35103492#endif
3511- PyObject * ret = getarrayitem_maybe_locked ((PyObject * )ao , index );
3493+ PyObject * ret = getarrayitem_threadsafe ((PyObject * )ao , index );
35123494 if (ret != NULL ) {
35133495 FT_ATOMIC_STORE_SSIZE_RELAXED (it -> index , index + 1 );
35143496 }
0 commit comments