diff options
author | Eli Zaretskii <eliz@gnu.org> | 2011-08-05 13:48:37 +0300 |
---|---|---|
committer | Eli Zaretskii <eliz@gnu.org> | 2011-08-05 13:48:37 +0300 |
commit | 35928349678bc6ed8f621fe7d4da6a9a3fb3579d (patch) | |
tree | 57238a3de3ab2aed53b463a06b866ca2811d878f /src/bidi.c | |
parent | 7daee9109e1d69d62528f6b460d101e1ea44f4e1 (diff) | |
download | emacs-35928349678bc6ed8f621fe7d4da6a9a3fb3579d.tar.gz |
Fix bug #9221 with resource allocation under word-wrap.
Add diagnostic facility for monitoring memory allocated for cache shelving.
src/xdisp.c (display_line): Release buffer allocated for shelved bidi
cache. (Bug#9221)
src/bidi.c (bidi_shelve_cache, bidi_unshelve_cache): Track total
amount allocated this far in `bidi_cache_total_alloc'.
(bidi_unshelve_cache): Accept an additional argument JUST_FREE; if
non-zero, only free the data buffer without restoring the cache
contents. All callers changed.
src/dispextern.h (bidi_unshelve_cache): Update prototype.
src/xdisp.c (SAVE_IT, pos_visible_p, move_it_in_display_line_to)
(move_it_in_display_line, move_it_to)
(move_it_vertically_backward, move_it_by_lines): Replace the call
to xfree to an equivalent call to bidi_unshelve_cache.
(move_it_in_display_line_to): Fix logic of returning
MOVE_POS_MATCH_OR_ZV in the bidi case.
Diffstat (limited to 'src/bidi.c')
-rw-r--r-- | src/bidi.c | 76 |
1 files changed, 51 insertions, 25 deletions
diff --git a/src/bidi.c b/src/bidi.c index 77043d9236f..a2ba60a7baf 100644 --- a/src/bidi.c +++ b/src/bidi.c @@ -609,12 +609,15 @@ bidi_pop_it (struct bidi_it *bidi_it) bidi_cache_last_idx = -1; } +ptrdiff_t bidi_cache_total_alloc; + /* Stash away a copy of the cache and its control variables. */ void * bidi_shelve_cache (void) { unsigned char *databuf; + /* Empty cache. */ if (bidi_cache_idx == 0) return NULL; @@ -623,6 +626,12 @@ bidi_shelve_cache (void) + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp) + sizeof (bidi_cache_start) + sizeof (bidi_cache_last_idx)); + bidi_cache_total_alloc += + sizeof (bidi_cache_idx) + bidi_cache_idx * sizeof (struct bidi_it) + + sizeof (bidi_cache_start_stack) + + sizeof (bidi_cache_sp) + sizeof (bidi_cache_start) + + sizeof (bidi_cache_last_idx); + memcpy (databuf, &bidi_cache_idx, sizeof (bidi_cache_idx)); memcpy (databuf + sizeof (bidi_cache_idx), bidi_cache, bidi_cache_idx * sizeof (struct bidi_it)); @@ -648,7 +657,7 @@ bidi_shelve_cache (void) /* Restore the cache state from a copy stashed away by bidi_shelve_cache. */ void -bidi_unshelve_cache (void *databuf) +bidi_unshelve_cache (void *databuf, int just_free) { unsigned char *p = databuf; @@ -661,30 +670,47 @@ bidi_unshelve_cache (void *databuf) } else { - memcpy (&bidi_cache_idx, p, sizeof (bidi_cache_idx)); - bidi_cache_ensure_space (bidi_cache_idx); - memcpy (bidi_cache, p + sizeof (bidi_cache_idx), - bidi_cache_idx * sizeof (struct bidi_it)); - memcpy (bidi_cache_start_stack, - p + sizeof (bidi_cache_idx) - + bidi_cache_idx * sizeof (struct bidi_it), - sizeof (bidi_cache_start_stack)); - memcpy (&bidi_cache_sp, - p + sizeof (bidi_cache_idx) - + bidi_cache_idx * sizeof (struct bidi_it) - + sizeof (bidi_cache_start_stack), - sizeof (bidi_cache_sp)); - memcpy (&bidi_cache_start, - p + sizeof (bidi_cache_idx) - + bidi_cache_idx * sizeof (struct bidi_it) - + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp), - sizeof (bidi_cache_start)); - memcpy (&bidi_cache_last_idx, - p + sizeof (bidi_cache_idx) - + bidi_cache_idx * sizeof (struct bidi_it) - + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp) - + sizeof (bidi_cache_start), - sizeof (bidi_cache_last_idx)); + if (just_free) + { + ptrdiff_t idx; + + memcpy (&idx, p, sizeof (bidi_cache_idx)); + bidi_cache_total_alloc -= + sizeof (bidi_cache_idx) + idx * sizeof (struct bidi_it) + + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp) + + sizeof (bidi_cache_start) + sizeof (bidi_cache_last_idx); + } + else + { + memcpy (&bidi_cache_idx, p, sizeof (bidi_cache_idx)); + bidi_cache_ensure_space (bidi_cache_idx); + memcpy (bidi_cache, p + sizeof (bidi_cache_idx), + bidi_cache_idx * sizeof (struct bidi_it)); + memcpy (bidi_cache_start_stack, + p + sizeof (bidi_cache_idx) + + bidi_cache_idx * sizeof (struct bidi_it), + sizeof (bidi_cache_start_stack)); + memcpy (&bidi_cache_sp, + p + sizeof (bidi_cache_idx) + + bidi_cache_idx * sizeof (struct bidi_it) + + sizeof (bidi_cache_start_stack), + sizeof (bidi_cache_sp)); + memcpy (&bidi_cache_start, + p + sizeof (bidi_cache_idx) + + bidi_cache_idx * sizeof (struct bidi_it) + + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp), + sizeof (bidi_cache_start)); + memcpy (&bidi_cache_last_idx, + p + sizeof (bidi_cache_idx) + + bidi_cache_idx * sizeof (struct bidi_it) + + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp) + + sizeof (bidi_cache_start), + sizeof (bidi_cache_last_idx)); + bidi_cache_total_alloc -= + sizeof (bidi_cache_idx) + bidi_cache_idx * sizeof (struct bidi_it) + + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp) + + sizeof (bidi_cache_start) + sizeof (bidi_cache_last_idx); + } xfree (p); } |