diff -r 9214f8440c44 Objects/unicodeobject.c --- a/Objects/unicodeobject.c Sat Nov 10 14:52:10 2012 +0000 +++ b/Objects/unicodeobject.c Sun Nov 11 10:40:55 2012 +0200 @@ -10882,6 +10882,7 @@ { Py_ssize_t len; Py_uhash_t x; + unsigned char *p; #ifdef Py_DEBUG assert(_Py_HashSecret_Initialized); @@ -10899,37 +10900,23 @@ _PyUnicode_HASH(self) = 0; return 0; } - - /* The hash function as a macro, gets expanded three times below. */ -#define HASH(P) \ - x ^= (Py_uhash_t) *P << 7; \ - while (--len >= 0) \ - x = (_PyHASH_MULTIPLIER * x) ^ (Py_uhash_t) *P++; \ - + p = PyUnicode_DATA(self); x = (Py_uhash_t) _Py_HashSecret.prefix; - switch (PyUnicode_KIND(self)) { - case PyUnicode_1BYTE_KIND: { - const unsigned char *c = PyUnicode_1BYTE_DATA(self); - HASH(c); - break; - } - case PyUnicode_2BYTE_KIND: { - const Py_UCS2 *s = PyUnicode_2BYTE_DATA(self); - HASH(s); - break; - } - default: { - Py_UCS4 *l; - assert(PyUnicode_KIND(self) == PyUnicode_4BYTE_KIND && - "Impossible switch case in unicode_hash"); - l = PyUnicode_4BYTE_DATA(self); - HASH(l); - break; - } - } + x ^= (Py_uhash_t) *p << 7; + len *= PyUnicode_KIND(self); + assert(_Py_IS_ALIGNED(p, sizeof(size_t))); + if (len >= sizeof(size_t)) { + size_t *q = (size_t *)p; + size_t *e = (size_t *)_Py_ALIGN_DOWN(p + len, sizeof(size_t)); + while (q < e) + x = (_PyHASH_MULTIPLIER * x) ^ (Py_uhash_t) *q++; + len -= (unsigned char *)q - p; + p = (unsigned char *)q; + } + while (len--) + x = (_PyHASH_MULTIPLIER * x) ^ (Py_uhash_t) *p++; x ^= (Py_uhash_t) PyUnicode_GET_LENGTH(self); x ^= (Py_uhash_t) _Py_HashSecret.suffix; - if (x == -1) x = -2; _PyUnicode_HASH(self) = x;