--- a/String.st Sat Jun 13 07:00:29 2015 +0200
+++ b/String.st Wed Jun 17 06:22:00 2015 +0100
@@ -1822,20 +1822,39 @@
long h = me.hash_fnv1a();
return __c__._RETURN(STInteger._new(h));
#else
- extern unsigned int __symbolHash(char *);
- unsigned char *cp;
- unsigned int h;
+ /* Following code is inlined FNV1a hash.
+ * Inlined for speed (to avoid send).
+ * DO NOT use __symbolHash() here as it
+ * does not handle characters with codepoint 0
+ * properly - see
+ * https://swing.fit.cvut.cz/projects/stx-jv/ticket/65
+ */
+ REGISTER unsigned int h;
+ REGISTER unsigned char *cp;
+ int l;
cp = __stringVal(self);
+ l = __stringSize(self);
if (!__qIsStringLike(self)) {
int n = __OBJS2BYTES__(__intVal(__ClassInstPtr(__qClass(self))->c_ninstvars));
cp += n;
+ }
+ h = 2166136261U;
+ while (l >= 4) {
+ l -= 4;
+ h = (h ^ cp[0]) * 16777619;
+ h = (h ^ cp[1]) * 16777619;
+ h = (h ^ cp[2]) * 16777619;
+ h = (h ^ cp[3]) * 16777619;
+ cp += 4;
}
- h = __symbolHash(cp);
- // make sure, it fits into a smallInt
+ while (l--) {
+ h = (h ^ *cp++) * 16777619;
+ }
+ // make it a smallInteger
h = (h ^ (h >> 30)) & 0x3FFFFFFF;
- RETURN(__mkSmallInteger(h));
+ RETURN ( __mkSmallInteger(h));
#endif /* not SCHTEAM */
%}.
^ self primitiveFailed
@@ -1932,7 +1951,7 @@
l -= n;
}
- h = 2166136261;
+ h = 2166136261U;
while (l >= 4) {
l -= 4;
h = (h ^ cp[0]) * 16777619;