소스 검색

reenable word-at-at-time copying in memmove

before restrict was added, memove called memcpy for forward copies and
used a byte-at-a-time loop for reverse copies. this was changed to
avoid invoking UB now that memcpy has an undefined copying order,
making memmove considerably slower.

performance is still rather bad, so I'll be adding asm soon.
Rich Felker 12 년 전
부모
커밋
1701e4f3d4
1개의 변경된 파일27개의 추가작업 그리고 4개의 파일을 삭제
  1. 27 4
      src/string/memmove.c

+ 27 - 4
src/string/memmove.c

@@ -1,13 +1,36 @@
 #include <string.h>
+#include <stdint.h>
+
+#define WT size_t
+#define WS (sizeof(WT))
 
 void *memmove(void *dest, const void *src, size_t n)
 {
 	char *d = dest;
 	const char *s = src;
+
 	if (d==s) return d;
-	if ((size_t)(d-s) < n)
-		while (n--) d[n] = s[n];
-	else
-		while (n--) *d++ = *s++;
+	if (s+n <= d || d+n <= s) return memcpy(d, s, n);
+
+	if (d<s) {
+		if ((uintptr_t)s % WS == (uintptr_t)d % WS) {
+			while ((uintptr_t)d % WS) {
+				if (!n--) return dest;
+				*d++ = *s++;
+			}
+			for (; n>=WS; n-=WS, d+=WS, s+=WS) *(WT *)d = *(WT *)s;
+		}
+		for (; n; n--) *d++ = *s++;
+	} else {
+		if ((uintptr_t)s % WS == (uintptr_t)d % WS) {
+			while ((uintptr_t)(d+n) % WS) {
+				if (!n--) return dest;
+				d[n] = s[n];
+			}
+			while (n>=WS) n-=WS, *(WT *)(d+n) = *(WT *)(s+n);
+		}
+		while (n) n--, d[n] = s[n];
+	}
+
 	return dest;
 }