Skip to content

Commit a6f17c9

Browse files
committed
more requested changes
1 parent 409239c commit a6f17c9

File tree

1 file changed

+49
-67
lines changed

1 file changed

+49
-67
lines changed

Modules/arraymodule.c

Lines changed: 49 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ struct arraydescr {
4444

4545
typedef struct {
4646
Py_ssize_t allocated;
47-
char items[];
47+
_Alignas(8) char items[];
4848
} arraydata;
4949

5050
typedef 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
7777
PyArray_GET_SIZE(PyObject *op) {
7878
arrayobject *ao = (arrayobject *)op;
7979
#ifdef Py_GIL_DISABLED
@@ -152,9 +152,6 @@ enum machine_format_code {
152152
static arraydata *
153153
arraydata_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

196182
static arraydata *
197183
arraydata_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 *
213196
array_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
809792
valid_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

829812
static 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

852835
static 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

878858
static 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

903883
static 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

927907
static 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

947927
error:
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

954934
static 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
963943
ins1(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)
11541132
static PyObject *
11551133
array_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
13631341
array_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

Comments
 (0)