diff options
| author | Miles Bader | 2006-08-03 11:45:23 +0000 |
|---|---|---|
| committer | Miles Bader | 2006-08-03 11:45:23 +0000 |
| commit | e2b97060142842813b657144787cef3e6e743967 (patch) | |
| tree | d7f76853b585d08837d3321504a759919c5fbb42 /src/alloc.c | |
| parent | a8fa10a629c86144c90b8b0e58f99581c4e82aba (diff) | |
| parent | 9b7fa2975f40b82e94dadd13c049ff67ef0ef449 (diff) | |
| download | emacs-e2b97060142842813b657144787cef3e6e743967.tar.gz emacs-e2b97060142842813b657144787cef3e6e743967.zip | |
Merge from emacs--devo--0
Patches applied:
* emacs--devo--0 (patch 357-381)
- Merge from gnus--rel--5.10
- Update from CVS
- Merge from erc--emacs--21
* gnus--rel--5.10 (patch 116-122)
- Update from CVS
- Merge from emacs--devo--0
Revision: emacs@sv.gnu.org/emacs--unicode--0--patch-98
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 167 |
1 files changed, 139 insertions, 28 deletions
diff --git a/src/alloc.c b/src/alloc.c index 2cf3ff40e3b..9f93e62d2ed 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -78,6 +78,10 @@ extern POINTER_TYPE *sbrk (); | |||
| 78 | #define O_WRONLY 1 | 78 | #define O_WRONLY 1 |
| 79 | #endif | 79 | #endif |
| 80 | 80 | ||
| 81 | #ifdef WINDOWSNT | ||
| 82 | #include <fcntl.h> | ||
| 83 | #endif | ||
| 84 | |||
| 81 | #ifdef DOUG_LEA_MALLOC | 85 | #ifdef DOUG_LEA_MALLOC |
| 82 | 86 | ||
| 83 | #include <malloc.h> | 87 | #include <malloc.h> |
| @@ -289,10 +293,18 @@ static size_t pure_bytes_used_before_overflow; | |||
| 289 | && ((PNTR_COMPARISON_TYPE) (P) \ | 293 | && ((PNTR_COMPARISON_TYPE) (P) \ |
| 290 | >= (PNTR_COMPARISON_TYPE) purebeg)) | 294 | >= (PNTR_COMPARISON_TYPE) purebeg)) |
| 291 | 295 | ||
| 292 | /* Index in pure at which next pure object will be allocated.. */ | 296 | /* Total number of bytes allocated in pure storage. */ |
| 293 | 297 | ||
| 294 | EMACS_INT pure_bytes_used; | 298 | EMACS_INT pure_bytes_used; |
| 295 | 299 | ||
| 300 | /* Index in pure at which next pure Lisp object will be allocated.. */ | ||
| 301 | |||
| 302 | static EMACS_INT pure_bytes_used_lisp; | ||
| 303 | |||
| 304 | /* Number of bytes allocated for non-Lisp objects in pure storage. */ | ||
| 305 | |||
| 306 | static EMACS_INT pure_bytes_used_non_lisp; | ||
| 307 | |||
| 296 | /* If nonzero, this is a warning delivered by malloc and not yet | 308 | /* If nonzero, this is a warning delivered by malloc and not yet |
| 297 | displayed. */ | 309 | displayed. */ |
| 298 | 310 | ||
| @@ -4555,6 +4567,28 @@ mark_stack () | |||
| 4555 | #endif /* GC_MARK_STACK != 0 */ | 4567 | #endif /* GC_MARK_STACK != 0 */ |
| 4556 | 4568 | ||
| 4557 | 4569 | ||
| 4570 | /* Determine whether it is safe to access memory at address P. */ | ||
| 4571 | int | ||
| 4572 | valid_pointer_p (p) | ||
| 4573 | void *p; | ||
| 4574 | { | ||
| 4575 | int fd; | ||
| 4576 | |||
| 4577 | /* Obviously, we cannot just access it (we would SEGV trying), so we | ||
| 4578 | trick the o/s to tell us whether p is a valid pointer. | ||
| 4579 | Unfortunately, we cannot use NULL_DEVICE here, as emacs_write may | ||
| 4580 | not validate p in that case. */ | ||
| 4581 | |||
| 4582 | if ((fd = emacs_open ("__Valid__Lisp__Object__", O_CREAT | O_WRONLY | O_TRUNC, 0666)) >= 0) | ||
| 4583 | { | ||
| 4584 | int valid = (emacs_write (fd, (char *)p, 16) == 16); | ||
| 4585 | emacs_close (fd); | ||
| 4586 | unlink ("__Valid__Lisp__Object__"); | ||
| 4587 | return valid; | ||
| 4588 | } | ||
| 4589 | |||
| 4590 | return -1; | ||
| 4591 | } | ||
| 4558 | 4592 | ||
| 4559 | /* Return 1 if OBJ is a valid lisp object. | 4593 | /* Return 1 if OBJ is a valid lisp object. |
| 4560 | Return 0 if OBJ is NOT a valid lisp object. | 4594 | Return 0 if OBJ is NOT a valid lisp object. |
| @@ -4567,9 +4601,7 @@ valid_lisp_object_p (obj) | |||
| 4567 | Lisp_Object obj; | 4601 | Lisp_Object obj; |
| 4568 | { | 4602 | { |
| 4569 | void *p; | 4603 | void *p; |
| 4570 | #if !GC_MARK_STACK | 4604 | #if GC_MARK_STACK |
| 4571 | int fd; | ||
| 4572 | #else | ||
| 4573 | struct mem_node *m; | 4605 | struct mem_node *m; |
| 4574 | #endif | 4606 | #endif |
| 4575 | 4607 | ||
| @@ -4581,26 +4613,22 @@ valid_lisp_object_p (obj) | |||
| 4581 | return 1; | 4613 | return 1; |
| 4582 | 4614 | ||
| 4583 | #if !GC_MARK_STACK | 4615 | #if !GC_MARK_STACK |
| 4584 | /* We need to determine whether it is safe to access memory at | 4616 | return valid_pointer_p (p); |
| 4585 | address P. Obviously, we cannot just access it (we would SEGV | ||
| 4586 | trying), so we trick the o/s to tell us whether p is a valid | ||
| 4587 | pointer. Unfortunately, we cannot use NULL_DEVICE here, as | ||
| 4588 | emacs_write may not validate p in that case. */ | ||
| 4589 | if ((fd = emacs_open ("__Valid__Lisp__Object__", O_CREAT | O_WRONLY | O_TRUNC, 0666)) >= 0) | ||
| 4590 | { | ||
| 4591 | int valid = (emacs_write (fd, (char *)p, 16) == 16); | ||
| 4592 | emacs_close (fd); | ||
| 4593 | unlink ("__Valid__Lisp__Object__"); | ||
| 4594 | return valid; | ||
| 4595 | } | ||
| 4596 | |||
| 4597 | return -1; | ||
| 4598 | #else | 4617 | #else |
| 4599 | 4618 | ||
| 4600 | m = mem_find (p); | 4619 | m = mem_find (p); |
| 4601 | 4620 | ||
| 4602 | if (m == MEM_NIL) | 4621 | if (m == MEM_NIL) |
| 4603 | return 0; | 4622 | { |
| 4623 | int valid = valid_pointer_p (p); | ||
| 4624 | if (valid <= 0) | ||
| 4625 | return valid; | ||
| 4626 | |||
| 4627 | if (SUBRP (obj)) | ||
| 4628 | return 1; | ||
| 4629 | |||
| 4630 | return 0; | ||
| 4631 | } | ||
| 4604 | 4632 | ||
| 4605 | switch (m->type) | 4633 | switch (m->type) |
| 4606 | { | 4634 | { |
| @@ -4649,10 +4677,7 @@ valid_lisp_object_p (obj) | |||
| 4649 | 4677 | ||
| 4650 | /* Allocate room for SIZE bytes from pure Lisp storage and return a | 4678 | /* Allocate room for SIZE bytes from pure Lisp storage and return a |
| 4651 | pointer to it. TYPE is the Lisp type for which the memory is | 4679 | pointer to it. TYPE is the Lisp type for which the memory is |
| 4652 | allocated. TYPE < 0 means it's not used for a Lisp object. | 4680 | allocated. TYPE < 0 means it's not used for a Lisp object. */ |
| 4653 | |||
| 4654 | If store_pure_type_info is set and TYPE is >= 0, the type of | ||
| 4655 | the allocated object is recorded in pure_types. */ | ||
| 4656 | 4681 | ||
| 4657 | static POINTER_TYPE * | 4682 | static POINTER_TYPE * |
| 4658 | pure_alloc (size, type) | 4683 | pure_alloc (size, type) |
| @@ -4677,8 +4702,21 @@ pure_alloc (size, type) | |||
| 4677 | #endif | 4702 | #endif |
| 4678 | 4703 | ||
| 4679 | again: | 4704 | again: |
| 4680 | result = ALIGN (purebeg + pure_bytes_used, alignment); | 4705 | if (type >= 0) |
| 4681 | pure_bytes_used = ((char *)result - (char *)purebeg) + size; | 4706 | { |
| 4707 | /* Allocate space for a Lisp object from the beginning of the free | ||
| 4708 | space with taking account of alignment. */ | ||
| 4709 | result = ALIGN (purebeg + pure_bytes_used_lisp, alignment); | ||
| 4710 | pure_bytes_used_lisp = ((char *)result - (char *)purebeg) + size; | ||
| 4711 | } | ||
| 4712 | else | ||
| 4713 | { | ||
| 4714 | /* Allocate space for a non-Lisp object from the end of the free | ||
| 4715 | space. */ | ||
| 4716 | pure_bytes_used_non_lisp += size; | ||
| 4717 | result = purebeg + pure_size - pure_bytes_used_non_lisp; | ||
| 4718 | } | ||
| 4719 | pure_bytes_used = pure_bytes_used_lisp + pure_bytes_used_non_lisp; | ||
| 4682 | 4720 | ||
| 4683 | if (pure_bytes_used <= pure_size) | 4721 | if (pure_bytes_used <= pure_size) |
| 4684 | return result; | 4722 | return result; |
| @@ -4690,6 +4728,7 @@ pure_alloc (size, type) | |||
| 4690 | pure_size = 10000; | 4728 | pure_size = 10000; |
| 4691 | pure_bytes_used_before_overflow += pure_bytes_used - size; | 4729 | pure_bytes_used_before_overflow += pure_bytes_used - size; |
| 4692 | pure_bytes_used = 0; | 4730 | pure_bytes_used = 0; |
| 4731 | pure_bytes_used_lisp = pure_bytes_used_non_lisp = 0; | ||
| 4693 | goto again; | 4732 | goto again; |
| 4694 | } | 4733 | } |
| 4695 | 4734 | ||
| @@ -4705,6 +4744,73 @@ check_pure_size () | |||
| 4705 | } | 4744 | } |
| 4706 | 4745 | ||
| 4707 | 4746 | ||
| 4747 | /* Find the byte sequence {DATA[0], ..., DATA[NBYTES-1], '\0'} from | ||
| 4748 | the non-Lisp data pool of the pure storage, and return its start | ||
| 4749 | address. Return NULL if not found. */ | ||
| 4750 | |||
| 4751 | static char * | ||
| 4752 | find_string_data_in_pure (data, nbytes) | ||
| 4753 | char *data; | ||
| 4754 | int nbytes; | ||
| 4755 | { | ||
| 4756 | int i, skip, bm_skip[256], last_char_skip, infinity, start, start_max; | ||
| 4757 | unsigned char *p; | ||
| 4758 | char *non_lisp_beg; | ||
| 4759 | |||
| 4760 | if (pure_bytes_used_non_lisp < nbytes + 1) | ||
| 4761 | return NULL; | ||
| 4762 | |||
| 4763 | /* Set up the Boyer-Moore table. */ | ||
| 4764 | skip = nbytes + 1; | ||
| 4765 | for (i = 0; i < 256; i++) | ||
| 4766 | bm_skip[i] = skip; | ||
| 4767 | |||
| 4768 | p = (unsigned char *) data; | ||
| 4769 | while (--skip > 0) | ||
| 4770 | bm_skip[*p++] = skip; | ||
| 4771 | |||
| 4772 | last_char_skip = bm_skip['\0']; | ||
| 4773 | |||
| 4774 | non_lisp_beg = purebeg + pure_size - pure_bytes_used_non_lisp; | ||
| 4775 | start_max = pure_bytes_used_non_lisp - (nbytes + 1); | ||
| 4776 | |||
| 4777 | /* See the comments in the function `boyer_moore' (search.c) for the | ||
| 4778 | use of `infinity'. */ | ||
| 4779 | infinity = pure_bytes_used_non_lisp + 1; | ||
| 4780 | bm_skip['\0'] = infinity; | ||
| 4781 | |||
| 4782 | p = (unsigned char *) non_lisp_beg + nbytes; | ||
| 4783 | start = 0; | ||
| 4784 | do | ||
| 4785 | { | ||
| 4786 | /* Check the last character (== '\0'). */ | ||
| 4787 | do | ||
| 4788 | { | ||
| 4789 | start += bm_skip[*(p + start)]; | ||
| 4790 | } | ||
| 4791 | while (start <= start_max); | ||
| 4792 | |||
| 4793 | if (start < infinity) | ||
| 4794 | /* Couldn't find the last character. */ | ||
| 4795 | return NULL; | ||
| 4796 | |||
| 4797 | /* No less than `infinity' means we could find the last | ||
| 4798 | character at `p[start - infinity]'. */ | ||
| 4799 | start -= infinity; | ||
| 4800 | |||
| 4801 | /* Check the remaining characters. */ | ||
| 4802 | if (memcmp (data, non_lisp_beg + start, nbytes) == 0) | ||
| 4803 | /* Found. */ | ||
| 4804 | return non_lisp_beg + start; | ||
| 4805 | |||
| 4806 | start += last_char_skip; | ||
| 4807 | } | ||
| 4808 | while (start <= start_max); | ||
| 4809 | |||
| 4810 | return NULL; | ||
| 4811 | } | ||
| 4812 | |||
| 4813 | |||
| 4708 | /* Return a string allocated in pure space. DATA is a buffer holding | 4814 | /* Return a string allocated in pure space. DATA is a buffer holding |
| 4709 | NCHARS characters, and NBYTES bytes of string data. MULTIBYTE | 4815 | NCHARS characters, and NBYTES bytes of string data. MULTIBYTE |
| 4710 | non-zero means make the result string multibyte. | 4816 | non-zero means make the result string multibyte. |
| @@ -4723,11 +4829,15 @@ make_pure_string (data, nchars, nbytes, multibyte) | |||
| 4723 | struct Lisp_String *s; | 4829 | struct Lisp_String *s; |
| 4724 | 4830 | ||
| 4725 | s = (struct Lisp_String *) pure_alloc (sizeof *s, Lisp_String); | 4831 | s = (struct Lisp_String *) pure_alloc (sizeof *s, Lisp_String); |
| 4726 | s->data = (unsigned char *) pure_alloc (nbytes + 1, -1); | 4832 | s->data = find_string_data_in_pure (data, nbytes); |
| 4833 | if (s->data == NULL) | ||
| 4834 | { | ||
| 4835 | s->data = (unsigned char *) pure_alloc (nbytes + 1, -1); | ||
| 4836 | bcopy (data, s->data, nbytes); | ||
| 4837 | s->data[nbytes] = '\0'; | ||
| 4838 | } | ||
| 4727 | s->size = nchars; | 4839 | s->size = nchars; |
| 4728 | s->size_byte = multibyte ? nbytes : -1; | 4840 | s->size_byte = multibyte ? nbytes : -1; |
| 4729 | bcopy (data, s->data, nbytes); | ||
| 4730 | s->data[nbytes] = '\0'; | ||
| 4731 | s->intervals = NULL_INTERVAL; | 4841 | s->intervals = NULL_INTERVAL; |
| 4732 | XSETSTRING (string, s); | 4842 | XSETSTRING (string, s); |
| 4733 | return string; | 4843 | return string; |
| @@ -6182,6 +6292,7 @@ init_alloc_once () | |||
| 6182 | purebeg = PUREBEG; | 6292 | purebeg = PUREBEG; |
| 6183 | pure_size = PURESIZE; | 6293 | pure_size = PURESIZE; |
| 6184 | pure_bytes_used = 0; | 6294 | pure_bytes_used = 0; |
| 6295 | pure_bytes_used_lisp = pure_bytes_used_non_lisp = 0; | ||
| 6185 | pure_bytes_used_before_overflow = 0; | 6296 | pure_bytes_used_before_overflow = 0; |
| 6186 | 6297 | ||
| 6187 | /* Initialize the list of free aligned blocks. */ | 6298 | /* Initialize the list of free aligned blocks. */ |