aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
authorStefan Monnier2003-07-04 20:19:06 +0000
committerStefan Monnier2003-07-04 20:19:06 +0000
commitab6780cd2f7e0da50b92261010279981a0993ee4 (patch)
tree4131fad08ccc1ebcb03b51fdb327a7a17c1f9005 /src/alloc.c
parentd320e9f3063624c097228fbd62d283aefef80fb4 (diff)
downloademacs-ab6780cd2f7e0da50b92261010279981a0993ee4.tar.gz
emacs-ab6780cd2f7e0da50b92261010279981a0993ee4.zip
(ALIGN): Add casts to simplify usage.
(BLOCK_ALIGN, BLOCK_BYTES, ABLOCKS_PADDING, ABLOCKS_SIZE) (ABLOCKS_BYTES, ABLOCK_ABASE, ABLOCKS_BUSY, ABLOCKS_BASE): New macros. (struct ablock, struct ablocks): New types. (free_ablock): New global var. (lisp_align_malloc, lisp_align_free): New functions. (FLOAT_BLOCK_SIZE): Redefine in terms of BLOCK_BYTES. (struct float_block): Reorder and add gcmarkbits. (GETMARKBIT, SETMARKBIT, UNSETMARKBIT, FLOAT_BLOCK, FLOAT_INDEX) (FLOAT_MARKED_P, FLOAT_MARK, FLOAT_UNMARK): New macros. (init_float, make_float): Use lisp_align_malloc. (free_float, live_float_p): Don't use `type' any more. (make_float): Use FLOAT_UNMARK to access to mark bit. (mark_maybe_object, mark_maybe_pointer, survives_gc_p): Use FLOAT_MARKED_P to access the mark bit. (pure_alloc): Simplify use of ALIGN. (mark_object): Use FLOAT_MARK to access the mark bit. (gc_sweep): Use new macros to access the float's mark bit. (init_alloc_once): Init free_ablock.
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c291
1 files changed, 255 insertions, 36 deletions
diff --git a/src/alloc.c b/src/alloc.c
index 8dfeb25edf4..4ec3a1c3863 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -21,6 +21,7 @@ Boston, MA 02111-1307, USA. */
21 21
22#include <config.h> 22#include <config.h>
23#include <stdio.h> 23#include <stdio.h>
24#include <limits.h> /* For CHAR_BIT. */
24 25
25#ifdef ALLOC_DEBUG 26#ifdef ALLOC_DEBUG
26#undef INLINE 27#undef INLINE
@@ -418,8 +419,9 @@ static POINTER_TYPE *pure_alloc P_ ((size_t, int));
418/* Value is SZ rounded up to the next multiple of ALIGNMENT. 419/* Value is SZ rounded up to the next multiple of ALIGNMENT.
419 ALIGNMENT must be a power of 2. */ 420 ALIGNMENT must be a power of 2. */
420 421
421#define ALIGN(SZ, ALIGNMENT) \ 422#define ALIGN(ptr, ALIGNMENT) \
422 (((SZ) + (ALIGNMENT) - 1) & ~((ALIGNMENT) - 1)) 423 ((POINTER_TYPE *) ((((EMACS_UINT)(ptr)) + (ALIGNMENT) - 1) \
424 & ~((ALIGNMENT) - 1)))
423 425
424 426
425 427
@@ -635,6 +637,202 @@ lisp_free (block)
635 UNBLOCK_INPUT; 637 UNBLOCK_INPUT;
636} 638}
637 639
640/* Allocation of aligned blocks of memory to store Lisp data. */
641/* The entry point is lisp_align_malloc which returns blocks of at most */
642/* BLOCK_BYTES and guarantees they are aligned on a BLOCK_ALIGN boundary. */
643
644
645/* BLOCK_ALIGN has to be a power of 2. */
646#define BLOCK_ALIGN (1 << 10)
647#define BLOCK_BYTES \
648 (BLOCK_ALIGN - sizeof (struct aligned_block *) - ABLOCKS_PADDING)
649
650/* Internal data structures and constants. */
651
652/* Padding to leave at the end of a malloc'd block. This is to give
653 malloc a chance to minimize the amount of memory wasted to alignment.
654 It should be tuned to the particular malloc library used.
655 The current setting is based on glibc-2.3.2. */
656#define ABLOCKS_PADDING 0
657#define ABLOCKS_SIZE 16
658
659/* An aligned block of memory. */
660struct ablock
661{
662 union
663 {
664 char payload[BLOCK_BYTES];
665 struct ablock *next_free;
666 } x;
667 /* `abase' is the aligned base of the ablocks. */
668 /* It is overloaded to hold the virtual `busy' field that counts
669 the number of used ablock in the parent ablocks.
670 The first ablock has the `busy' field, the others have the `abase'
671 field. To tell the difference, we assume that pointers will have
672 integer values larger than 2 * ABLOCKS_SIZE. The lowest bit of `busy'
673 is used to tell whether the real base of the parent ablocks is `abase'
674 (if not, the word before the first ablock holds a pointer to the
675 real base). */
676 struct ablocks *abase;
677 /* The padding of all but the last ablock is unused. The padding of
678 the last ablock in an ablocks is not allocated. */
679 char padding[ABLOCKS_PADDING];
680};
681
682/* A bunch of consecutive aligned blocks. */
683struct ablocks
684{
685 struct ablock blocks[ABLOCKS_SIZE];
686};
687
688/* Size of the block requested from malloc or memalign. */
689#define ABLOCKS_BYTES (sizeof (struct ablocks) - ABLOCKS_PADDING)
690
691#define ABLOCK_ABASE(block) \
692 (((unsigned long) (block)->abase) <= (1 + 2 * ABLOCKS_SIZE) \
693 ? (struct ablocks *)(block) \
694 : (block)->abase)
695
696/* Virtual `busy' field. */
697#define ABLOCKS_BUSY(abase) ((abase)->blocks[0].abase)
698
699/* Pointer to the (not necessarily aligned) malloc block. */
700#define ABLOCKS_BASE(abase) \
701 (1 & (int) ABLOCKS_BUSY (abase) ? abase : ((void**)abase)[-1])
702
703/* The list of free ablock. */
704static struct ablock *free_ablock;
705
706/* Allocate an aligned block of nbytes.
707 Alignment is on a multiple of BLOCK_ALIGN and `nbytes' has to be
708 smaller or equal to BLOCK_BYTES. */
709static POINTER_TYPE *
710lisp_align_malloc (nbytes, type)
711 size_t nbytes;
712 enum mem_type type;
713{
714 void *base, *val;
715 struct ablocks *abase;
716
717 eassert (nbytes <= BLOCK_BYTES);
718
719 BLOCK_INPUT;
720
721#ifdef GC_MALLOC_CHECK
722 allocated_mem_type = type;
723#endif
724
725 if (!free_ablock)
726 {
727 int i, aligned;
728
729#ifdef DOUG_LEA_MALLOC
730 /* Prevent mmap'ing the chunk. Lisp data may not be mmap'ed
731 because mapped region contents are not preserved in
732 a dumped Emacs. */
733 mallopt (M_MMAP_MAX, 0);
734#endif
735
736 base = malloc (ABLOCKS_BYTES);
737 abase = ALIGN (base, BLOCK_ALIGN);
738
739 aligned = (base == abase);
740 if (!aligned)
741 ((void**)abase)[-1] = base;
742
743#ifdef DOUG_LEA_MALLOC
744 /* Back to a reasonable maximum of mmap'ed areas. */
745 mallopt (M_MMAP_MAX, MMAP_MAX_AREAS);
746#endif
747
748 /* Initialize the blocks and put them on the free list.
749 Is `base' was not properly aligned, we can't use the last block. */
750 for (i = 0; i < (aligned ? ABLOCKS_SIZE : ABLOCKS_SIZE - 1); i++)
751 {
752 abase->blocks[i].abase = abase;
753 abase->blocks[i].x.next_free = free_ablock;
754 free_ablock = &abase->blocks[i];
755 }
756 ABLOCKS_BUSY (abase) = (struct ablocks *) aligned;
757
758 eassert (ABLOCK_ABASE (&abase->blocks[3]) == abase); /* 3 is arbitrary */
759 eassert (ABLOCK_ABASE (&abase->blocks[0]) == abase);
760 eassert (ABLOCKS_BASE (abase) == base);
761 eassert (aligned == (int)ABLOCKS_BUSY (abase));
762 }
763
764 abase = ABLOCK_ABASE (free_ablock);
765 ABLOCKS_BUSY (abase) = (struct ablocks *) (2 + (int) ABLOCKS_BUSY (abase));
766 val = free_ablock;
767 free_ablock = free_ablock->x.next_free;
768
769 /* If the memory just allocated cannot be addressed thru a Lisp
770 object's pointer, and it needs to be,
771 that's equivalent to running out of memory. */
772 if (val && type != MEM_TYPE_NON_LISP)
773 {
774 Lisp_Object tem;
775 XSETCONS (tem, (char *) val + nbytes - 1);
776 if ((char *) XCONS (tem) != (char *) val + nbytes - 1)
777 {
778 lisp_malloc_loser = val;
779 free (val);
780 val = 0;
781 }
782 }
783
784#if GC_MARK_STACK && !defined GC_MALLOC_CHECK
785 if (val && type != MEM_TYPE_NON_LISP)
786 mem_insert (val, (char *) val + nbytes, type);
787#endif
788
789 UNBLOCK_INPUT;
790 if (!val && nbytes)
791 memory_full ();
792
793 eassert (0 == ((EMACS_UINT)val) % BLOCK_ALIGN);
794 return val;
795}
796
797static void
798lisp_align_free (block)
799 POINTER_TYPE *block;
800{
801 struct ablock *ablock = block;
802 struct ablocks *abase = ABLOCK_ABASE (ablock);
803
804 BLOCK_INPUT;
805#if GC_MARK_STACK && !defined GC_MALLOC_CHECK
806 mem_delete (mem_find (block));
807#endif
808 /* Put on free list. */
809 ablock->x.next_free = free_ablock;
810 free_ablock = ablock;
811 /* Update busy count. */
812 ABLOCKS_BUSY (abase) = (struct ablocks *) (-2 + (int) ABLOCKS_BUSY (abase));
813
814 if (2 > (int) ABLOCKS_BUSY (abase))
815 { /* All the blocks are free. */
816 int i = 0, aligned = (int) ABLOCKS_BUSY (abase);
817 struct ablock **tem = &free_ablock;
818 struct ablock *atop = &abase->blocks[aligned ? ABLOCKS_SIZE : ABLOCKS_SIZE - 1];
819
820 while (*tem)
821 {
822 if (*tem >= (struct ablock *) abase && *tem < atop)
823 {
824 i++;
825 *tem = (*tem)->x.next_free;
826 }
827 else
828 tem = &(*tem)->x.next_free;
829 }
830 eassert ((aligned & 1) == aligned);
831 eassert (i == (aligned ? ABLOCKS_SIZE : ABLOCKS_SIZE - 1));
832 free (ABLOCKS_BASE (abase));
833 }
834 UNBLOCK_INPUT;
835}
638 836
639/* Return a new buffer structure allocated from the heap with 837/* Return a new buffer structure allocated from the heap with
640 a call to lisp_malloc. */ 838 a call to lisp_malloc. */
@@ -1899,21 +2097,48 @@ make_uninit_multibyte_string (nchars, nbytes)
1899/* We store float cells inside of float_blocks, allocating a new 2097/* We store float cells inside of float_blocks, allocating a new
1900 float_block with malloc whenever necessary. Float cells reclaimed 2098 float_block with malloc whenever necessary. Float cells reclaimed
1901 by GC are put on a free list to be reallocated before allocating 2099 by GC are put on a free list to be reallocated before allocating
1902 any new float cells from the latest float_block. 2100 any new float cells from the latest float_block. */
1903
1904 Each float_block is just under 1020 bytes long, since malloc really
1905 allocates in units of powers of two and uses 4 bytes for its own
1906 overhead. */
1907 2101
1908#define FLOAT_BLOCK_SIZE \ 2102#define FLOAT_BLOCK_SIZE \
1909 ((1020 - sizeof (struct float_block *)) / sizeof (struct Lisp_Float)) 2103 (((BLOCK_BYTES - sizeof (struct float_block *)) * CHAR_BIT) \
2104 / (sizeof (struct Lisp_Float) * CHAR_BIT + 1))
2105
2106#define GETMARKBIT(block,n) \
2107 (((block)->gcmarkbits[(n) / (sizeof(int) * CHAR_BIT)] \
2108 >> ((n) % (sizeof(int) * CHAR_BIT))) \
2109 & 1)
2110
2111#define SETMARKBIT(block,n) \
2112 (block)->gcmarkbits[(n) / (sizeof(int) * CHAR_BIT)] \
2113 |= 1 << ((n) % (sizeof(int) * CHAR_BIT))
2114
2115#define UNSETMARKBIT(block,n) \
2116 (block)->gcmarkbits[(n) / (sizeof(int) * CHAR_BIT)] \
2117 &= ~(1 << ((n) % (sizeof(int) * CHAR_BIT)))
2118
2119#define FLOAT_BLOCK(fptr) \
2120 ((struct float_block *)(((EMACS_UINT)(fptr)) & ~(BLOCK_ALIGN - 1)))
2121
2122#define FLOAT_INDEX(fptr) \
2123 ((((EMACS_UINT)(fptr)) & (BLOCK_ALIGN - 1)) / sizeof (struct Lisp_Float))
1910 2124
1911struct float_block 2125struct float_block
1912{ 2126{
1913 struct float_block *next; 2127 /* Place `floats' at the beginning, to ease up FLOAT_INDEX's job. */
1914 struct Lisp_Float floats[FLOAT_BLOCK_SIZE]; 2128 struct Lisp_Float floats[FLOAT_BLOCK_SIZE];
2129 int gcmarkbits[1 + FLOAT_BLOCK_SIZE / (sizeof(int) * CHAR_BIT)];
2130 struct float_block *next;
1915}; 2131};
1916 2132
2133#define FLOAT_MARKED_P(fptr) \
2134 GETMARKBIT (FLOAT_BLOCK (fptr), FLOAT_INDEX ((fptr)))
2135
2136#define FLOAT_MARK(fptr) \
2137 SETMARKBIT (FLOAT_BLOCK (fptr), FLOAT_INDEX ((fptr)))
2138
2139#define FLOAT_UNMARK(fptr) \
2140 UNSETMARKBIT (FLOAT_BLOCK (fptr), FLOAT_INDEX ((fptr)))
2141
1917/* Current float_block. */ 2142/* Current float_block. */
1918 2143
1919struct float_block *float_block; 2144struct float_block *float_block;
@@ -1936,10 +2161,11 @@ struct Lisp_Float *float_free_list;
1936void 2161void
1937init_float () 2162init_float ()
1938{ 2163{
1939 float_block = (struct float_block *) lisp_malloc (sizeof *float_block, 2164 float_block = (struct float_block *) lisp_align_malloc (sizeof *float_block,
1940 MEM_TYPE_FLOAT); 2165 MEM_TYPE_FLOAT);
1941 float_block->next = 0; 2166 float_block->next = 0;
1942 bzero ((char *) float_block->floats, sizeof float_block->floats); 2167 bzero ((char *) float_block->floats, sizeof float_block->floats);
2168 bzero ((char *) float_block->gcmarkbits, sizeof float_block->gcmarkbits);
1943 float_block_index = 0; 2169 float_block_index = 0;
1944 float_free_list = 0; 2170 float_free_list = 0;
1945 n_float_blocks = 1; 2171 n_float_blocks = 1;
@@ -1953,9 +2179,6 @@ free_float (ptr)
1953 struct Lisp_Float *ptr; 2179 struct Lisp_Float *ptr;
1954{ 2180{
1955 *(struct Lisp_Float **)&ptr->data = float_free_list; 2181 *(struct Lisp_Float **)&ptr->data = float_free_list;
1956#if GC_MARK_STACK
1957 ptr->type = Vdead;
1958#endif
1959 float_free_list = ptr; 2182 float_free_list = ptr;
1960} 2183}
1961 2184
@@ -1981,8 +2204,8 @@ make_float (float_value)
1981 { 2204 {
1982 register struct float_block *new; 2205 register struct float_block *new;
1983 2206
1984 new = (struct float_block *) lisp_malloc (sizeof *new, 2207 new = (struct float_block *) lisp_align_malloc (sizeof *new,
1985 MEM_TYPE_FLOAT); 2208 MEM_TYPE_FLOAT);
1986 new->next = float_block; 2209 new->next = float_block;
1987 float_block = new; 2210 float_block = new;
1988 float_block_index = 0; 2211 float_block_index = 0;
@@ -1992,7 +2215,7 @@ make_float (float_value)
1992 } 2215 }
1993 2216
1994 XFLOAT_DATA (val) = float_value; 2217 XFLOAT_DATA (val) = float_value;
1995 XSETFASTINT (XFLOAT (val)->type, 0); /* bug chasing -wsr */ 2218 FLOAT_UNMARK (XFLOAT (val));
1996 consing_since_gc += sizeof (struct Lisp_Float); 2219 consing_since_gc += sizeof (struct Lisp_Float);
1997 floats_consed++; 2220 floats_consed++;
1998 return val; 2221 return val;
@@ -3240,14 +3463,12 @@ live_float_p (m, p)
3240 struct float_block *b = (struct float_block *) m->start; 3463 struct float_block *b = (struct float_block *) m->start;
3241 int offset = (char *) p - (char *) &b->floats[0]; 3464 int offset = (char *) p - (char *) &b->floats[0];
3242 3465
3243 /* P must point to the start of a Lisp_Float, not be 3466 /* P must point to the start of a Lisp_Float and not be
3244 one of the unused cells in the current float block, 3467 one of the unused cells in the current float block. */
3245 and not be on the free-list. */
3246 return (offset >= 0 3468 return (offset >= 0
3247 && offset % sizeof b->floats[0] == 0 3469 && offset % sizeof b->floats[0] == 0
3248 && (b != float_block 3470 && (b != float_block
3249 || offset / sizeof b->floats[0] < float_block_index) 3471 || offset / sizeof b->floats[0] < float_block_index));
3250 && !EQ (((struct Lisp_Float *) p)->type, Vdead));
3251 } 3472 }
3252 else 3473 else
3253 return 0; 3474 return 0;
@@ -3394,8 +3615,7 @@ mark_maybe_object (obj)
3394 break; 3615 break;
3395 3616
3396 case Lisp_Float: 3617 case Lisp_Float:
3397 mark_p = (live_float_p (m, po) 3618 mark_p = (live_float_p (m, po) && !FLOAT_MARKED_P (XFLOAT (obj)));
3398 && !XMARKBIT (XFLOAT (obj)->type));
3399 break; 3619 break;
3400 3620
3401 case Lisp_Vectorlike: 3621 case Lisp_Vectorlike:
@@ -3483,8 +3703,7 @@ mark_maybe_pointer (p)
3483 break; 3703 break;
3484 3704
3485 case MEM_TYPE_FLOAT: 3705 case MEM_TYPE_FLOAT:
3486 if (live_float_p (m, p) 3706 if (live_float_p (m, p) && !FLOAT_MARKED_P (p))
3487 && !XMARKBIT (((struct Lisp_Float *) p)->type))
3488 XSETFLOAT (obj, p); 3707 XSETFLOAT (obj, p);
3489 break; 3708 break;
3490 3709
@@ -3741,7 +3960,7 @@ mark_stack ()
3741 3960
3742 /* This trick flushes the register windows so that all the state of 3961 /* This trick flushes the register windows so that all the state of
3743 the process is contained in the stack. */ 3962 the process is contained in the stack. */
3744 /* Fixme: Code in the Boehm GC sugests flushing (with `flushrs') is 3963 /* Fixme: Code in the Boehm GC suggests flushing (with `flushrs') is
3745 needed on ia64 too. See mach_dep.c, where it also says inline 3964 needed on ia64 too. See mach_dep.c, where it also says inline
3746 assembler doesn't work with relevant proprietary compilers. */ 3965 assembler doesn't work with relevant proprietary compilers. */
3747#ifdef sparc 3966#ifdef sparc
@@ -3823,7 +4042,7 @@ pure_alloc (size, type)
3823 } 4042 }
3824 4043
3825 again: 4044 again:
3826 result = (POINTER_TYPE *) ALIGN ((EMACS_UINT)purebeg + pure_bytes_used, alignment); 4045 result = ALIGN (purebeg + pure_bytes_used, alignment);
3827 pure_bytes_used = ((char *)result - (char *)purebeg) + size; 4046 pure_bytes_used = ((char *)result - (char *)purebeg) + size;
3828 4047
3829 if (pure_bytes_used <= pure_size) 4048 if (pure_bytes_used <= pure_size)
@@ -4825,7 +5044,7 @@ mark_object (argptr)
4825 5044
4826 case Lisp_Float: 5045 case Lisp_Float:
4827 CHECK_ALLOCATED_AND_LIVE (live_float_p); 5046 CHECK_ALLOCATED_AND_LIVE (live_float_p);
4828 XMARK (XFLOAT (obj)->type); 5047 FLOAT_MARK (XFLOAT (obj));
4829 break; 5048 break;
4830 5049
4831 case Lisp_Int: 5050 case Lisp_Int:
@@ -4948,7 +5167,7 @@ survives_gc_p (obj)
4948 break; 5167 break;
4949 5168
4950 case Lisp_Float: 5169 case Lisp_Float:
4951 survives_p = XMARKBIT (XFLOAT (obj)->type); 5170 survives_p = FLOAT_MARKED_P (XFLOAT (obj));
4952 break; 5171 break;
4953 5172
4954 default: 5173 default:
@@ -5039,19 +5258,16 @@ gc_sweep ()
5039 register int i; 5258 register int i;
5040 int this_free = 0; 5259 int this_free = 0;
5041 for (i = 0; i < lim; i++) 5260 for (i = 0; i < lim; i++)
5042 if (!XMARKBIT (fblk->floats[i].type)) 5261 if (!FLOAT_MARKED_P (&fblk->floats[i]))
5043 { 5262 {
5044 this_free++; 5263 this_free++;
5045 *(struct Lisp_Float **)&fblk->floats[i].data = float_free_list; 5264 *(struct Lisp_Float **)&fblk->floats[i].data = float_free_list;
5046 float_free_list = &fblk->floats[i]; 5265 float_free_list = &fblk->floats[i];
5047#if GC_MARK_STACK
5048 float_free_list->type = Vdead;
5049#endif
5050 } 5266 }
5051 else 5267 else
5052 { 5268 {
5053 num_used++; 5269 num_used++;
5054 XUNMARK (fblk->floats[i].type); 5270 FLOAT_UNMARK (&fblk->floats[i]);
5055 } 5271 }
5056 lim = FLOAT_BLOCK_SIZE; 5272 lim = FLOAT_BLOCK_SIZE;
5057 /* If this block contains only free floats and we have already 5273 /* If this block contains only free floats and we have already
@@ -5062,7 +5278,7 @@ gc_sweep ()
5062 *fprev = fblk->next; 5278 *fprev = fblk->next;
5063 /* Unhook from the free list. */ 5279 /* Unhook from the free list. */
5064 float_free_list = *(struct Lisp_Float **) &fblk->floats[0].data; 5280 float_free_list = *(struct Lisp_Float **) &fblk->floats[0].data;
5065 lisp_free (fblk); 5281 lisp_align_free (fblk);
5066 n_float_blocks--; 5282 n_float_blocks--;
5067 } 5283 }
5068 else 5284 else
@@ -5373,6 +5589,9 @@ init_alloc_once ()
5373 pure_bytes_used = 0; 5589 pure_bytes_used = 0;
5374 pure_bytes_used_before_overflow = 0; 5590 pure_bytes_used_before_overflow = 0;
5375 5591
5592 /* Initialize the list of free aligned blocks. */
5593 free_ablock = NULL;
5594
5376#if GC_MARK_STACK || defined GC_MALLOC_CHECK 5595#if GC_MARK_STACK || defined GC_MALLOC_CHECK
5377 mem_init (); 5596 mem_init ();
5378 Vdead = make_pure_string ("DEAD", 4, 4, 0); 5597 Vdead = make_pure_string ("DEAD", 4, 4, 0);