diff options
| author | Stefan Monnier | 2003-07-04 20:19:06 +0000 |
|---|---|---|
| committer | Stefan Monnier | 2003-07-04 20:19:06 +0000 |
| commit | ab6780cd2f7e0da50b92261010279981a0993ee4 (patch) | |
| tree | 4131fad08ccc1ebcb03b51fdb327a7a17c1f9005 /src/alloc.c | |
| parent | d320e9f3063624c097228fbd62d283aefef80fb4 (diff) | |
| download | emacs-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.c | 291 |
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. */ | ||
| 660 | struct 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. */ | ||
| 683 | struct 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. */ | ||
| 704 | static 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. */ | ||
| 709 | static POINTER_TYPE * | ||
| 710 | lisp_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 | |||
| 797 | static void | ||
| 798 | lisp_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 | ||
| 1911 | struct float_block | 2125 | struct 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 | ||
| 1919 | struct float_block *float_block; | 2144 | struct float_block *float_block; |
| @@ -1936,10 +2161,11 @@ struct Lisp_Float *float_free_list; | |||
| 1936 | void | 2161 | void |
| 1937 | init_float () | 2162 | init_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); |