aboutsummaryrefslogtreecommitdiffstats
path: root/src/region-cache.c
diff options
context:
space:
mode:
authorPaul Eggert2011-08-04 19:15:35 -0700
committerPaul Eggert2011-08-04 19:15:35 -0700
commit0065d05491ce5981ea20896bb26d21dcd31e6769 (patch)
tree13240167319d4a99ab5eacae4a883258eb2d28de /src/region-cache.c
parent18ab493650d648ab8dca651ea2698861f926e895 (diff)
downloademacs-0065d05491ce5981ea20896bb26d21dcd31e6769.tar.gz
emacs-0065d05491ce5981ea20896bb26d21dcd31e6769.zip
Adjust in response to jan.h.d's comments.
See, for example <http://debbugs.gnu.org/cgi/bugreport.cgi?bug=9196#26>.
Diffstat (limited to 'src/region-cache.c')
-rw-r--r--src/region-cache.c89
1 files changed, 39 insertions, 50 deletions
diff --git a/src/region-cache.c b/src/region-cache.c
index e6cec96171d..ed7a07a6709 100644
--- a/src/region-cache.c
+++ b/src/region-cache.c
@@ -63,7 +63,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
63 revalidate_region_cache to see how this helps. */ 63 revalidate_region_cache to see how this helps. */
64 64
65struct boundary { 65struct boundary {
66 EMACS_INT pos; 66 ptrdiff_t pos;
67 int value; 67 int value;
68}; 68};
69 69
@@ -73,16 +73,16 @@ struct region_cache {
73 struct boundary *boundaries; 73 struct boundary *boundaries;
74 74
75 /* boundaries[gap_start ... gap_start + gap_len - 1] is the gap. */ 75 /* boundaries[gap_start ... gap_start + gap_len - 1] is the gap. */
76 EMACS_INT gap_start, gap_len; 76 ptrdiff_t gap_start, gap_len;
77 77
78 /* The number of elements allocated to boundaries, not including the 78 /* The number of elements allocated to boundaries, not including the
79 gap. */ 79 gap. */
80 EMACS_INT cache_len; 80 ptrdiff_t cache_len;
81 81
82 /* The areas that haven't changed since the last time we cleaned out 82 /* The areas that haven't changed since the last time we cleaned out
83 invalid entries from the cache. These overlap when the buffer is 83 invalid entries from the cache. These overlap when the buffer is
84 entirely unchanged. */ 84 entirely unchanged. */
85 EMACS_INT beg_unchanged, end_unchanged; 85 ptrdiff_t beg_unchanged, end_unchanged;
86 86
87 /* The first and last positions in the buffer. Because boundaries 87 /* The first and last positions in the buffer. Because boundaries
88 store their positions relative to the start (BEG) and end (Z) of 88 store their positions relative to the start (BEG) and end (Z) of
@@ -92,7 +92,7 @@ struct region_cache {
92 92
93 Yes, buffer_beg is always 1. It's there for symmetry with 93 Yes, buffer_beg is always 1. It's there for symmetry with
94 buffer_end and the BEG and BUF_BEG macros. */ 94 buffer_end and the BEG and BUF_BEG macros. */
95 EMACS_INT buffer_beg, buffer_end; 95 ptrdiff_t buffer_beg, buffer_end;
96}; 96};
97 97
98/* Return the position of boundary i in cache c. */ 98/* Return the position of boundary i in cache c. */
@@ -173,17 +173,17 @@ free_region_cache (struct region_cache *c)
173 This operation should be logarithmic in the number of cache 173 This operation should be logarithmic in the number of cache
174 entries. It would be nice if it took advantage of locality of 174 entries. It would be nice if it took advantage of locality of
175 reference, too, by searching entries near the last entry found. */ 175 reference, too, by searching entries near the last entry found. */
176static EMACS_INT 176static ptrdiff_t
177find_cache_boundary (struct region_cache *c, EMACS_INT pos) 177find_cache_boundary (struct region_cache *c, ptrdiff_t pos)
178{ 178{
179 EMACS_INT low = 0, high = c->cache_len; 179 ptrdiff_t low = 0, high = c->cache_len;
180 180
181 while (low + 1 < high) 181 while (low + 1 < high)
182 { 182 {
183 /* mid is always a valid index, because low < high and ">> 1" 183 /* mid is always a valid index, because low < high and ">> 1"
184 rounds down. */ 184 rounds down. */
185 EMACS_INT mid = (low + high) >> 1; 185 ptrdiff_t mid = (low >> 1) + (high >> 1) + (low & high & 1);
186 EMACS_INT boundary = BOUNDARY_POS (c, mid); 186 ptrdiff_t boundary = BOUNDARY_POS (c, mid);
187 187
188 if (pos < boundary) 188 if (pos < boundary)
189 high = mid; 189 high = mid;
@@ -208,13 +208,13 @@ find_cache_boundary (struct region_cache *c, EMACS_INT pos)
208/* Move the gap of cache C to index POS, and make sure it has space 208/* Move the gap of cache C to index POS, and make sure it has space
209 for at least MIN_SIZE boundaries. */ 209 for at least MIN_SIZE boundaries. */
210static void 210static void
211move_cache_gap (struct region_cache *c, EMACS_INT pos, EMACS_INT min_size) 211move_cache_gap (struct region_cache *c, ptrdiff_t pos, ptrdiff_t min_size)
212{ 212{
213 /* Copy these out of the cache and into registers. */ 213 /* Copy these out of the cache and into registers. */
214 EMACS_INT gap_start = c->gap_start; 214 ptrdiff_t gap_start = c->gap_start;
215 EMACS_INT gap_len = c->gap_len; 215 ptrdiff_t gap_len = c->gap_len;
216 EMACS_INT buffer_beg = c->buffer_beg; 216 ptrdiff_t buffer_beg = c->buffer_beg;
217 EMACS_INT buffer_end = c->buffer_end; 217 ptrdiff_t buffer_end = c->buffer_end;
218 218
219 if (pos < 0 219 if (pos < 0
220 || pos > c->cache_len) 220 || pos > c->cache_len)
@@ -246,22 +246,11 @@ move_cache_gap (struct region_cache *c, EMACS_INT pos, EMACS_INT min_size)
246 when the portion after the gap is smallest. */ 246 when the portion after the gap is smallest. */
247 if (gap_len < min_size) 247 if (gap_len < min_size)
248 { 248 {
249 EMACS_INT i; 249 ptrdiff_t i;
250 ptrdiff_t cache_len_max =
251 min (PTRDIFF_MAX, SIZE_MAX) / sizeof *c->boundaries;
252 ptrdiff_t min_size_max = cache_len_max - c->cache_len;
253
254 if (min_size_max < min_size)
255 memory_full (SIZE_MAX);
256
257 /* Unless running out of space, make at least NEW_CACHE_GAP
258 elements, as long as we're expanding anyway. */
259 min_size = max (min_size, min (min_size_max, NEW_CACHE_GAP));
260 250
261 c->boundaries = 251 c->boundaries =
262 (struct boundary *) xrealloc (c->boundaries, 252 xpalloc (c->boundaries, &c->cache_len, min_size, -1,
263 ((min_size + c->cache_len) 253 sizeof *c->boundaries);
264 * sizeof (*c->boundaries)));
265 254
266 /* Some systems don't provide a version of the copy routine that 255 /* Some systems don't provide a version of the copy routine that
267 can be trusted to shift memory upward into an overlapping 256 can be trusted to shift memory upward into an overlapping
@@ -298,7 +287,7 @@ move_cache_gap (struct region_cache *c, EMACS_INT pos, EMACS_INT min_size)
298/* Insert a new boundary in cache C; it will have cache index I, 287/* Insert a new boundary in cache C; it will have cache index I,
299 and have the specified POS and VALUE. */ 288 and have the specified POS and VALUE. */
300static void 289static void
301insert_cache_boundary (struct region_cache *c, EMACS_INT i, EMACS_INT pos, 290insert_cache_boundary (struct region_cache *c, ptrdiff_t i, ptrdiff_t pos,
302 int value) 291 int value)
303{ 292{
304 /* i must be a valid cache index. */ 293 /* i must be a valid cache index. */
@@ -336,9 +325,9 @@ insert_cache_boundary (struct region_cache *c, EMACS_INT i, EMACS_INT pos,
336 325
337static void 326static void
338delete_cache_boundaries (struct region_cache *c, 327delete_cache_boundaries (struct region_cache *c,
339 EMACS_INT start, EMACS_INT end) 328 ptrdiff_t start, ptrdiff_t end)
340{ 329{
341 EMACS_INT len = end - start; 330 ptrdiff_t len = end - start;
342 331
343 /* Gotta be in range. */ 332 /* Gotta be in range. */
344 if (start < 0 333 if (start < 0
@@ -389,7 +378,7 @@ delete_cache_boundaries (struct region_cache *c,
389/* Set the value in cache C for the region START..END to VALUE. */ 378/* Set the value in cache C for the region START..END to VALUE. */
390static void 379static void
391set_cache_region (struct region_cache *c, 380set_cache_region (struct region_cache *c,
392 EMACS_INT start, EMACS_INT end, int value) 381 ptrdiff_t start, ptrdiff_t end, int value)
393{ 382{
394 if (start > end) 383 if (start > end)
395 abort (); 384 abort ();
@@ -412,8 +401,8 @@ set_cache_region (struct region_cache *c,
412 index of the earliest boundary after the last character in 401 index of the earliest boundary after the last character in
413 start..end. (This tortured terminology is intended to answer 402 start..end. (This tortured terminology is intended to answer
414 all the "< or <=?" sort of questions.) */ 403 all the "< or <=?" sort of questions.) */
415 EMACS_INT start_ix = find_cache_boundary (c, start); 404 ptrdiff_t start_ix = find_cache_boundary (c, start);
416 EMACS_INT end_ix = find_cache_boundary (c, end - 1) + 1; 405 ptrdiff_t end_ix = find_cache_boundary (c, end - 1) + 1;
417 406
418 /* We must remember the value established by the last boundary 407 /* We must remember the value established by the last boundary
419 before end; if that boundary's domain stretches beyond end, 408 before end; if that boundary's domain stretches beyond end,
@@ -491,7 +480,7 @@ set_cache_region (struct region_cache *c,
491 args to pass are the same before and after such an operation.) */ 480 args to pass are the same before and after such an operation.) */
492void 481void
493invalidate_region_cache (struct buffer *buf, struct region_cache *c, 482invalidate_region_cache (struct buffer *buf, struct region_cache *c,
494 EMACS_INT head, EMACS_INT tail) 483 ptrdiff_t head, ptrdiff_t tail)
495{ 484{
496 /* Let chead = c->beg_unchanged, and 485 /* Let chead = c->beg_unchanged, and
497 ctail = c->end_unchanged. 486 ctail = c->end_unchanged.
@@ -629,7 +618,7 @@ revalidate_region_cache (struct buffer *buf, struct region_cache *c)
629 corresponds to the modified region of the buffer. */ 618 corresponds to the modified region of the buffer. */
630 else 619 else
631 { 620 {
632 EMACS_INT modified_ix; 621 ptrdiff_t modified_ix;
633 622
634 /* These positions are correct, relative to both the cache basis 623 /* These positions are correct, relative to both the cache basis
635 and the buffer basis. */ 624 and the buffer basis. */
@@ -698,7 +687,7 @@ revalidate_region_cache (struct buffer *buf, struct region_cache *c)
698 no newlines", in the case of the line cache). */ 687 no newlines", in the case of the line cache). */
699void 688void
700know_region_cache (struct buffer *buf, struct region_cache *c, 689know_region_cache (struct buffer *buf, struct region_cache *c,
701 EMACS_INT start, EMACS_INT end) 690 ptrdiff_t start, ptrdiff_t end)
702{ 691{
703 revalidate_region_cache (buf, c); 692 revalidate_region_cache (buf, c);
704 693
@@ -713,14 +702,14 @@ know_region_cache (struct buffer *buf, struct region_cache *c,
713 position after POS where the knownness changes. */ 702 position after POS where the knownness changes. */
714int 703int
715region_cache_forward (struct buffer *buf, struct region_cache *c, 704region_cache_forward (struct buffer *buf, struct region_cache *c,
716 EMACS_INT pos, EMACS_INT *next) 705 ptrdiff_t pos, ptrdiff_t *next)
717{ 706{
718 revalidate_region_cache (buf, c); 707 revalidate_region_cache (buf, c);
719 708
720 { 709 {
721 EMACS_INT i = find_cache_boundary (c, pos); 710 ptrdiff_t i = find_cache_boundary (c, pos);
722 int i_value = BOUNDARY_VALUE (c, i); 711 int i_value = BOUNDARY_VALUE (c, i);
723 EMACS_INT j; 712 ptrdiff_t j;
724 713
725 /* Beyond the end of the buffer is unknown, by definition. */ 714 /* Beyond the end of the buffer is unknown, by definition. */
726 if (pos >= BUF_Z (buf)) 715 if (pos >= BUF_Z (buf))
@@ -749,7 +738,7 @@ region_cache_forward (struct buffer *buf, struct region_cache *c,
749 the purposes of CACHE. If NEXT is non-zero, set *NEXT to the nearest 738 the purposes of CACHE. If NEXT is non-zero, set *NEXT to the nearest
750 position before POS where the knownness changes. */ 739 position before POS where the knownness changes. */
751int region_cache_backward (struct buffer *buf, struct region_cache *c, 740int region_cache_backward (struct buffer *buf, struct region_cache *c,
752 EMACS_INT pos, EMACS_INT *next) 741 ptrdiff_t pos, ptrdiff_t *next)
753{ 742{
754 revalidate_region_cache (buf, c); 743 revalidate_region_cache (buf, c);
755 744
@@ -762,9 +751,9 @@ int region_cache_backward (struct buffer *buf, struct region_cache *c,
762 } 751 }
763 752
764 { 753 {
765 EMACS_INT i = find_cache_boundary (c, pos - 1); 754 ptrdiff_t i = find_cache_boundary (c, pos - 1);
766 int i_value = BOUNDARY_VALUE (c, i); 755 int i_value = BOUNDARY_VALUE (c, i);
767 EMACS_INT j; 756 ptrdiff_t j;
768 757
769 if (next) 758 if (next)
770 { 759 {
@@ -790,18 +779,18 @@ void pp_cache (struct region_cache *) EXTERNALLY_VISIBLE;
790void 779void
791pp_cache (struct region_cache *c) 780pp_cache (struct region_cache *c)
792{ 781{
793 int i; 782 ptrdiff_t i;
794 EMACS_INT beg_u = c->buffer_beg + c->beg_unchanged; 783 ptrdiff_t beg_u = c->buffer_beg + c->beg_unchanged;
795 EMACS_INT end_u = c->buffer_end - c->end_unchanged; 784 ptrdiff_t end_u = c->buffer_end - c->end_unchanged;
796 785
797 fprintf (stderr, 786 fprintf (stderr,
798 "basis: %"pI"d..%"pI"d modified: %"pI"d..%"pI"d\n", 787 "basis: %"pD"d..%"pD"d modified: %"pD"d..%"pD"d\n",
799 c->buffer_beg, c->buffer_end, 788 c->buffer_beg, c->buffer_end,
800 beg_u, end_u); 789 beg_u, end_u);
801 790
802 for (i = 0; i < c->cache_len; i++) 791 for (i = 0; i < c->cache_len; i++)
803 { 792 {
804 EMACS_INT pos = BOUNDARY_POS (c, i); 793 ptrdiff_t pos = BOUNDARY_POS (c, i);
805 794
806 putc (((pos < beg_u) ? 'v' 795 putc (((pos < beg_u) ? 'v'
807 : (pos == beg_u) ? '-' 796 : (pos == beg_u) ? '-'
@@ -811,6 +800,6 @@ pp_cache (struct region_cache *c)
811 : (pos == end_u) ? '-' 800 : (pos == end_u) ? '-'
812 : ' '), 801 : ' '),
813 stderr); 802 stderr);
814 fprintf (stderr, "%"pI"d : %d\n", pos, BOUNDARY_VALUE (c, i)); 803 fprintf (stderr, "%"pD"d : %d\n", pos, BOUNDARY_VALUE (c, i));
815 } 804 }
816} 805}