summaryrefslogtreecommitdiff
path: root/src/bidi.c
diff options
context:
space:
mode:
authorEli Zaretskii <eliz@gnu.org>2010-05-14 18:19:07 +0300
committerEli Zaretskii <eliz@gnu.org>2010-05-14 18:19:07 +0300
commit2fe72643a04d063444b0eba90d77e15fcf6d751f (patch)
tree70e1ce6c65c99c314f9647e1eea50548cb80445c /src/bidi.c
parent4b292a226c730b205b65f774164b21e094c31b3d (diff)
downloademacs-2fe72643a04d063444b0eba90d77e15fcf6d751f.tar.gz
Make the cache of bidi iterator states dynamically allocated.
bidi.c (bidi_cache_shrink): New function. (bidi_init_it): Call it. (bidi_cache_iterator_state): Enlarge the cache if needed.
Diffstat (limited to 'src/bidi.c')
-rw-r--r--src/bidi.c30
1 files changed, 24 insertions, 6 deletions
diff --git a/src/bidi.c b/src/bidi.c
index 4b44699f7b2..c4cb4c599df 100644
--- a/src/bidi.c
+++ b/src/bidi.c
@@ -540,9 +540,11 @@ bidi_copy_it (struct bidi_it *to, struct bidi_it *from)
/* Caching the bidi iterator states. */
-static struct bidi_it bidi_cache[1000]; /* FIXME: make this dynamically allocated! */
-static int bidi_cache_idx;
-static int bidi_cache_last_idx;
+#define BIDI_CACHE_CHUNK 200
+static struct bidi_it *bidi_cache;
+static size_t bidi_cache_size = 0;
+static int bidi_cache_idx; /* next unused cache slot */
+static int bidi_cache_last_idx; /* slot of last cache hit */
static INLINE void
bidi_cache_reset (void)
@@ -552,6 +554,17 @@ bidi_cache_reset (void)
}
static INLINE void
+bidi_cache_shrink (void)
+{
+ if (bidi_cache_size > BIDI_CACHE_CHUNK)
+ {
+ bidi_cache_size = BIDI_CACHE_CHUNK * sizeof (struct bidi_it);
+ bidi_cache = (struct bidi_it *) xrealloc (bidi_cache, bidi_cache_size);
+ }
+ bidi_cache_reset ();
+}
+
+static INLINE void
bidi_cache_fetch_state (int idx, struct bidi_it *bidi_it)
{
int current_scan_dir = bidi_it->scan_dir;
@@ -672,9 +685,13 @@ bidi_cache_iterator_state (struct bidi_it *bidi_it, int resolved)
if (idx < 0)
{
idx = bidi_cache_idx;
- /* Don't overrun the cache limit. */
- if (idx > sizeof (bidi_cache) / sizeof (bidi_cache[0]) - 1)
- abort ();
+ /* Enlarge the cache as needed. */
+ if (idx >= bidi_cache_size)
+ {
+ bidi_cache_size += BIDI_CACHE_CHUNK * sizeof (struct bidi_it);
+ bidi_cache =
+ (struct bidi_it *) xrealloc (bidi_cache, bidi_cache_size);
+ }
/* Character positions should correspond to cache positions 1:1.
If we are outside the range of cached positions, the cache is
useless and must be reset. */
@@ -990,6 +1007,7 @@ bidi_init_it (EMACS_INT charpos, EMACS_INT bytepos, struct bidi_it *bidi_it)
bidi_it->prev_for_neutral.type_after_w1 =
bidi_it->prev_for_neutral.orig_type = UNKNOWN_BT;
bidi_it->sor = L2R; /* FIXME: should it be user-selectable? */
+ bidi_cache_shrink ();
}
/* Push the current embedding level and override status; reset the