diff options
author | Jason Evans <jasone@canonware.com> | 2016-02-20 18:23:48 (GMT) |
---|---|---|
committer | Jason Evans <jasone@canonware.com> | 2016-02-20 18:23:48 (GMT) |
commit | a0aaad1afa8c1c4b30bf15c6b8744084ffc32055 (patch) | |
tree | 55cc2ff4c7341e2460d73afe82ba22f6de2f8789 | |
parent | 9f24c944744e91d0cfe1864287ca7a52c16598fa (diff) | |
download | jemalloc-a0aaad1afa8c1c4b30bf15c6b8744084ffc32055.zip jemalloc-a0aaad1afa8c1c4b30bf15c6b8744084ffc32055.tar.gz jemalloc-a0aaad1afa8c1c4b30bf15c6b8744084ffc32055.tar.bz2 |
Handle unaligned keys in hash().
Reported by Christopher Ferris <cferris@google.com>.
-rw-r--r-- | include/jemalloc/internal/hash.h | 18 | ||||
-rw-r--r-- | test/unit/hash.c | 19 |
2 files changed, 33 insertions, 4 deletions
diff --git a/include/jemalloc/internal/hash.h b/include/jemalloc/internal/hash.h index bcead33..8b5fb03 100644 --- a/include/jemalloc/internal/hash.h +++ b/include/jemalloc/internal/hash.h @@ -1,6 +1,6 @@ /* * The following hash function is based on MurmurHash3, placed into the public - * domain by Austin Appleby. See http://code.google.com/p/smhasher/ for + * domain by Austin Appleby. See https://github.com/aappleby/smhasher for * details. */ /******************************************************************************/ @@ -49,6 +49,14 @@ JEMALLOC_INLINE uint32_t hash_get_block_32(const uint32_t *p, int i) { + /* Handle unaligned read. */ + if (unlikely((uintptr_t)p & (sizeof(uint32_t)-1)) != 0) { + uint32_t ret; + + memcpy(&ret, &p[i], sizeof(uint32_t)); + return (ret); + } + return (p[i]); } @@ -56,6 +64,14 @@ JEMALLOC_INLINE uint64_t hash_get_block_64(const uint64_t *p, int i) { + /* Handle unaligned read. */ + if (unlikely((uintptr_t)p & (sizeof(uint64_t)-1)) != 0) { + uint64_t ret; + + memcpy(&ret, &p[i], sizeof(uint64_t)); + return (ret); + } + return (p[i]); } diff --git a/test/unit/hash.c b/test/unit/hash.c index 77a8ced..ea73d70 100644 --- a/test/unit/hash.c +++ b/test/unit/hash.c @@ -59,17 +59,17 @@ hash_variant_string(hash_variant_t variant) } } +#define KEY_SIZE 256 static void -hash_variant_verify(hash_variant_t variant) +hash_variant_verify_key(hash_variant_t variant, uint8_t *key) { const size_t hashbytes = hash_variant_bits(variant) / 8; - uint8_t key[256]; VARIABLE_ARRAY(uint8_t, hashes, hashbytes * 256); VARIABLE_ARRAY(uint8_t, final, hashbytes); unsigned i; uint32_t computed, expected; - memset(key, 0, sizeof(key)); + memset(key, 0, KEY_SIZE); memset(hashes, 0, sizeof(hashes)); memset(final, 0, sizeof(final)); @@ -139,6 +139,19 @@ hash_variant_verify(hash_variant_t variant) hash_variant_string(variant), expected, computed); } +static void +hash_variant_verify(hash_variant_t variant) +{ +#define MAX_ALIGN 16 + uint8_t key[KEY_SIZE + (MAX_ALIGN - 1)]; + unsigned i; + + for (i = 0; i < MAX_ALIGN; i++) + hash_variant_verify_key(variant, &key[i]); +#undef MAX_ALIGN +} +#undef KEY_SIZE + TEST_BEGIN(test_hash_x86_32) { |