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