aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYAMAMOTO Mitsuharu2006-07-25 10:10:19 +0000
committerYAMAMOTO Mitsuharu2006-07-25 10:10:19 +0000
commit79fd0489dd7b2015d74b70755720298bef63cf74 (patch)
tree492e8c0c75a07028ac47559ccd1bdc4e62bc4a1c
parent303b246dbed0f1bc281f0133d98408a45b2e056b (diff)
downloademacs-79fd0489dd7b2015d74b70755720298bef63cf74.tar.gz
emacs-79fd0489dd7b2015d74b70755720298bef63cf74.zip
(find_string_data_in_pure): New function.
(make_pure_string): Use it to reuse existing string data if possible.
-rw-r--r--src/alloc.c77
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 ()
4767} 4767}
4768 4768
4769 4769
4770/* Find the byte sequence {DATA[0], ..., DATA[NBYTES-1], '\0'} from
4771 the non-Lisp data pool of the pure storage, and return its start
4772 address. Return NULL if not found. */
4773
4774static char *
4775find_string_data_in_pure (data, nbytes)
4776 char *data;
4777 int nbytes;
4778{
4779 int i, skip, bm_skip[256], last_char_skip, infinity, start, start_max;
4780 unsigned char *p;
4781 char *non_lisp_beg;
4782
4783 if (pure_bytes_used_non_lisp < nbytes + 1)
4784 return NULL;
4785
4786 /* Set up the Boyer-Moore table. */
4787 skip = nbytes + 1;
4788 for (i = 0; i < 256; i++)
4789 bm_skip[i] = skip;
4790
4791 p = (unsigned char *) data;
4792 while (--skip > 0)
4793 bm_skip[*p++] = skip;
4794
4795 last_char_skip = bm_skip['\0'];
4796
4797 non_lisp_beg = purebeg + pure_size - pure_bytes_used_non_lisp;
4798 start_max = pure_bytes_used_non_lisp - (nbytes + 1);
4799
4800 /* See the comments in the function `boyer_moore' (search.c) for the
4801 use of `infinity'. */
4802 infinity = pure_bytes_used_non_lisp + 1;
4803 bm_skip['\0'] = infinity;
4804
4805 p = (unsigned char *) non_lisp_beg + nbytes;
4806 start = 0;
4807 do
4808 {
4809 /* Check the last character (== '\0'). */
4810 do
4811 {
4812 start += bm_skip[*(p + start)];
4813 }
4814 while (start <= start_max);
4815
4816 if (start < infinity)
4817 /* Couldn't find the last character. */
4818 return NULL;
4819
4820 /* No less than `infinity' means we could find the last
4821 character at `p[start - infinity]'. */
4822 start -= infinity;
4823
4824 /* Check the remaining characters. */
4825 if (memcmp (data, non_lisp_beg + start, nbytes) == 0)
4826 /* Found. */
4827 return non_lisp_beg + start;
4828
4829 start += last_char_skip;
4830 }
4831 while (start <= start_max);
4832
4833 return NULL;
4834}
4835
4836
4770/* Return a string allocated in pure space. DATA is a buffer holding 4837/* Return a string allocated in pure space. DATA is a buffer holding
4771 NCHARS characters, and NBYTES bytes of string data. MULTIBYTE 4838 NCHARS characters, and NBYTES bytes of string data. MULTIBYTE
4772 non-zero means make the result string multibyte. 4839 non-zero means make the result string multibyte.
@@ -4785,11 +4852,15 @@ make_pure_string (data, nchars, nbytes, multibyte)
4785 struct Lisp_String *s; 4852 struct Lisp_String *s;
4786 4853
4787 s = (struct Lisp_String *) pure_alloc (sizeof *s, Lisp_String); 4854 s = (struct Lisp_String *) pure_alloc (sizeof *s, Lisp_String);
4788 s->data = (unsigned char *) pure_alloc (nbytes + 1, -1); 4855 s->data = find_string_data_in_pure (data, nbytes);
4856 if (s->data == NULL)
4857 {
4858 s->data = (unsigned char *) pure_alloc (nbytes + 1, -1);
4859 bcopy (data, s->data, nbytes);
4860 s->data[nbytes] = '\0';
4861 }
4789 s->size = nchars; 4862 s->size = nchars;
4790 s->size_byte = multibyte ? nbytes : -1; 4863 s->size_byte = multibyte ? nbytes : -1;
4791 bcopy (data, s->data, nbytes);
4792 s->data[nbytes] = '\0';
4793 s->intervals = NULL_INTERVAL; 4864 s->intervals = NULL_INTERVAL;
4794 XSETSTRING (string, s); 4865 XSETSTRING (string, s);
4795 return string; 4866 return string;