|
38 | 38 | #include <utility> |
39 | 39 | #include <vector> |
40 | 40 |
|
41 | | -#include "absl/base/internal/endian.h" |
| 41 | +#include "absl/base/config.h" |
| 42 | +#include "absl/base/internal/unaligned_access.h" |
42 | 43 | #include "absl/base/port.h" |
43 | 44 | #include "absl/container/fixed_array.h" |
44 | 45 | #include "absl/hash/internal/wyhash.h" |
@@ -804,26 +805,54 @@ class ABSL_DLL HashState : public HashStateBase<HashState> { |
804 | 805 | size_t len); |
805 | 806 |
|
806 | 807 | // Reads 9 to 16 bytes from p. |
807 | | - // The first 8 bytes are in .first, the rest (zero padded) bytes are in |
808 | | - // .second. |
| 808 | + // The least significant 8 bytes are in .first, the rest (zero padded) bytes |
| 809 | + // are in .second. |
809 | 810 | static std::pair<uint64_t, uint64_t> Read9To16(const unsigned char* p, |
810 | 811 | size_t len) { |
811 | | - uint64_t high = little_endian::Load64(p + len - 8); |
812 | | - return {little_endian::Load64(p), high >> (128 - len * 8)}; |
| 812 | + uint64_t low_mem = absl::base_internal::UnalignedLoad64(p); |
| 813 | + uint64_t high_mem = absl::base_internal::UnalignedLoad64(p + len - 8); |
| 814 | +#ifdef ABSL_IS_LITTLE_ENDIAN |
| 815 | + uint64_t most_significant = high_mem; |
| 816 | + uint64_t least_significant = low_mem; |
| 817 | +#else |
| 818 | + uint64_t most_significant = low_mem; |
| 819 | + uint64_t least_significant = high_mem; |
| 820 | +#endif |
| 821 | + return {least_significant, most_significant >> (128 - len * 8)}; |
813 | 822 | } |
814 | 823 |
|
815 | 824 | // Reads 4 to 8 bytes from p. Zero pads to fill uint64_t. |
816 | 825 | static uint64_t Read4To8(const unsigned char* p, size_t len) { |
817 | | - return (static_cast<uint64_t>(little_endian::Load32(p + len - 4)) |
818 | | - << (len - 4) * 8) | |
819 | | - little_endian::Load32(p); |
| 826 | + uint32_t low_mem = absl::base_internal::UnalignedLoad32(p); |
| 827 | + uint32_t high_mem = absl::base_internal::UnalignedLoad32(p + len - 4); |
| 828 | +#ifdef ABSL_IS_LITTLE_ENDIAN |
| 829 | + uint32_t most_significant = high_mem; |
| 830 | + uint32_t least_significant = low_mem; |
| 831 | +#else |
| 832 | + uint32_t most_significant = low_mem; |
| 833 | + uint32_t least_significant = high_mem; |
| 834 | +#endif |
| 835 | + return (static_cast<uint64_t>(most_significant) << (len - 4) * 8) | |
| 836 | + least_significant; |
820 | 837 | } |
821 | 838 |
|
822 | 839 | // Reads 1 to 3 bytes from p. Zero pads to fill uint32_t. |
823 | 840 | static uint32_t Read1To3(const unsigned char* p, size_t len) { |
824 | | - return static_cast<uint32_t>((p[0]) | // |
825 | | - (p[len / 2] << (len / 2 * 8)) | // |
826 | | - (p[len - 1] << ((len - 1) * 8))); |
| 841 | + unsigned char mem0 = p[0]; |
| 842 | + unsigned char mem1 = p[len / 2]; |
| 843 | + unsigned char mem2 = p[len - 1]; |
| 844 | +#ifdef ABSL_IS_LITTLE_ENDIAN |
| 845 | + unsigned char significant2 = mem2; |
| 846 | + unsigned char significant1 = mem1; |
| 847 | + unsigned char significant0 = mem0; |
| 848 | +#else |
| 849 | + unsigned char significant2 = mem0; |
| 850 | + unsigned char significant1 = mem1; |
| 851 | + unsigned char significant0 = mem2; |
| 852 | +#endif |
| 853 | + return static_cast<uint32_t>(significant0 | // |
| 854 | + (significant1 << (len / 2 * 8)) | // |
| 855 | + (significant2 << ((len - 1) * 8))); |
827 | 856 | } |
828 | 857 |
|
829 | 858 | ABSL_ATTRIBUTE_ALWAYS_INLINE static uint64_t Mix(uint64_t state, uint64_t v) { |
|
0 commit comments