[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master 592a230: * src/fns.c (hash_string): Fix bug#46111
From: |
Stefan Monnier |
Subject: |
master 592a230: * src/fns.c (hash_string): Fix bug#46111 |
Date: |
Thu, 28 Jan 2021 12:28:11 -0500 (EST) |
branch: master
commit 592a230832257e915aa3ed798a1f0210df639031
Author: Stefan Monnier <monnier@iro.umontreal.ca>
Commit: Stefan Monnier <monnier@iro.umontreal.ca>
* src/fns.c (hash_string): Fix bug#46111
Use `memcpy` instead of an unaligned memory access. On x86 at least,
GCC turns this `memcpy` into a single `mov`, so it's about as fast.
---
src/fns.c | 34 +++++++++++++++-------------------
1 file changed, 15 insertions(+), 19 deletions(-)
diff --git a/src/fns.c b/src/fns.c
index 7ab2e8f..bd4afa0 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -4599,33 +4599,29 @@ sweep_weak_table (struct Lisp_Hash_Table *h, bool
remove_entries_p)
EMACS_UINT
hash_string (char const *ptr, ptrdiff_t len)
{
- EMACS_UINT const *p = (EMACS_UINT const *) ptr;
- EMACS_UINT const *end = (EMACS_UINT const *) (ptr + len);
+ char const *p = ptr;
+ char const *end = ptr + len;
EMACS_UINT hash = len;
/* At most 8 steps. We could reuse SXHASH_MAX_LEN, of course,
* but dividing by 8 is cheaper. */
- ptrdiff_t step = 1 + ((end - p) >> 3);
+ ptrdiff_t step = sizeof hash + ((end - p) >> 3);
- /* Beware: `end` might be unaligned, so `p < end` is not always the same
- * as `p <= end - 1`. */
- while (p <= end - 1)
+ while (p + sizeof hash <= end)
{
- EMACS_UINT c = *p;
+ EMACS_UINT c;
+ /* We presume that the compiler will replace this `memcpy` with
+ a single load/move instruction when applicable. */
+ memcpy (&c, p, sizeof hash);
p += step;
hash = sxhash_combine (hash, c);
}
- if (p < end)
- { /* A few last bytes remain (smaller than an EMACS_UINT). */
- /* FIXME: We could do this without a loop, but it'd require
- endian-dependent code :-( */
- char const *p1 = (char const *)p;
- char const *end1 = (char const *)end;
- do
- {
- unsigned char c = *p1++;
- hash = sxhash_combine (hash, c);
- }
- while (p1 < end1);
+ /* A few last bytes may remain (smaller than an EMACS_UINT). */
+ /* FIXME: We could do this without a loop, but it'd require
+ endian-dependent code :-( */
+ while (p < end)
+ {
+ unsigned char c = *p++;
+ hash = sxhash_combine (hash, c);
}
return hash;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- master 592a230: * src/fns.c (hash_string): Fix bug#46111,
Stefan Monnier <=