@@ -577,6 +577,14 @@ on 1 byte), but shoehorning those bytes into integers efficiently is messy.
577577#pragma GCC diagnostic push
578578#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
579579
580+ #ifndef __has_feature
581+ #define __has_feature (x ) 0
582+ #endif
583+
584+ #if defined(__SANITIZE_ADDRESS__) || __has_feature(address_sanitizer)
585+ #define VALGRIND
586+ #endif
587+
580588#ifdef __be__
581589# define HASH_LITTLE_ENDIAN 0
582590# define HASH_BIG_ENDIAN 1
@@ -739,6 +747,7 @@ uint32_t MathLib::hashlittle( const void *key, size_t length, uint32_t initval)
739747 * still catch it and complain. The masking trick does make the hash
740748 * noticably faster for short strings (like English words).
741749 */
750+ #ifndef VALGRIND
742751
743752 switch (length)
744753 {
@@ -757,6 +766,28 @@ uint32_t MathLib::hashlittle( const void *key, size_t length, uint32_t initval)
757766 case 0 : return c; /* zero length strings require no mixing */
758767 }
759768
769+ #else /* make valgrind happy */
770+
771+ const uint8_t *k8 = (const uint8_t *)k;
772+ switch (length)
773+ {
774+ case 12 : c+=k[2 ]; b+=k[1 ]; a+=k[0 ]; break ;
775+ case 11 : c+=((uint32_t )k8[10 ])<<16 ; /* fall through */
776+ case 10 : c+=((uint32_t )k8[9 ])<<8 ; /* fall through */
777+ case 9 : c+=k8[8 ]; /* fall through */
778+ case 8 : b+=k[1 ]; a+=k[0 ]; break ;
779+ case 7 : b+=((uint32_t )k8[6 ])<<16 ; /* fall through */
780+ case 6 : b+=((uint32_t )k8[5 ])<<8 ; /* fall through */
781+ case 5 : b+=k8[4 ]; /* fall through */
782+ case 4 : a+=k[0 ]; break ;
783+ case 3 : a+=((uint32_t )k8[2 ])<<16 ; /* fall through */
784+ case 2 : a+=((uint32_t )k8[1 ])<<8 ; /* fall through */
785+ case 1 : a+=k8[0 ]; break ;
786+ case 0 : return c;
787+ }
788+
789+ #endif /* !valgrind */
790+
760791 } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1 ) == 0 )) {
761792 const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */
762793 const uint8_t *k8;
@@ -899,6 +930,7 @@ void MathLib::hashlittle2(
899930 * still catch it and complain. The masking trick does make the hash
900931 * noticably faster for short strings (like English words).
901932 */
933+ #ifndef VALGRIND
902934
903935 switch (length)
904936 {
@@ -917,6 +949,28 @@ void MathLib::hashlittle2(
917949 case 0 : *pc=c; *pb=b; return ; /* zero length strings require no mixing */
918950 }
919951
952+ #else /* make valgrind happy */
953+
954+ const uint8_t *k8 = (const uint8_t *)k;
955+ switch (length)
956+ {
957+ case 12 : c+=k[2 ]; b+=k[1 ]; a+=k[0 ]; break ;
958+ case 11 : c+=((uint32_t )k8[10 ])<<16 ; /* fall through */
959+ case 10 : c+=((uint32_t )k8[9 ])<<8 ; /* fall through */
960+ case 9 : c+=k8[8 ]; /* fall through */
961+ case 8 : b+=k[1 ]; a+=k[0 ]; break ;
962+ case 7 : b+=((uint32_t )k8[6 ])<<16 ; /* fall through */
963+ case 6 : b+=((uint32_t )k8[5 ])<<8 ; /* fall through */
964+ case 5 : b+=k8[4 ]; /* fall through */
965+ case 4 : a+=k[0 ]; break ;
966+ case 3 : a+=((uint32_t )k8[2 ])<<16 ; /* fall through */
967+ case 2 : a+=((uint32_t )k8[1 ])<<8 ; /* fall through */
968+ case 1 : a+=k8[0 ]; break ;
969+ case 0 : *pc=c; *pb=b; return ; /* zero length strings require no mixing */
970+ }
971+
972+ #endif /* !valgrind */
973+
920974 } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1 ) == 0 )) {
921975 const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */
922976 const uint8_t *k8;
@@ -1050,6 +1104,7 @@ uint32_t MathLib::hashbig( const void *key, size_t length, uint32_t initval)
10501104 * still catch it and complain. The masking trick does make the hash
10511105 * noticably faster for short strings (like English words).
10521106 */
1107+ #ifndef VALGRIND
10531108
10541109 switch (length)
10551110 {
@@ -1068,6 +1123,28 @@ uint32_t MathLib::hashbig( const void *key, size_t length, uint32_t initval)
10681123 case 0 : return c; /* zero length strings require no mixing */
10691124 }
10701125
1126+ #else /* make valgrind happy */
1127+
1128+ const uint8_t *k8 = (const uint8_t *)k;
1129+ switch (length) /* all the case statements fall through */
1130+ {
1131+ case 12 : c+=k[2 ]; b+=k[1 ]; a+=k[0 ]; break ;
1132+ case 11 : c+=((uint32_t )k8[10 ])<<8 ; /* fall through */
1133+ case 10 : c+=((uint32_t )k8[9 ])<<16 ; /* fall through */
1134+ case 9 : c+=((uint32_t )k8[8 ])<<24 ; /* fall through */
1135+ case 8 : b+=k[1 ]; a+=k[0 ]; break ;
1136+ case 7 : b+=((uint32_t )k8[6 ])<<8 ; /* fall through */
1137+ case 6 : b+=((uint32_t )k8[5 ])<<16 ; /* fall through */
1138+ case 5 : b+=((uint32_t )k8[4 ])<<24 ; /* fall through */
1139+ case 4 : a+=k[0 ]; break ;
1140+ case 3 : a+=((uint32_t )k8[2 ])<<8 ; /* fall through */
1141+ case 2 : a+=((uint32_t )k8[1 ])<<16 ; /* fall through */
1142+ case 1 : a+=((uint32_t )k8[0 ])<<24 ; break ;
1143+ case 0 : return c;
1144+ }
1145+
1146+ #endif /* !VALGRIND */
1147+
10711148 } else { /* need to read the key one byte at a time */
10721149 const uint8_t *k = (const uint8_t *)key;
10731150
0 commit comments