Rémi Bernon : ntdll: Use the unrolled memset from msvcrt.
Alexandre Julliard
julliard at winehq.org
Mon Oct 25 16:30:08 CDT 2021
Module: wine
Branch: master
Commit: a602bdd326cf09b9c77ecbd4cb59af3c32bf2ecd
URL: https://source.winehq.org/git/wine.git/?a=commit;h=a602bdd326cf09b9c77ecbd4cb59af3c32bf2ecd
Author: Rémi Bernon <rbernon at codeweavers.com>
Date: Thu Oct 21 10:44:30 2021 +0200
ntdll: Use the unrolled memset from msvcrt.
Although less frequently used, heap allocations are zeroed out with
ntdll memset and they don't benefit from the msvcrt memset optimisation.
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/ntdll/string.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 63 insertions(+), 3 deletions(-)
diff --git a/dlls/ntdll/string.c b/dlls/ntdll/string.c
index fe484426bcb..0fa83821d21 100644
--- a/dlls/ntdll/string.c
+++ b/dlls/ntdll/string.c
@@ -25,6 +25,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <stdint.h>
#include "windef.h"
#include "winbase.h"
@@ -140,13 +141,72 @@ void * __cdecl memmove( void *dst, const void *src, size_t n )
}
+static inline void memset_aligned_32( unsigned char *d, uint64_t v, size_t n )
+{
+ unsigned char *end = d + n;
+ while (d < end)
+ {
+ *(uint64_t *)(d + 0) = v;
+ *(uint64_t *)(d + 8) = v;
+ *(uint64_t *)(d + 16) = v;
+ *(uint64_t *)(d + 24) = v;
+ d += 32;
+ }
+}
+
/*********************************************************************
* memset (NTDLL.@)
*/
-void * __cdecl memset( void *dst, int c, size_t n )
+void *__cdecl memset( void *dst, int c, size_t n )
{
- volatile unsigned char *d = dst; /* avoid gcc optimizations */
- while (n--) *d++ = c;
+ typedef uint64_t DECLSPEC_ALIGN(1) unaligned_ui64;
+ typedef uint32_t DECLSPEC_ALIGN(1) unaligned_ui32;
+ typedef uint16_t DECLSPEC_ALIGN(1) unaligned_ui16;
+
+ uint64_t v = 0x101010101010101ull * (unsigned char)c;
+ unsigned char *d = (unsigned char *)dst;
+ size_t a = 0x20 - ((uintptr_t)d & 0x1f);
+
+ if (n >= 16)
+ {
+ *(unaligned_ui64 *)(d + 0) = v;
+ *(unaligned_ui64 *)(d + 8) = v;
+ *(unaligned_ui64 *)(d + n - 16) = v;
+ *(unaligned_ui64 *)(d + n - 8) = v;
+ if (n <= 32) return dst;
+ *(unaligned_ui64 *)(d + 16) = v;
+ *(unaligned_ui64 *)(d + 24) = v;
+ *(unaligned_ui64 *)(d + n - 32) = v;
+ *(unaligned_ui64 *)(d + n - 24) = v;
+ if (n <= 64) return dst;
+
+ n = (n - a) & ~0x1f;
+ memset_aligned_32( d + a, v, n );
+ return dst;
+ }
+ if (n >= 8)
+ {
+ *(unaligned_ui64 *)d = v;
+ *(unaligned_ui64 *)(d + n - 8) = v;
+ return dst;
+ }
+ if (n >= 4)
+ {
+ *(unaligned_ui32 *)d = v;
+ *(unaligned_ui32 *)(d + n - 4) = v;
+ return dst;
+ }
+ if (n >= 2)
+ {
+ *(unaligned_ui16 *)d = v;
+ *(unaligned_ui16 *)(d + n - 2) = v;
+ return dst;
+ }
+ if (n >= 1)
+ {
+ *(uint8_t *)d = v;
+ return dst;
+ }
return dst;
}
More information about the wine-cvs
mailing list