Fix murmur hash implementations to work on strict alignment
authorMatthew Dempsky <mdempsky@google.com>
Mon, 8 Jul 2013 17:47:57 +0000 (10:47 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Mon, 8 Jul 2013 17:49:49 +0000 (10:49 -0700)
architectures like OpenBSD/mips64el and OpenBSD/hppa64.

src/build_log.cc
src/hash_map.h

index 6b73002..a040ce2 100644 (file)
@@ -54,26 +54,27 @@ uint64_t MurmurHash64A(const void* key, size_t len) {
   const uint64_t m = BIG_CONSTANT(0xc6a4a7935bd1e995);
   const int r = 47;
   uint64_t h = seed ^ (len * m);
-  const uint64_t * data = (const uint64_t *)key;
-  const uint64_t * end = data + (len/8);
-  while (data != end) {
-    uint64_t k = *data++;
+  const unsigned char * data = (const unsigned char *)key;
+  while (len >= 8) {
+    uint64_t k;
+    memcpy(&k, data, sizeof k);
     k *= m;
     k ^= k >> r;
     k *= m;
     h ^= k;
     h *= m;
+    data += 8;
+    len -= 8;
   }
-  const unsigned char* data2 = (const unsigned char*)data;
   switch (len & 7)
   {
-  case 7: h ^= uint64_t(data2[6]) << 48;
-  case 6: h ^= uint64_t(data2[5]) << 40;
-  case 5: h ^= uint64_t(data2[4]) << 32;
-  case 4: h ^= uint64_t(data2[3]) << 24;
-  case 3: h ^= uint64_t(data2[2]) << 16;
-  case 2: h ^= uint64_t(data2[1]) << 8;
-  case 1: h ^= uint64_t(data2[0]);
+  case 7: h ^= uint64_t(data[6]) << 48;
+  case 6: h ^= uint64_t(data[5]) << 40;
+  case 5: h ^= uint64_t(data[4]) << 32;
+  case 4: h ^= uint64_t(data[3]) << 24;
+  case 3: h ^= uint64_t(data[2]) << 16;
+  case 2: h ^= uint64_t(data[1]) << 8;
+  case 1: h ^= uint64_t(data[0]);
           h *= m;
   };
   h ^= h >> r;
index 076f6c0..919b6fc 100644 (file)
@@ -15,6 +15,7 @@
 #ifndef NINJA_MAP_H_
 #define NINJA_MAP_H_
 
+#include <string.h>
 #include "string_piece.h"
 
 // MurmurHash2, by Austin Appleby
@@ -26,7 +27,8 @@ unsigned int MurmurHash2(const void* key, size_t len) {
   unsigned int h = seed ^ len;
   const unsigned char * data = (const unsigned char *)key;
   while (len >= 4) {
-    unsigned int k = *(unsigned int *)data;
+    unsigned int k;
+    memcpy(&k, data, sizeof k);
     k *= m;
     k ^= k >> r;
     k *= m;