comparison 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
comparison
equal deleted inserted replaced
5773:94a6b8fbd56e 5774:7a538e1a4676
829 text_checking_assert (fmt == FORMAT_8_BIT_FIXED); 829 text_checking_assert (fmt == FORMAT_8_BIT_FIXED);
830 return (Bytecount) len; 830 return (Bytecount) len;
831 } 831 }
832 } 832 }
833 833
834 #ifdef EFFICIENT_INT_128_BIT
835 # define STRIDE_TYPE INT_128_BIT
836 # define HIGH_BIT_MASK \
837 MAKE_128_BIT_UNSIGNED_CONSTANT (0x80808080808080808080808080808080)
838 #elif defined (EFFICIENT_INT_64_BIT)
839 # define STRIDE_TYPE INT_64_BIT
840 # define HIGH_BIT_MASK MAKE_64_BIT_UNSIGNED_CONSTANT (0x8080808080808080)
841 #else
842 # define STRIDE_TYPE INT_32_BIT
843 # define HIGH_BIT_MASK MAKE_32_BIT_UNSIGNED_CONSTANT (0x80808080)
844 #endif
845
846 #define ALIGN_BITS ((EMACS_UINT) (ALIGNOF (STRIDE_TYPE) - 1))
847 #define ALIGN_MASK (~ ALIGN_BITS)
848 #define ALIGNED(ptr) ((((EMACS_UINT) ptr) & ALIGN_BITS) == 0)
849 #define STRIDE sizeof (STRIDE_TYPE)
850
851 /* Skip as many ASCII bytes as possible in the memory block [PTR, END).
852 Return pointer to the first non-ASCII byte. optimized for long
853 stretches of ASCII. */
854 DECLARE_INLINE_HEADER (
855 const Ibyte *
856 skip_ascii (const Ibyte *ptr, const Ibyte *end)
857 )
858 {
859 const unsigned STRIDE_TYPE *ascii_end;
860
861 /* Need to do in 3 sections -- before alignment start, aligned chunk,
862 after alignment end. */
863 while (!ALIGNED (ptr))
864 {
865 if (ptr == end || !byte_ascii_p (*ptr))
866 return ptr;
867 ptr++;
868 }
869 ascii_end = (const unsigned STRIDE_TYPE *) ptr;
870 /* This loop screams, because we can detect ASCII
871 characters 4 or 8 at a time. */
872 while ((const Ibyte *) ascii_end + STRIDE <= end
873 && !(*ascii_end & HIGH_BIT_MASK))
874 ascii_end++;
875 ptr = (Ibyte *) ascii_end;
876 while (ptr < end && byte_ascii_p (*ptr))
877 ptr++;
878 return ptr;
879 }
880
881 /* Skip as many ASCII bytes as possible in the memory block [END, PTR),
882 going downwards. Return pointer to the location above the first
883 non-ASCII byte. Optimized for long stretches of ASCII. */
884 DECLARE_INLINE_HEADER (
885 const Ibyte *
886 skip_ascii_down (const Ibyte *ptr, const Ibyte *end)
887 )
888 {
889 const unsigned STRIDE_TYPE *ascii_end;
890
891 /* Need to do in 3 sections -- before alignment start, aligned chunk,
892 after alignment end. */
893 while (!ALIGNED (ptr))
894 {
895 if (ptr == end || !byte_ascii_p (*(ptr - 1)))
896 return ptr;
897 ptr--;
898 }
899 ascii_end = (const unsigned STRIDE_TYPE *) ptr - 1;
900 /* This loop screams, because we can detect ASCII
901 characters 4 or 8 at a time. */
902 while ((const Ibyte *) ascii_end >= end
903 && !(*ascii_end & HIGH_BIT_MASK))
904 ascii_end--;
905 ptr = (Ibyte *) (ascii_end + 1);
906 while (ptr > end && byte_ascii_p (*(ptr - 1)))
907 ptr--;
908 return ptr;
909 }
910
834 #else 911 #else
835 912
836 #define bytecount_to_charcount(ptr, len) ((Charcount) (len)) 913 #define bytecount_to_charcount(ptr, len) ((Charcount) (len))
837 #define bytecount_to_charcount_fmt(ptr, len, fmt) ((Charcount) (len)) 914 #define bytecount_to_charcount_fmt(ptr, len, fmt) ((Charcount) (len))
838 #define charcount_to_bytecount(ptr, len) ((Bytecount) (len)) 915 #define charcount_to_bytecount(ptr, len) ((Bytecount) (len))
839 #define charcount_to_bytecount_fmt(ptr, len, fmt) ((Bytecount) (len)) 916 #define charcount_to_bytecount_fmt(ptr, len, fmt) ((Bytecount) (len))
917 #define skip_ascii(ptr, end) end
918 #define skip_ascii_down(ptr, end) end
840 919
841 #endif /* MULE */ 920 #endif /* MULE */
842 921
843 /* Return the length of the first character at PTR. Equivalent to 922 /* Return the length of the first character at PTR. Equivalent to
844 charcount_to_bytecount (ptr, 1). 923 charcount_to_bytecount (ptr, 1).