Mercurial > hg > xemacs-beta
diff src/insdel.c @ 412:697ef44129c6 r21-2-14
Import from CVS: tag r21-2-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:20:41 +0200 |
parents | de805c49cfc1 |
children | 11054d720c21 |
line wrap: on
line diff
--- a/src/insdel.c Mon Aug 13 11:19:22 2007 +0200 +++ b/src/insdel.c Mon Aug 13 11:20:41 2007 +0200 @@ -200,6 +200,7 @@ #include <config.h> #include "lisp.h" +#include <limits.h> #include "buffer.h" #include "device.h" @@ -303,64 +304,65 @@ the equivalent length in characters. */ Charcount -bytecount_to_charcount (const Bufbyte *ptr, Bytecount len) +bytecount_to_charcount (CONST Bufbyte *ptr, Bytecount len) { Charcount count = 0; - const Bufbyte *end = ptr + len; - -#if SIZEOF_LONG == 8 -# define STRIDE_TYPE long -# define HIGH_BIT_MASK 0x8080808080808080UL -#elif SIZEOF_LONG_LONG == 8 && !(defined (i386) || defined (__i386__)) -# define STRIDE_TYPE long long -# define HIGH_BIT_MASK 0x8080808080808080ULL -#elif SIZEOF_LONG == 4 -# define STRIDE_TYPE long -# define HIGH_BIT_MASK 0x80808080UL -#else -# error Add support for 128-bit systems here -#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) - + CONST Bufbyte *end = ptr + len; + +#if (LONGBITS == 32 || LONGBITS == 64) + +# if (LONGBITS == 32) +# define LONG_BYTES 4 +# define ALIGN_MASK 0xFFFFFFFCU +# define HIGH_BIT_MASK 0x80808080U +# else +# define LONG_BYTES 8 +# define ALIGN_MASK 0xFFFFFFFFFFFFFFF8UL + /* I had a dream, I was being overrun with early Intel processors ... */ +# define HIGH_BIT_MASK 0x8080808080808080UL +# endif + + /* When we have a large number of bytes to scan, we can be trickier + and significantly faster by scanning them in chunks of the CPU word + size (assuming that they're all ASCII -- we cut out as soon as + we find something non-ASCII). */ + if (len >= 12) + { + /* Determine the section in the middle of the string that's + amenable to this treatment. Everything has to be aligned + on CPU word boundaries. */ + CONST Bufbyte *aligned_ptr = + (CONST Bufbyte *) (((unsigned long) (ptr + LONG_BYTES - 1)) & + ALIGN_MASK); + CONST Bufbyte *aligned_end = + (CONST Bufbyte *) (((unsigned long) end) & ALIGN_MASK); + + /* Handle unaligned stuff at the beginning. */ + while (ptr < aligned_ptr) + { + if (!BYTE_ASCII_P (*ptr)) + goto bail; + count++, ptr++; + } + /* Now do it. */ + while (ptr < aligned_end) + { + + if ((* (unsigned long *) ptr) & HIGH_BIT_MASK) + goto bail; + ptr += LONG_BYTES; + count += LONG_BYTES; + } + } + +#endif /* LONGBITS == 32 || LONGBITS == 64 */ + + bail: while (ptr < end) { - if (BYTE_ASCII_P (*ptr)) - { - /* optimize for long stretches of ASCII */ - if (! ALIGNED (ptr)) - ptr++, count++; - else - { - const unsigned STRIDE_TYPE *ascii_end = - (const unsigned STRIDE_TYPE *) ptr; - /* This loop screams, because we can typically - detect ASCII characters 8 at a time. */ - while ((const Bufbyte *) ascii_end + STRIDE <= end - && !(*ascii_end & HIGH_BIT_MASK)) - ascii_end++; - if ((Bufbyte *) ascii_end == ptr) - ptr++, count++; - else - { - count += (Bufbyte *) ascii_end - ptr; - ptr = (Bufbyte *) ascii_end; - } - } - } - else - { - /* optimize for successive characters from the same charset */ - Bufbyte leading_byte = *ptr; - size_t bytes = REP_BYTES_BY_FIRST_BYTE (leading_byte); - while ((ptr < end) && (*ptr == leading_byte)) - ptr += bytes, count++; - } + count++; + INC_CHARPTR (ptr); } - #ifdef ERROR_CHECK_BUFPOS /* Bomb out if the specified substring ends in the middle of a character. Note that we might have already gotten @@ -376,9 +378,9 @@ the equivalent length in bytes. */ Bytecount -charcount_to_bytecount (const Bufbyte *ptr, Charcount len) +charcount_to_bytecount (CONST Bufbyte *ptr, Charcount len) { - const Bufbyte *newptr = ptr; + CONST Bufbyte *newptr = ptr; while (len > 0) { @@ -1603,7 +1605,7 @@ adjust_markers (struct buffer *buf, Memind from, Memind to, Bytecount amount) { - Lisp_Marker *m; + struct Lisp_Marker *m; for (m = BUF_MARKERS (buf); m; m = marker_next (m)) m->memind = do_marker_adjustment (m->memind, from, to, amount); @@ -1615,7 +1617,7 @@ static void adjust_markers_for_insert (struct buffer *buf, Memind ind, Bytecount amount) { - Lisp_Marker *m; + struct Lisp_Marker *m; for (m = BUF_MARKERS (buf); m; m = marker_next (m)) { @@ -1629,6 +1631,18 @@ /* Routines for dealing with the gap */ /************************************************************************/ +/* XEmacs requires an ANSI C compiler, and it damn well better have a + working memmove() */ +#define GAP_USE_BCOPY +#ifdef BCOPY_UPWARD_SAFE +# undef BCOPY_UPWARD_SAFE +#endif +#ifdef BCOPY_DOWNWARD_SAFE +# undef BCOPY_DOWNWARD_SAFE +#endif +#define BCOPY_UPWARD_SAFE 1 +#define BCOPY_DOWNWARD_SAFE 1 + /* maximum amount of memory moved in a single chunk. Increasing this value improves gap-motion efficiency but decreases QUIT responsiveness time. Was 32000 but today's processors are faster and files are @@ -1669,15 +1683,23 @@ /* Move at most GAP_MOVE_CHUNK chars before checking again for a quit. */ if (i > GAP_MOVE_CHUNK) i = GAP_MOVE_CHUNK; - - if (i >= 128) +#ifdef GAP_USE_BCOPY + if (i >= 128 + /* bcopy is safe if the two areas of memory do not overlap + or on systems where bcopy is always safe for moving upward. */ + && (BCOPY_UPWARD_SAFE + || to - from >= 128)) { + /* If overlap is not safe, avoid it by not moving too many + characters at once. */ + if (!BCOPY_UPWARD_SAFE && i > to - from) + i = to - from; new_s1 -= i; - from -= i; - to -= i; + from -= i, to -= i; memmove (to, from, i); } else +#endif { new_s1 -= i; while (--i >= 0) @@ -1740,15 +1762,23 @@ /* Move at most GAP_MOVE_CHUNK chars before checking again for a quit. */ if (i > GAP_MOVE_CHUNK) i = GAP_MOVE_CHUNK; - - if (i >= 128) +#ifdef GAP_USE_BCOPY + if (i >= 128 + /* bcopy is safe if the two areas of memory do not overlap + or on systems where bcopy is always safe for moving downward. */ + && (BCOPY_DOWNWARD_SAFE + || from - to >= 128)) { + /* If overlap is not safe, avoid it by not moving too many + characters at once. */ + if (!BCOPY_DOWNWARD_SAFE && i > from - to) + i = from - to; new_s1 += i; memmove (to, from, i); - from += i; - to += i; + from += i, to += i; } else +#endif { new_s1 += i; while (--i >= 0) @@ -2027,12 +2057,7 @@ of the specified region, that will also be handled correctly. begin_multiple_change() returns a number (actually a specpdl depth) - that you must pass to end_multiple_change() when you are done. - - FSF Emacs 20 implements a similar feature, accessible from Lisp - through a `combine-after-change-calls' special form, which is - essentially equivalent to this function. We should consider - whether we want to introduce a similar Lisp form. */ + that you must pass to end_multiple_change() when you are done. */ int begin_multiple_change (struct buffer *buf, Bufpos start, Bufpos end) @@ -2080,8 +2105,7 @@ /* We should first reset the variable and then change the buffer, because Fset_buffer() can throw. */ inside_change_hook = 0; - if (XBUFFER (buffer) != current_buffer) - Fset_buffer (buffer); + Fset_buffer (buffer); return Qnil; } @@ -2131,7 +2155,6 @@ if (!inside_change_hook) { Lisp_Object buffer; - int speccount; /* Are we in a multiple-change session? */ if (buf->text->changes->in_multiple_change && @@ -2169,9 +2192,6 @@ } /* Now in any case run the before-change-functions if any. */ - speccount = specpdl_depth (); - record_unwind_protect (change_function_restore, Fcurrent_buffer ()); - inside_change_hook = 1; MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) { @@ -2180,28 +2200,25 @@ /* Obsolete, for compatibility */ || !NILP (symbol_value_in_buffer (Qbefore_change_function, buffer))) { + int speccount = specpdl_depth (); + record_unwind_protect (change_function_restore, Fcurrent_buffer ()); set_buffer_internal (buf); + inside_change_hook = 1; va_run_hook_with_args (Qbefore_change_functions, 2, make_int (start), make_int (end)); /* Obsolete, for compatibility */ va_run_hook_with_args (Qbefore_change_function, 2, make_int (start), make_int (end)); + unbind_to (speccount, Qnil); } } - /* Make sure endpoints remain valid. before-change-functions - might have modified the buffer. */ - if (start < BUF_BEGV (buf)) start = BUF_BEGV (buf); - if (start > BUF_ZV (buf)) start = BUF_ZV (buf); - if (end < BUF_BEGV (buf)) end = BUF_BEGV (buf); - if (end > BUF_ZV (buf)) end = BUF_ZV (buf); - MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) { XSETBUFFER (buffer, mbuf); - report_extent_modification (buffer, start, end, 0); + report_extent_modification (buffer, start, end, + &inside_change_hook, 0); } - unbind_to (speccount, Qnil); /* Only now do we indicate that the before-change-functions have been called, in case some function throws out. */ @@ -2238,7 +2255,6 @@ if (!inside_change_hook) { Lisp_Object buffer; - int speccount; if (buf->text->changes->in_multiple_change && buf->text->changes->mc_begin != 0) @@ -2251,9 +2267,6 @@ return; /* after-change-functions signalled when all changes done */ } - speccount = specpdl_depth (); - record_unwind_protect (change_function_restore, Fcurrent_buffer ()); - inside_change_hook = 1; MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) { XSETBUFFER (buffer, mbuf); @@ -2262,7 +2275,10 @@ /* Obsolete, for compatibility */ || !NILP (symbol_value_in_buffer (Qafter_change_function, buffer))) { + int speccount = specpdl_depth (); + record_unwind_protect (change_function_restore, Fcurrent_buffer ()); set_buffer_internal (buf); + inside_change_hook = 1; /* The actual after-change functions take slightly different arguments than what we were passed. */ va_run_hook_with_args (Qafter_change_functions, 3, @@ -2272,24 +2288,16 @@ va_run_hook_with_args (Qafter_change_function, 3, make_int (start), make_int (new_end), make_int (orig_end - start)); + unbind_to (speccount, Qnil); } } - /* Make sure endpoints remain valid. after-change-functions - might have modified the buffer. */ - if (start < BUF_BEGV (buf)) start = BUF_BEGV (buf); - if (start > BUF_ZV (buf)) start = BUF_ZV (buf); - if (new_end < BUF_BEGV (buf)) new_end = BUF_BEGV (buf); - if (new_end > BUF_ZV (buf)) new_end = BUF_ZV (buf); - if (orig_end < BUF_BEGV (buf)) orig_end = BUF_BEGV (buf); - if (orig_end > BUF_ZV (buf)) orig_end = BUF_ZV (buf); - MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) { XSETBUFFER (buffer, mbuf); - report_extent_modification (buffer, start, new_end, 1); + report_extent_modification (buffer, start, new_end, + &inside_change_hook, 1); } - unbind_to (speccount, Qnil); /* sets inside_change_hook back to 0 */ } } @@ -2369,7 +2377,7 @@ /************************************************************************/ void -fixup_internal_substring (const Bufbyte *nonreloc, Lisp_Object reloc, +fixup_internal_substring (CONST Bufbyte *nonreloc, Lisp_Object reloc, Bytecount offset, Bytecount *len) { assert ((nonreloc && NILP (reloc)) || (!nonreloc && STRINGP (reloc))); @@ -2377,7 +2385,7 @@ if (*len < 0) { if (nonreloc) - *len = strlen ((const char *) nonreloc) - offset; + *len = strlen ((CONST char *) nonreloc) - offset; else *len = XSTRING_LENGTH (reloc) - offset; } @@ -2411,7 +2419,7 @@ Charcount buffer_insert_string_1 (struct buffer *buf, Bufpos pos, - const Bufbyte *nonreloc, Lisp_Object reloc, + CONST Bufbyte *nonreloc, Lisp_Object reloc, Bytecount offset, Bytecount length, int flags) { @@ -2576,7 +2584,7 @@ Charcount buffer_insert_raw_string_1 (struct buffer *buf, Bufpos pos, - const Bufbyte *nonreloc, Bytecount length, + CONST Bufbyte *nonreloc, Bytecount length, int flags) { /* This function can GC */ @@ -2600,12 +2608,12 @@ /* Insert the null-terminated string S (in external format). */ Charcount -buffer_insert_c_string_1 (struct buffer *buf, Bufpos pos, const char *s, +buffer_insert_c_string_1 (struct buffer *buf, Bufpos pos, CONST char *s, int flags) { /* This function can GC */ - const char *translated = GETTEXT (s); - return buffer_insert_string_1 (buf, pos, (const Bufbyte *) translated, Qnil, + CONST char *translated = GETTEXT (s); + return buffer_insert_string_1 (buf, pos, (CONST Bufbyte *) translated, Qnil, 0, strlen (translated), flags); } @@ -3071,23 +3079,16 @@ } void -find_charsets_in_bufbyte_string (unsigned char *charsets, const Bufbyte *str, +find_charsets_in_bufbyte_string (unsigned char *charsets, CONST Bufbyte *str, Bytecount len) { #ifndef MULE /* Telescope this. */ charsets[0] = 1; #else - const Bufbyte *strend = str + len; + CONST Bufbyte *strend = str + len; memset (charsets, 0, NUM_LEADING_BYTES); - /* #### SJT doesn't like this. */ - if (len == 0) - { - charsets[XCHARSET_LEADING_BYTE (Vcharset_ascii) - 128] = 1; - return; - } - while (str < strend) { charsets[CHAR_LEADING_BYTE (charptr_emchar (str)) - 128] = 1; @@ -3097,7 +3098,7 @@ } void -find_charsets_in_emchar_string (unsigned char *charsets, const Emchar *str, +find_charsets_in_emchar_string (unsigned char *charsets, CONST Emchar *str, Charcount len) { #ifndef MULE @@ -3107,14 +3108,6 @@ int i; memset (charsets, 0, NUM_LEADING_BYTES); - - /* #### SJT doesn't like this. */ - if (len == 0) - { - charsets[XCHARSET_LEADING_BYTE (Vcharset_ascii) - 128] = 1; - return; - } - for (i = 0; i < len; i++) { charsets[CHAR_LEADING_BYTE (str[i]) - 128] = 1; @@ -3123,10 +3116,10 @@ } int -bufbyte_string_displayed_columns (const Bufbyte *str, Bytecount len) +bufbyte_string_displayed_columns (CONST Bufbyte *str, Bytecount len) { int cols = 0; - const Bufbyte *end = str + len; + CONST Bufbyte *end = str + len; while (str < end) { @@ -3143,7 +3136,7 @@ } int -emchar_string_displayed_columns (const Emchar *str, Charcount len) +emchar_string_displayed_columns (CONST Emchar *str, Charcount len) { #ifdef MULE int cols = 0; @@ -3161,10 +3154,10 @@ /* NOTE: Does not reset the Dynarr. */ void -convert_bufbyte_string_into_emchar_dynarr (const Bufbyte *str, Bytecount len, +convert_bufbyte_string_into_emchar_dynarr (CONST Bufbyte *str, Bytecount len, Emchar_dynarr *dyn) { - const Bufbyte *strend = str + len; + CONST Bufbyte *strend = str + len; while (str < strend) { @@ -3175,10 +3168,10 @@ } Charcount -convert_bufbyte_string_into_emchar_string (const Bufbyte *str, Bytecount len, +convert_bufbyte_string_into_emchar_string (CONST Bufbyte *str, Bytecount len, Emchar *arr) { - const Bufbyte *strend = str + len; + CONST Bufbyte *strend = str + len; Charcount newlen = 0; while (str < strend) { @@ -3241,7 +3234,7 @@ /************************************************************************/ void -reinit_vars_of_insdel (void) +vars_of_insdel (void) { int i; @@ -3253,12 +3246,6 @@ } void -vars_of_insdel (void) -{ - reinit_vars_of_insdel (); -} - -void init_buffer_text (struct buffer *b) { if (!b->base_buffer)