Skip to content

Commit f051e43

Browse files
committed
Issue #28126: Replace Py_MEMCPY with memcpy(). Visual Studio can properly optimize memcpy().
1 parent a4d9b17 commit f051e43

File tree

14 files changed

+83
-97
lines changed

14 files changed

+83
-97
lines changed

Include/pyport.h

Lines changed: 14 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -177,26 +177,9 @@ typedef int Py_ssize_clean_t;
177177
#define Py_LOCAL_INLINE(type) static type
178178
#endif
179179

180-
/* Py_MEMCPY can be used instead of memcpy in cases where the copied blocks
181-
* are often very short. While most platforms have highly optimized code for
182-
* large transfers, the setup costs for memcpy are often quite high. MEMCPY
183-
* solves this by doing short copies "in line".
184-
*/
185-
186-
#if defined(_MSC_VER)
187-
#define Py_MEMCPY(target, source, length) do { \
188-
size_t i_, n_ = (length); \
189-
char *t_ = (void*) (target); \
190-
const char *s_ = (void*) (source); \
191-
if (n_ >= 16) \
192-
memcpy(t_, s_, n_); \
193-
else \
194-
for (i_ = 0; i_ < n_; i_++) \
195-
t_[i_] = s_[i_]; \
196-
} while (0)
197-
#else
180+
/* Py_MEMCPY is kept for backwards compatibility,
181+
* see https://bugs.python.org/issue28126 */
198182
#define Py_MEMCPY memcpy
199-
#endif
200183

201184
#include <stdlib.h>
202185

