diff -r eafff38a56cc Objects/unicodeobject.c --- a/Objects/unicodeobject.c Fri May 10 05:22:14 2013 +0300 +++ b/Objects/unicodeobject.c Fri May 10 21:37:20 2013 +0300 @@ -4641,6 +4641,10 @@ # error C 'long' size should be either 4 or 8! #endif +/* Try to decode ASCII-encoded string into PyASCIIObject. + + Returns a number of succesfully decoded characters. */ + static Py_ssize_t ascii_decode(const char *start, const char *end, Py_UCS1 *dest) { @@ -4648,13 +4652,18 @@ const char *aligned_end = (const char *) _Py_ALIGN_DOWN(end, SIZEOF_LONG); #if SIZEOF_LONG <= SIZEOF_VOID_P - assert(_Py_IS_ALIGNED(dest, SIZEOF_LONG)); - if (_Py_IS_ALIGNED(p, SIZEOF_LONG)) { - /* Fast path, see in STRINGLIB(utf8_decode) for - an explanation. */ + /* Fast path, see in STRINGLIB(utf8_decode) for + an explanation. + dest is always aligned on common platforms + (if sizeof(PyASCIIObject) is divisible by SIZEOF_LONG). + p is aligned on common platforms for bytes and bytearrays + (but may not be for a general buffer). */ + if (sizeof(PyASCIIObject) % SIZEOF_LONG == 0 && + _Py_IS_ALIGNED(p, SIZEOF_LONG)) { /* Help register allocation */ register const char *_p = p; register Py_UCS1 * q = dest; + assert(_Py_IS_ALIGNED(dest, SIZEOF_LONG)); while (_p < aligned_end) { unsigned long value = *(const unsigned long *) _p; if (value & ASCII_CHAR_MASK)