comparison src/alloc.c @ 72114:fe7f8d2385f8

(find_string_data_in_pure): New function. (make_pure_string): Use it to reuse existing string data if possible.
author YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
date Tue, 25 Jul 2006 10:10:19 +0000
parents 107f9a044a0a
children b4ec5a95c687 02e39decdc84
comparison
equal deleted inserted replaced
72113:3d39ae4ce1b6 72114:fe7f8d2385f8
4765 message ("emacs:0:Pure Lisp storage overflow (approx. %d bytes needed)", 4765 message ("emacs:0:Pure Lisp storage overflow (approx. %d bytes needed)",
4766 (int) (pure_bytes_used + pure_bytes_used_before_overflow)); 4766 (int) (pure_bytes_used + pure_bytes_used_before_overflow));
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
4774 static char *
4775 find_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.
4773 4840
4774 Must get an error if pure storage is full, since if it cannot hold 4841 Must get an error if pure storage is full, since if it cannot hold
4783 { 4850 {
4784 Lisp_Object string; 4851 Lisp_Object string;
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;
4796 } 4867 }
4797 4868