Mercurial > emacs
comparison src/alloc.c @ 90573:858cb33ae39d
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
| author | Miles Bader <miles@gnu.org> |
|---|---|
| date | Thu, 03 Aug 2006 11:45:23 +0000 |
| parents | 8a8e69664178 4eba80d54b43 |
| children | cf4b4d3f2600 |
comparison
equal
deleted
inserted
replaced
| 90572:ab9b8d043c39 | 90573:858cb33ae39d |
|---|---|
| 74 #define INCLUDED_FCNTL | 74 #define INCLUDED_FCNTL |
| 75 #include <fcntl.h> | 75 #include <fcntl.h> |
| 76 #endif | 76 #endif |
| 77 #ifndef O_WRONLY | 77 #ifndef O_WRONLY |
| 78 #define O_WRONLY 1 | 78 #define O_WRONLY 1 |
| 79 #endif | |
| 80 | |
| 81 #ifdef WINDOWSNT | |
| 82 #include <fcntl.h> | |
| 79 #endif | 83 #endif |
| 80 | 84 |
| 81 #ifdef DOUG_LEA_MALLOC | 85 #ifdef DOUG_LEA_MALLOC |
| 82 | 86 |
| 83 #include <malloc.h> | 87 #include <malloc.h> |
| 287 (((PNTR_COMPARISON_TYPE) (P) \ | 291 (((PNTR_COMPARISON_TYPE) (P) \ |
| 288 < (PNTR_COMPARISON_TYPE) ((char *) purebeg + pure_size)) \ | 292 < (PNTR_COMPARISON_TYPE) ((char *) purebeg + pure_size)) \ |
| 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; |
| 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; | |
| 295 | 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 |
| 299 char *pending_malloc_warning; | 311 char *pending_malloc_warning; |
| 4553 } | 4565 } |
| 4554 | 4566 |
| 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. |
| 4561 Return -1 if we cannot validate OBJ. | 4595 Return -1 if we cannot validate OBJ. |
| 4562 This function can be quite slow, | 4596 This function can be quite slow, |
| 4565 int | 4599 int |
| 4566 valid_lisp_object_p (obj) | 4600 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 |
| 4576 if (INTEGERP (obj)) | 4608 if (INTEGERP (obj)) |
| 4577 return 1; | 4609 return 1; |
| 4579 p = (void *) XPNTR (obj); | 4611 p = (void *) XPNTR (obj); |
| 4580 if (PURE_POINTER_P (p)) | 4612 if (PURE_POINTER_P (p)) |
| 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 { |
| 4607 case MEM_TYPE_NON_LISP: | 4635 case MEM_TYPE_NON_LISP: |
| 4608 return 0; | 4636 return 0; |
| 4647 Pure Storage Management | 4675 Pure Storage Management |
| 4648 ***********************************************************************/ | 4676 ***********************************************************************/ |
| 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) |
| 4659 size_t size; | 4684 size_t size; |
| 4660 int type; | 4685 int type; |
| 4675 #endif | 4700 #endif |
| 4676 } | 4701 } |
| 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; |
| 4685 | 4723 |
| 4686 /* Don't allocate a large amount here, | 4724 /* Don't allocate a large amount here, |
| 4688 might not be usable. */ | 4726 might not be usable. */ |
| 4689 purebeg = (char *) xmalloc (10000); | 4727 purebeg = (char *) xmalloc (10000); |
| 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 |
| 4696 | 4735 |
| 4697 /* Print a warning if PURESIZE is too small. */ | 4736 /* Print a warning if PURESIZE is too small. */ |
| 4700 check_pure_size () | 4739 check_pure_size () |
| 4701 { | 4740 { |
| 4702 if (pure_bytes_used_before_overflow) | 4741 if (pure_bytes_used_before_overflow) |
| 4703 message ("emacs:0:Pure Lisp storage overflow (approx. %d bytes needed)", | 4742 message ("emacs:0:Pure Lisp storage overflow (approx. %d bytes needed)", |
| 4704 (int) (pure_bytes_used + pure_bytes_used_before_overflow)); | 4743 (int) (pure_bytes_used + pure_bytes_used_before_overflow)); |
| 4744 } | |
| 4745 | |
| 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; | |
| 4705 } | 4811 } |
| 4706 | 4812 |
| 4707 | 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 |
| 4721 { | 4827 { |
| 4722 Lisp_Object string; | 4828 Lisp_Object string; |
| 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; |
| 4734 } | 4844 } |
| 4735 | 4845 |
| 6180 { | 6290 { |
| 6181 /* Used to do Vpurify_flag = Qt here, but Qt isn't set up yet! */ | 6291 /* Used to do Vpurify_flag = Qt here, but Qt isn't set up yet! */ |
| 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. */ |
| 6188 free_ablock = NULL; | 6299 free_ablock = NULL; |
| 6189 | 6300 |
