diff options
| author | YAMAMOTO Mitsuharu | 2006-07-25 10:10:19 +0000 |
|---|---|---|
| committer | YAMAMOTO Mitsuharu | 2006-07-25 10:10:19 +0000 |
| commit | 79fd0489dd7b2015d74b70755720298bef63cf74 (patch) | |
| tree | 492e8c0c75a07028ac47559ccd1bdc4e62bc4a1c /src | |
| parent | 303b246dbed0f1bc281f0133d98408a45b2e056b (diff) | |
| download | emacs-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.
Diffstat (limited to 'src')
| -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 () | |||
| 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. |
| @@ -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; |