aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
authorMiles Bader2006-08-03 11:45:23 +0000
committerMiles Bader2006-08-03 11:45:23 +0000
commite2b97060142842813b657144787cef3e6e743967 (patch)
treed7f76853b585d08837d3321504a759919c5fbb42 /src/alloc.c
parenta8fa10a629c86144c90b8b0e58f99581c4e82aba (diff)
parent9b7fa2975f40b82e94dadd13c049ff67ef0ef449 (diff)
downloademacs-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.c167
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
294EMACS_INT pure_bytes_used; 298EMACS_INT pure_bytes_used;
295 299
300/* Index in pure at which next pure Lisp object will be allocated.. */
301
302static EMACS_INT pure_bytes_used_lisp;
303
304/* Number of bytes allocated for non-Lisp objects in pure storage. */
305
306static 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. */
4571int
4572valid_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
4657static POINTER_TYPE * 4682static POINTER_TYPE *
4658pure_alloc (size, type) 4683pure_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
4751static char *
4752find_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. */