@@ -449,18 +432,18 @@ extern "C" {
449432
#define HAVE_PY_SET_53BIT_PRECISION 1
450433
#define _Py_SET_53BIT_PRECISION_HEADER \
451434
unsigned int old_fpcr, new_fpcr
452-
#define _Py_SET_53BIT_PRECISION_START \
453-
do { \
454-
__asm__ ("fmove.l %%fpcr,%0" : "=g" (old_fpcr)); \
455-
/* Set double precision / round to nearest. */ \
456-
new_fpcr = (old_fpcr & ~0xf0) | 0x80; \
457-
if (new_fpcr != old_fpcr) \
458-
__asm__ volatile ("fmove.l %0,%%fpcr" : : "g" (new_fpcr)); \
435+
#define _Py_SET_53BIT_PRECISION_START \
436+
do { \
437+
__asm__ ("fmove.l %%fpcr,%0" : "=g" (old_fpcr)); \
438+
/* Set double precision / round to nearest. */ \
439+
new_fpcr = (old_fpcr & ~0xf0) | 0x80; \
440+
if (new_fpcr != old_fpcr) \
441+
__asm__ volatile ("fmove.l %0,%%fpcr" : : "g" (new_fpcr)); \
459442
} while (0)
460-
#define _Py_SET_53BIT_PRECISION_END \
461-
do { \
462-
if (new_fpcr != old_fpcr) \
463-
__asm__ volatile ("fmove.l %0,%%fpcr" : : "g" (old_fpcr)); \
443+
#define _Py_SET_53BIT_PRECISION_END \
444+
do { \
445+
if (new_fpcr != old_fpcr) \
446+
__asm__ volatile ("fmove.l %0,%%fpcr" : : "g" (old_fpcr)); \
464447
} while (0)
465448
#endif
466449

@@ -742,7 +725,7 @@ extern pid_t forkpty(int *, char *, struct termios *, struct winsize *);
742725
#endif
743726

744727
#ifdef VA_LIST_IS_ARRAY
745-
#define Py_VA_COPY(x, y) Py_MEMCPY((x), (y), sizeof(va_list))
728+
#define Py_VA_COPY(x, y) memcpy((x), (y), sizeof(va_list))
746729
#else
747730
#ifdef __va_copy
748731
#define Py_VA_COPY __va_copy

Include/unicodeobject.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ typedef uint8_t Py_UCS1;
156156
Py_UNICODE_ISNUMERIC(ch))
157157

158158
#define Py_UNICODE_COPY(target, source, length) \
159-
Py_MEMCPY((target), (source), (length)*sizeof(Py_UNICODE))
159+
memcpy((target), (source), (length)*sizeof(Py_UNICODE))
160160

161161
#define Py_UNICODE_FILL(target, value, length) \
162162
do {Py_ssize_t i_; Py_UNICODE *t_ = (target); Py_UNICODE v_ = (value);\

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ What's New in Python 3.6.0 beta 2
1010
Core and Builtins
1111
-----------------
1212

13+
- Issue #28126: Replace Py_MEMCPY with memcpy(). Visual Studio can properly
14+
optimize memcpy().
15+
1316
- Issue #28120: Fix dict.pop() for splitted dictionary when trying to remove a
1417
"pending key" (Not yet inserted in split-table). Patch by Xiang Zhang.
1518

Modules/arraymodule.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -836,10 +836,10 @@ array_repeat(arrayobject *a, Py_ssize_t n)
836836
memset(np->ob_item, a->ob_item[0], newbytes);
837837
} else {
838838
Py_ssize_t done = oldbytes;
839-
Py_MEMCPY(np->ob_item, a->ob_item, oldbytes);
839+
memcpy(np->ob_item, a->ob_item, oldbytes);
840840
while (done < newbytes) {
841841
Py_ssize_t ncopy = (done <= newbytes-done) ? done : newbytes-done;
842-
Py_MEMCPY(np->ob_item+done, np->ob_item, ncopy);
842+
memcpy(np->ob_item+done, np->ob_item, ncopy);
843843
done += ncopy;
844844
}
845845
}

Modules/hashtable.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,14 @@
6464
#define ENTRY_READ_PDATA(TABLE, ENTRY, DATA_SIZE, PDATA) \
6565
do { \
6666
assert((DATA_SIZE) == (TABLE)->data_size); \
67-
Py_MEMCPY((PDATA), _Py_HASHTABLE_ENTRY_PDATA(TABLE, (ENTRY)), \
67+
memcpy((PDATA), _Py_HASHTABLE_ENTRY_PDATA(TABLE, (ENTRY)), \
6868
(DATA_SIZE)); \
6969
} while (0)
7070

7171
#define ENTRY_WRITE_PDATA(TABLE, ENTRY, DATA_SIZE, PDATA) \
7272
do { \
7373
assert((DATA_SIZE) == (TABLE)->data_size); \
74-
Py_MEMCPY((void *)_Py_HASHTABLE_ENTRY_PDATA((TABLE), (ENTRY)), \
74+
memcpy((void *)_Py_HASHTABLE_ENTRY_PDATA((TABLE), (ENTRY)), \
7575
(PDATA), (DATA_SIZE)); \
7676
} while (0)
7777

@@ -337,7 +337,7 @@ _Py_hashtable_set(_Py_hashtable_t *ht, size_t key_size, const void *pkey,
337337
}
338338

339339
entry->key_hash = key_hash;
340-
Py_MEMCPY((void *)_Py_HASHTABLE_ENTRY_PKEY(entry), pkey, ht->key_size);
340+
memcpy((void *)_Py_HASHTABLE_ENTRY_PKEY(entry), pkey, ht->key_size);
341341
if (data)
342342
ENTRY_WRITE_PDATA(ht, entry, data_size, data);
343343

Modules/hashtable.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,26 +43,26 @@ typedef struct {
4343
#define _Py_HASHTABLE_READ_KEY(TABLE, PKEY, DST_KEY) \
4444
do { \
4545
assert(sizeof(DST_KEY) == (TABLE)->key_size); \
46-
Py_MEMCPY(&(DST_KEY), (PKEY), sizeof(DST_KEY)); \
46+
memcpy(&(DST_KEY), (PKEY), sizeof(DST_KEY)); \
4747
} while (0)
4848

4949
#define _Py_HASHTABLE_ENTRY_READ_KEY(TABLE, ENTRY, KEY) \
5050
do { \
5151
assert(sizeof(KEY) == (TABLE)->key_size); \
52-
Py_MEMCPY(&(KEY), _Py_HASHTABLE_ENTRY_PKEY(ENTRY), sizeof(KEY)); \
52+
memcpy(&(KEY), _Py_HASHTABLE_ENTRY_PKEY(ENTRY), sizeof(KEY)); \
5353
} while (0)
5454

5555
#define _Py_HASHTABLE_ENTRY_READ_DATA(TABLE, ENTRY, DATA) \
5656
do { \
5757
assert(sizeof(DATA) == (TABLE)->data_size); \
58-
Py_MEMCPY(&(DATA), _Py_HASHTABLE_ENTRY_PDATA(TABLE, (ENTRY)), \
58+
memcpy(&(DATA), _Py_HASHTABLE_ENTRY_PDATA(TABLE, (ENTRY)), \
5959
sizeof(DATA)); \
6060
} while (0)
6161

6262
#define _Py_HASHTABLE_ENTRY_WRITE_DATA(TABLE, ENTRY, DATA) \
6363
do { \
6464
assert(sizeof(DATA) == (TABLE)->data_size); \
65-
Py_MEMCPY((void *)_Py_HASHTABLE_ENTRY_PDATA((TABLE), (ENTRY)), \
65+
memcpy((void *)_Py_HASHTABLE_ENTRY_PDATA((TABLE), (ENTRY)), \
6666
&(DATA), sizeof(DATA)); \
6767
} while (0)
6868

Modules/zlibmodule.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -721,9 +721,9 @@ save_unconsumed_input(compobject *self, Py_buffer *data, int err)
721721
new_data = PyBytes_FromStringAndSize(NULL, new_size);
722722
if (new_data == NULL)
723723
return -1;
724-
Py_MEMCPY(PyBytes_AS_STRING(new_data),
724+
memcpy(PyBytes_AS_STRING(new_data),
725725
PyBytes_AS_STRING(self->unused_data), old_size);
726-
Py_MEMCPY(PyBytes_AS_STRING(new_data) + old_size,
726+
memcpy(PyBytes_AS_STRING(new_data) + old_size,
727727
self->zst.next_in, left_size);
728728
Py_SETREF(self->unused_data, new_data);
729729
self->zst.avail_in = 0;

Objects/abstract.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2353,7 +2353,7 @@ _PyObject_Call_Prepend(PyObject *func,
23532353

23542354
/* use borrowed references */
23552355
stack[0] = obj;
2356-
Py_MEMCPY(&stack[1],
2356+
memcpy(&stack[1],
23572357
&PyTuple_GET_ITEM(args, 0),
23582358
argcount * sizeof(PyObject *));
23592359

@@ -2428,7 +2428,7 @@ _PyStack_UnpackDict(PyObject **args, Py_ssize_t nargs, PyObject *kwargs,
24282428
}
24292429

24302430
/* Copy position arguments (borrowed references) */
2431-
Py_MEMCPY(stack, args, nargs * sizeof(stack[0]));
2431+
memcpy(stack, args, nargs * sizeof(stack[0]));
24322432

24332433
kwstack = stack + nargs;
24342434
pos = i = 0;

Objects/bytesobject.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ PyBytes_FromStringAndSize(const char *str, Py_ssize_t size)
120120
if (str == NULL)
121121
return (PyObject *) op;
122122

123-
Py_MEMCPY(op->ob_sval, str, size);
123+
memcpy(op->ob_sval, str, size);
124124
/* share short strings */
125125
if (size == 1) {
126126
characters[*str & UCHAR_MAX] = op;
@@ -163,7 +163,7 @@ PyBytes_FromString(const char *str)
163163
return PyErr_NoMemory();
164164
(void)PyObject_INIT_VAR(op, &PyBytes_Type, size);
165165
op->ob_shash = -1;
166-
Py_MEMCPY(op->ob_sval, str, size+1);
166+
memcpy(op->ob_sval, str, size+1);
167167
/* share short strings */
168168
if (size == 0) {
169169
nullstring = op;
@@ -437,7 +437,7 @@ formatfloat(PyObject *v, int flags, int prec, int type,
437437
str = _PyBytesWriter_Prepare(writer, str, len);
438438
if (str == NULL)
439439
return NULL;
440-
Py_MEMCPY(str, p, len);
440+
memcpy(str, p, len);
441441
PyMem_Free(p);
442442
str += len;
443443
return str;
@@ -626,7 +626,7 @@ _PyBytes_FormatEx(const char *format, Py_ssize_t format_len,
626626
len = format_len - (fmt - format);
627627
assert(len != 0);
628628

629-
Py_MEMCPY(res, fmt, len);
629+
memcpy(res, fmt, len);
630630
res += len;
631631
fmt += len;
632632
fmtcnt -= (len - 1);
@@ -1009,7 +1009,7 @@ _PyBytes_FormatEx(const char *format, Py_ssize_t format_len,
10091009
}
10101010

10111011
/* Copy bytes */
1012-
Py_MEMCPY(res, pbuf, len);
1012+
memcpy(res, pbuf, len);
10131013
res += len;
10141014

10151015
/* Pad right with the fill character if needed */
@@ -1473,12 +1473,12 @@ bytes_repeat(PyBytesObject *a, Py_ssize_t n)
14731473
}
14741474
i = 0;
14751475
if (i < size) {
1476-
Py_MEMCPY(op->ob_sval, a->ob_sval, Py_SIZE(a));
1476+
memcpy(op->ob_sval, a->ob_sval, Py_SIZE(a));
14771477
i = Py_SIZE(a);
14781478
}
14791479
while (i < size) {
14801480
j = (i <= size-i) ? i : size-i;
1481-
Py_MEMCPY(op->ob_sval+i, op->ob_sval, j);
1481+
memcpy(op->ob_sval+i, op->ob_sval, j);
14821482
i += j;
14831483
}
14841484
return (PyObject *) op;
@@ -2765,7 +2765,7 @@ bytes_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
27652765
n = PyBytes_GET_SIZE(tmp);
27662766
pnew = type->tp_alloc(type, n);
27672767
if (pnew != NULL) {
2768-
Py_MEMCPY(PyBytes_AS_STRING(pnew),
2768+
memcpy(PyBytes_AS_STRING(pnew),
27692769
PyBytes_AS_STRING(tmp), n+1);
27702770
((PyBytesObject *)pnew)->ob_shash =
27712771
((PyBytesObject *)tmp)->ob_shash;
@@ -3237,7 +3237,7 @@ _PyBytesWriter_Resize(_PyBytesWriter *writer, void *str, Py_ssize_t size)
32373237
dest = PyByteArray_AS_STRING(writer->buffer);
32383238
else
32393239
dest = PyBytes_AS_STRING(writer->buffer);
3240-
Py_MEMCPY(dest,
3240+
memcpy(dest,
32413241
writer->small_buffer,
32423242
pos);
32433243
}
@@ -3372,7 +3372,7 @@ _PyBytesWriter_WriteBytes(_PyBytesWriter *writer, void *ptr,
33723372
if (str == NULL)
33733373
return NULL;
33743374

3375-
Py_MEMCPY(str, bytes, size);
3375+
memcpy(str, bytes, size);
33763376
str += size;
33773377

33783378
return str;

Objects/stringlib/join.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ STRINGLIB(bytes_join)(PyObject *sep, PyObject *iterable)
107107
for (i = 0; i < nbufs; i++) {
108108
Py_ssize_t n = buffers[i].len;
109109
char *q = buffers[i].buf;
110-
Py_MEMCPY(p, q, n);
110+
memcpy(p, q, n);
111111
p += n;
112112
}
113113
goto done;
@@ -116,12 +116,12 @@ STRINGLIB(bytes_join)(PyObject *sep, PyObject *iterable)
116116
Py_ssize_t n;
117117
char *q;
118118
if (i) {
119-
Py_MEMCPY(p, sepstr, seplen);
119+
memcpy(p, sepstr, seplen);
120120
p += seplen;
121121
}
122122
n = buffers[i].len;
123123
q = buffers[i].buf;
124-
Py_MEMCPY(p, q, n);
124+
memcpy(p, q, n);
125125
p += n;
126126
}
127127
goto done;

0 commit comments

Comments
 (0)