diff options
Diffstat (limited to 'contrib/tools/python3/src/Objects/stringlib/codecs.h')
| -rw-r--r-- | contrib/tools/python3/src/Objects/stringlib/codecs.h | 39 |
1 files changed, 18 insertions, 21 deletions
diff --git a/contrib/tools/python3/src/Objects/stringlib/codecs.h b/contrib/tools/python3/src/Objects/stringlib/codecs.h index 9b2a29ba3b8..b17cda18f54 100644 --- a/contrib/tools/python3/src/Objects/stringlib/codecs.h +++ b/contrib/tools/python3/src/Objects/stringlib/codecs.h @@ -4,16 +4,16 @@ # error "codecs.h is specific to Unicode" #endif -#include "pycore_byteswap.h" // _Py_bswap32() +#include "pycore_bitutils.h" // _Py_bswap32() -/* Mask to quickly check whether a C 'long' contains a +/* Mask to quickly check whether a C 'size_t' contains a non-ASCII, UTF8-encoded char. */ -#if (SIZEOF_LONG == 8) -# define ASCII_CHAR_MASK 0x8080808080808080UL -#elif (SIZEOF_LONG == 4) -# define ASCII_CHAR_MASK 0x80808080UL +#if (SIZEOF_SIZE_T == 8) +# define ASCII_CHAR_MASK 0x8080808080808080ULL +#elif (SIZEOF_SIZE_T == 4) +# define ASCII_CHAR_MASK 0x80808080U #else -# error C 'long' size should be either 4 or 8! +# error C 'size_t' size should be either 4 or 8! #endif /* 10xxxxxx */ @@ -26,7 +26,6 @@ STRINGLIB(utf8_decode)(const char **inptr, const char *end, { Py_UCS4 ch; const char *s = *inptr; - const char *aligned_end = (const char *) _Py_ALIGN_DOWN(end, SIZEOF_LONG); STRINGLIB_CHAR *p = dest + *outpos; while (s < end) { @@ -36,19 +35,19 @@ STRINGLIB(utf8_decode)(const char **inptr, const char *end, /* Fast path for runs of ASCII characters. Given that common UTF-8 input will consist of an overwhelming majority of ASCII characters, we try to optimize for this case by checking - as many characters as a C 'long' can contain. + as many characters as a C 'size_t' can contain. First, check if we can do an aligned read, as most CPUs have a penalty for unaligned reads. */ - if (_Py_IS_ALIGNED(s, SIZEOF_LONG)) { + if (_Py_IS_ALIGNED(s, ALIGNOF_SIZE_T)) { /* Help register allocation */ const char *_s = s; STRINGLIB_CHAR *_p = p; - while (_s < aligned_end) { - /* Read a whole long at a time (either 4 or 8 bytes), + while (_s + SIZEOF_SIZE_T <= end) { + /* Read a whole size_t at a time (either 4 or 8 bytes), and do a fast unrolled copy if it only contains ASCII characters. */ - unsigned long value = *(const unsigned long *) _s; + size_t value = *(const size_t *) _s; if (value & ASCII_CHAR_MASK) break; #if PY_LITTLE_ENDIAN @@ -56,14 +55,14 @@ STRINGLIB(utf8_decode)(const char **inptr, const char *end, _p[1] = (STRINGLIB_CHAR)((value >> 8) & 0xFFu); _p[2] = (STRINGLIB_CHAR)((value >> 16) & 0xFFu); _p[3] = (STRINGLIB_CHAR)((value >> 24) & 0xFFu); -# if SIZEOF_LONG == 8 +# if SIZEOF_SIZE_T == 8 _p[4] = (STRINGLIB_CHAR)((value >> 32) & 0xFFu); _p[5] = (STRINGLIB_CHAR)((value >> 40) & 0xFFu); _p[6] = (STRINGLIB_CHAR)((value >> 48) & 0xFFu); _p[7] = (STRINGLIB_CHAR)((value >> 56) & 0xFFu); # endif #else -# if SIZEOF_LONG == 8 +# if SIZEOF_SIZE_T == 8 _p[0] = (STRINGLIB_CHAR)((value >> 56) & 0xFFu); _p[1] = (STRINGLIB_CHAR)((value >> 48) & 0xFFu); _p[2] = (STRINGLIB_CHAR)((value >> 40) & 0xFFu); @@ -79,8 +78,8 @@ STRINGLIB(utf8_decode)(const char **inptr, const char *end, _p[3] = (STRINGLIB_CHAR)(value & 0xFFu); # endif #endif - _s += SIZEOF_LONG; - _p += SIZEOF_LONG; + _s += SIZEOF_SIZE_T; + _p += SIZEOF_SIZE_T; } s = _s; p = _p; @@ -496,8 +495,6 @@ STRINGLIB(utf16_decode)(const unsigned char **inptr, const unsigned char *e, int native_ordering) { Py_UCS4 ch; - const unsigned char *aligned_end = - (const unsigned char *) _Py_ALIGN_DOWN(e, SIZEOF_LONG); const unsigned char *q = *inptr; STRINGLIB_CHAR *p = dest + *outpos; /* Offsets from q for retrieving byte pairs in the right order. */ @@ -512,10 +509,10 @@ STRINGLIB(utf16_decode)(const unsigned char **inptr, const unsigned char *e, Py_UCS4 ch2; /* First check for possible aligned read of a C 'long'. Unaligned reads are more expensive, better to defer to another iteration. */ - if (_Py_IS_ALIGNED(q, SIZEOF_LONG)) { + if (_Py_IS_ALIGNED(q, ALIGNOF_LONG)) { /* Fast path for runs of in-range non-surrogate chars. */ const unsigned char *_q = q; - while (_q < aligned_end) { + while (_q + SIZEOF_LONG <= e) { unsigned long block = * (const unsigned long *) _q; if (native_ordering) { /* Can use buffer directly */ |
