Mercurial > hg > xemacs-beta
diff src/text.h @ 5774:7a538e1a4676
Use skip_ascii() in no_conversion_convert() when encoding.
src/ChangeLog addition:
2013-12-19 Aidan Kehoe <kehoea@parhasard.net>
* text.c:
* text.h:
* text.h (skip_ascii):
Move skip_ascii (), the very fast inline function from the
bytecount-to-charcount code, to text.h, to allow the coding
systems to use it too as needed.
* file-coding.c (no_conversion_convert):
Use skip_ascii() as appropriate here, halving the time taken to
write large files in my tests (again, relevant to VM buffers, but
not a panacea to our issues with them.)
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Thu, 19 Dec 2013 18:13:11 +0000 |
parents | 308d34e9f07d |
children | 0cb4f494a548 |
line wrap: on
line diff
--- a/src/text.h Tue Dec 17 20:49:52 2013 +0200 +++ b/src/text.h Thu Dec 19 18:13:11 2013 +0000 @@ -831,12 +831,91 @@ } } +#ifdef EFFICIENT_INT_128_BIT +# define STRIDE_TYPE INT_128_BIT +# define HIGH_BIT_MASK \ + MAKE_128_BIT_UNSIGNED_CONSTANT (0x80808080808080808080808080808080) +#elif defined (EFFICIENT_INT_64_BIT) +# define STRIDE_TYPE INT_64_BIT +# define HIGH_BIT_MASK MAKE_64_BIT_UNSIGNED_CONSTANT (0x8080808080808080) +#else +# define STRIDE_TYPE INT_32_BIT +# define HIGH_BIT_MASK MAKE_32_BIT_UNSIGNED_CONSTANT (0x80808080) +#endif + +#define ALIGN_BITS ((EMACS_UINT) (ALIGNOF (STRIDE_TYPE) - 1)) +#define ALIGN_MASK (~ ALIGN_BITS) +#define ALIGNED(ptr) ((((EMACS_UINT) ptr) & ALIGN_BITS) == 0) +#define STRIDE sizeof (STRIDE_TYPE) + +/* Skip as many ASCII bytes as possible in the memory block [PTR, END). + Return pointer to the first non-ASCII byte. optimized for long + stretches of ASCII. */ +DECLARE_INLINE_HEADER ( +const Ibyte * +skip_ascii (const Ibyte *ptr, const Ibyte *end) +) +{ + const unsigned STRIDE_TYPE *ascii_end; + + /* Need to do in 3 sections -- before alignment start, aligned chunk, + after alignment end. */ + while (!ALIGNED (ptr)) + { + if (ptr == end || !byte_ascii_p (*ptr)) + return ptr; + ptr++; + } + ascii_end = (const unsigned STRIDE_TYPE *) ptr; + /* This loop screams, because we can detect ASCII + characters 4 or 8 at a time. */ + while ((const Ibyte *) ascii_end + STRIDE <= end + && !(*ascii_end & HIGH_BIT_MASK)) + ascii_end++; + ptr = (Ibyte *) ascii_end; + while (ptr < end && byte_ascii_p (*ptr)) + ptr++; + return ptr; +} + +/* Skip as many ASCII bytes as possible in the memory block [END, PTR), + going downwards. Return pointer to the location above the first + non-ASCII byte. Optimized for long stretches of ASCII. */ +DECLARE_INLINE_HEADER ( +const Ibyte * +skip_ascii_down (const Ibyte *ptr, const Ibyte *end) +) +{ + const unsigned STRIDE_TYPE *ascii_end; + + /* Need to do in 3 sections -- before alignment start, aligned chunk, + after alignment end. */ + while (!ALIGNED (ptr)) + { + if (ptr == end || !byte_ascii_p (*(ptr - 1))) + return ptr; + ptr--; + } + ascii_end = (const unsigned STRIDE_TYPE *) ptr - 1; + /* This loop screams, because we can detect ASCII + characters 4 or 8 at a time. */ + while ((const Ibyte *) ascii_end >= end + && !(*ascii_end & HIGH_BIT_MASK)) + ascii_end--; + ptr = (Ibyte *) (ascii_end + 1); + while (ptr > end && byte_ascii_p (*(ptr - 1))) + ptr--; + return ptr; +} + #else #define bytecount_to_charcount(ptr, len) ((Charcount) (len)) #define bytecount_to_charcount_fmt(ptr, len, fmt) ((Charcount) (len)) #define charcount_to_bytecount(ptr, len) ((Bytecount) (len)) #define charcount_to_bytecount_fmt(ptr, len, fmt) ((Bytecount) (len)) +#define skip_ascii(ptr, end) end +#define skip_ascii_down(ptr, end) end #endif /* MULE */