diff options
author | YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> | 2006-07-25 10:10:19 +0000 |
---|---|---|
committer | YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> | 2006-07-25 10:10:19 +0000 |
commit | 79fd0489dd7b2015d74b70755720298bef63cf74 (patch) | |
tree | 492e8c0c75a07028ac47559ccd1bdc4e62bc4a1c /src/alloc.c | |
parent | 303b246dbed0f1bc281f0133d98408a45b2e056b (diff) | |
download | emacs-79fd0489dd7b2015d74b70755720298bef63cf74.tar.gz |
(find_string_data_in_pure): New function.
(make_pure_string): Use it to reuse existing string data if possible.
Diffstat (limited to 'src/alloc.c')
-rw-r--r-- | src/alloc.c | 77 |
1 files changed, 74 insertions, 3 deletions
diff --git a/src/alloc.c b/src/alloc.c index 55dc9f4e6de..b058b29c697 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -4767,6 +4767,73 @@ check_pure_size () } +/* Find the byte sequence {DATA[0], ..., DATA[NBYTES-1], '\0'} from + the non-Lisp data pool of the pure storage, and return its start + address. Return NULL if not found. */ + +static char * +find_string_data_in_pure (data, nbytes) + char *data; + int nbytes; +{ + int i, skip, bm_skip[256], last_char_skip, infinity, start, start_max; + unsigned char *p; + char *non_lisp_beg; + + if (pure_bytes_used_non_lisp < nbytes + 1) + return NULL; + + /* Set up the Boyer-Moore table. */ + skip = nbytes + 1; + for (i = 0; i < 256; i++) + bm_skip[i] = skip; + + p = (unsigned char *) data; + while (--skip > 0) + bm_skip[*p++] = skip; + + last_char_skip = bm_skip['\0']; + + non_lisp_beg = purebeg + pure_size - pure_bytes_used_non_lisp; + start_max = pure_bytes_used_non_lisp - (nbytes + 1); + + /* See the comments in the function `boyer_moore' (search.c) for the + use of `infinity'. */ + infinity = pure_bytes_used_non_lisp + 1; + bm_skip['\0'] = infinity; + + p = (unsigned char *) non_lisp_beg + nbytes; + start = 0; + do + { + /* Check the last character (== '\0'). */ + do + { + start += bm_skip[*(p + start)]; + } + while (start <= start_max); + + if (start < infinity) + /* Couldn't find the last character. */ + return NULL; + + /* No less than `infinity' means we could find the last + character at `p[start - infinity]'. */ + start -= infinity; + + /* Check the remaining characters. */ + if (memcmp (data, non_lisp_beg + start, nbytes) == 0) + /* Found. */ + return non_lisp_beg + start; + + start += last_char_skip; + } + while (start <= start_max); + + return NULL; +} + + /* Return a string allocated in pure space. DATA is a buffer holding NCHARS characters, and NBYTES bytes of string data. MULTIBYTE non-zero means make the result string multibyte. @@ -4785,11 +4852,15 @@ make_pure_string (data, nchars, nbytes, multibyte) struct Lisp_String *s; s = (struct Lisp_String *) pure_alloc (sizeof *s, Lisp_String); - s->data = (unsigned char *) pure_alloc (nbytes + 1, -1); + s->data = find_string_data_in_pure (data, nbytes); + if (s->data == NULL) + { + s->data = (unsigned char *) pure_alloc (nbytes + 1, -1); + bcopy (data, s->data, nbytes); + s->data[nbytes] = '\0'; + } s->size = nchars; s->size_byte = multibyte ? nbytes : -1; - bcopy (data, s->data, nbytes); - s->data[nbytes] = '\0'; s->intervals = NULL_INTERVAL; XSETSTRING (string, s); return string; |