diff options
| author | Eli Zaretskii | 2012-11-13 16:17:18 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2012-11-13 16:17:18 +0200 |
| commit | 3c4ca7155293ffc2d04708007131bcbc882d8913 (patch) | |
| tree | 61787be8cd43b6fb3d5159852fbd186eea404de7 /src/alloc.c | |
| parent | 5ade42a5114255c43117065494b96d480c1e1588 (diff) | |
| parent | c708524567662c8911c5ab2695acc7bda0383705 (diff) | |
| download | emacs-3c4ca7155293ffc2d04708007131bcbc882d8913.tar.gz emacs-3c4ca7155293ffc2d04708007131bcbc882d8913.zip | |
Merge from trunk.
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 193 |
1 files changed, 122 insertions, 71 deletions
diff --git a/src/alloc.c b/src/alloc.c index 5bb528c64ab..a66a752f5dc 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -216,23 +216,19 @@ static Lisp_Object Qpost_gc_hook; | |||
| 216 | static void mark_terminals (void); | 216 | static void mark_terminals (void); |
| 217 | static void gc_sweep (void); | 217 | static void gc_sweep (void); |
| 218 | static Lisp_Object make_pure_vector (ptrdiff_t); | 218 | static Lisp_Object make_pure_vector (ptrdiff_t); |
| 219 | static void mark_glyph_matrix (struct glyph_matrix *); | ||
| 220 | static void mark_face_cache (struct face_cache *); | ||
| 221 | static void mark_buffer (struct buffer *); | 219 | static void mark_buffer (struct buffer *); |
| 222 | 220 | ||
| 223 | #if !defined REL_ALLOC || defined SYSTEM_MALLOC | 221 | #if !defined REL_ALLOC || defined SYSTEM_MALLOC |
| 224 | static void refill_memory_reserve (void); | 222 | static void refill_memory_reserve (void); |
| 225 | #endif | 223 | #endif |
| 226 | static struct Lisp_String *allocate_string (void); | ||
| 227 | static void compact_small_strings (void); | 224 | static void compact_small_strings (void); |
| 228 | static void free_large_strings (void); | 225 | static void free_large_strings (void); |
| 229 | static void sweep_strings (void); | ||
| 230 | static void free_misc (Lisp_Object); | 226 | static void free_misc (Lisp_Object); |
| 231 | extern Lisp_Object which_symbols (Lisp_Object, EMACS_INT) EXTERNALLY_VISIBLE; | 227 | extern Lisp_Object which_symbols (Lisp_Object, EMACS_INT) EXTERNALLY_VISIBLE; |
| 232 | 228 | ||
| 233 | /* When scanning the C stack for live Lisp objects, Emacs keeps track | 229 | /* When scanning the C stack for live Lisp objects, Emacs keeps track of |
| 234 | of what memory allocated via lisp_malloc is intended for what | 230 | what memory allocated via lisp_malloc and lisp_align_malloc is intended |
| 235 | purpose. This enumeration specifies the type of memory. */ | 231 | for what purpose. This enumeration specifies the type of memory. */ |
| 236 | 232 | ||
| 237 | enum mem_type | 233 | enum mem_type |
| 238 | { | 234 | { |
| @@ -243,10 +239,9 @@ enum mem_type | |||
| 243 | MEM_TYPE_MISC, | 239 | MEM_TYPE_MISC, |
| 244 | MEM_TYPE_SYMBOL, | 240 | MEM_TYPE_SYMBOL, |
| 245 | MEM_TYPE_FLOAT, | 241 | MEM_TYPE_FLOAT, |
| 246 | /* We used to keep separate mem_types for subtypes of vectors such as | 242 | /* Since all non-bool pseudovectors are small enough to be |
| 247 | process, hash_table, frame, terminal, and window, but we never made | 243 | allocated from vector blocks, this memory type denotes |
| 248 | use of the distinction, so it only caused source-code complexity | 244 | large regular vectors and large bool pseudovectors. */ |
| 249 | and runtime slowdown. Minor but pointless. */ | ||
| 250 | MEM_TYPE_VECTORLIKE, | 245 | MEM_TYPE_VECTORLIKE, |
| 251 | /* Special type to denote vector blocks. */ | 246 | /* Special type to denote vector blocks. */ |
| 252 | MEM_TYPE_VECTOR_BLOCK, | 247 | MEM_TYPE_VECTOR_BLOCK, |
| @@ -254,9 +249,6 @@ enum mem_type | |||
| 254 | MEM_TYPE_SPARE | 249 | MEM_TYPE_SPARE |
| 255 | }; | 250 | }; |
| 256 | 251 | ||
| 257 | static void *lisp_malloc (size_t, enum mem_type); | ||
| 258 | |||
| 259 | |||
| 260 | #if GC_MARK_STACK || defined GC_MALLOC_CHECK | 252 | #if GC_MARK_STACK || defined GC_MALLOC_CHECK |
| 261 | 253 | ||
| 262 | #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES | 254 | #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES |
| @@ -2040,7 +2032,7 @@ LENGTH must be a number. INIT matters only in whether it is t or nil. */) | |||
| 2040 | val = Fmake_vector (make_number (length_in_elts + extra_bool_elts), Qnil); | 2032 | val = Fmake_vector (make_number (length_in_elts + extra_bool_elts), Qnil); |
| 2041 | 2033 | ||
| 2042 | /* No Lisp_Object to trace in there. */ | 2034 | /* No Lisp_Object to trace in there. */ |
| 2043 | XSETPVECTYPESIZE (XVECTOR (val), PVEC_BOOL_VECTOR, 0); | 2035 | XSETPVECTYPESIZE (XVECTOR (val), PVEC_BOOL_VECTOR, 0, 0); |
| 2044 | 2036 | ||
| 2045 | p = XBOOL_VECTOR (val); | 2037 | p = XBOOL_VECTOR (val); |
| 2046 | p->size = XFASTINT (length); | 2038 | p->size = XFASTINT (length); |
| @@ -2619,19 +2611,54 @@ verify (VECTOR_BLOCK_SIZE <= (1 << PSEUDOVECTOR_SIZE_BITS)); | |||
| 2619 | 2611 | ||
| 2620 | #define VINDEX(nbytes) (((nbytes) - VBLOCK_BYTES_MIN) / roundup_size) | 2612 | #define VINDEX(nbytes) (((nbytes) - VBLOCK_BYTES_MIN) / roundup_size) |
| 2621 | 2613 | ||
| 2614 | /* Get and set the next field in block-allocated vectorlike objects on | ||
| 2615 | the free list. Doing it this way respects C's aliasing rules. | ||
| 2616 | We could instead make 'contents' a union, but that would mean | ||
| 2617 | changes everywhere that the code uses 'contents'. */ | ||
| 2618 | static struct Lisp_Vector * | ||
| 2619 | next_in_free_list (struct Lisp_Vector *v) | ||
| 2620 | { | ||
| 2621 | intptr_t i = XLI (v->contents[0]); | ||
| 2622 | return (struct Lisp_Vector *) i; | ||
| 2623 | } | ||
| 2624 | static void | ||
| 2625 | set_next_in_free_list (struct Lisp_Vector *v, struct Lisp_Vector *next) | ||
| 2626 | { | ||
| 2627 | v->contents[0] = XIL ((intptr_t) next); | ||
| 2628 | } | ||
| 2629 | |||
| 2622 | /* Common shortcut to setup vector on a free list. */ | 2630 | /* Common shortcut to setup vector on a free list. */ |
| 2623 | 2631 | ||
| 2624 | #define SETUP_ON_FREE_LIST(v, nbytes, index) \ | 2632 | #define SETUP_ON_FREE_LIST(v, nbytes, tmp) \ |
| 2625 | do { \ | 2633 | do { \ |
| 2626 | XSETPVECTYPESIZE (v, PVEC_FREE, nbytes); \ | 2634 | (tmp) = ((nbytes - header_size) / word_size); \ |
| 2627 | eassert ((nbytes) % roundup_size == 0); \ | 2635 | XSETPVECTYPESIZE (v, PVEC_FREE, 0, (tmp)); \ |
| 2628 | (index) = VINDEX (nbytes); \ | 2636 | eassert ((nbytes) % roundup_size == 0); \ |
| 2629 | eassert ((index) < VECTOR_MAX_FREE_LIST_INDEX); \ | 2637 | (tmp) = VINDEX (nbytes); \ |
| 2630 | (v)->header.next.vector = vector_free_lists[index]; \ | 2638 | eassert ((tmp) < VECTOR_MAX_FREE_LIST_INDEX); \ |
| 2631 | vector_free_lists[index] = (v); \ | 2639 | set_next_in_free_list (v, vector_free_lists[tmp]); \ |
| 2632 | total_free_vector_slots += (nbytes) / word_size; \ | 2640 | vector_free_lists[tmp] = (v); \ |
| 2641 | total_free_vector_slots += (nbytes) / word_size; \ | ||
| 2633 | } while (0) | 2642 | } while (0) |
| 2634 | 2643 | ||
| 2644 | /* This internal type is used to maintain the list of large vectors | ||
| 2645 | which are allocated at their own, e.g. outside of vector blocks. */ | ||
| 2646 | |||
| 2647 | struct large_vector | ||
| 2648 | { | ||
| 2649 | union { | ||
| 2650 | struct large_vector *vector; | ||
| 2651 | #if USE_LSB_TAG | ||
| 2652 | /* We need to maintain ROUNDUP_SIZE alignment for the vector member. */ | ||
| 2653 | unsigned char c[vroundup (sizeof (struct large_vector *))]; | ||
| 2654 | #endif | ||
| 2655 | } next; | ||
| 2656 | struct Lisp_Vector v; | ||
| 2657 | }; | ||
| 2658 | |||
| 2659 | /* This internal type is used to maintain an underlying storage | ||
| 2660 | for small vectors. */ | ||
| 2661 | |||
| 2635 | struct vector_block | 2662 | struct vector_block |
| 2636 | { | 2663 | { |
| 2637 | char data[VECTOR_BLOCK_BYTES]; | 2664 | char data[VECTOR_BLOCK_BYTES]; |
| @@ -2649,7 +2676,7 @@ static struct Lisp_Vector *vector_free_lists[VECTOR_MAX_FREE_LIST_INDEX]; | |||
| 2649 | 2676 | ||
| 2650 | /* Singly-linked list of large vectors. */ | 2677 | /* Singly-linked list of large vectors. */ |
| 2651 | 2678 | ||
| 2652 | static struct Lisp_Vector *large_vectors; | 2679 | static struct large_vector *large_vectors; |
| 2653 | 2680 | ||
| 2654 | /* The only vector with 0 slots, allocated from pure space. */ | 2681 | /* The only vector with 0 slots, allocated from pure space. */ |
| 2655 | 2682 | ||
| @@ -2693,7 +2720,7 @@ init_vectors (void) | |||
| 2693 | static struct Lisp_Vector * | 2720 | static struct Lisp_Vector * |
| 2694 | allocate_vector_from_block (size_t nbytes) | 2721 | allocate_vector_from_block (size_t nbytes) |
| 2695 | { | 2722 | { |
| 2696 | struct Lisp_Vector *vector, *rest; | 2723 | struct Lisp_Vector *vector; |
| 2697 | struct vector_block *block; | 2724 | struct vector_block *block; |
| 2698 | size_t index, restbytes; | 2725 | size_t index, restbytes; |
| 2699 | 2726 | ||
| @@ -2706,8 +2733,7 @@ allocate_vector_from_block (size_t nbytes) | |||
| 2706 | if (vector_free_lists[index]) | 2733 | if (vector_free_lists[index]) |
| 2707 | { | 2734 | { |
| 2708 | vector = vector_free_lists[index]; | 2735 | vector = vector_free_lists[index]; |
| 2709 | vector_free_lists[index] = vector->header.next.vector; | 2736 | vector_free_lists[index] = next_in_free_list (vector); |
| 2710 | vector->header.next.nbytes = nbytes; | ||
| 2711 | total_free_vector_slots -= nbytes / word_size; | 2737 | total_free_vector_slots -= nbytes / word_size; |
| 2712 | return vector; | 2738 | return vector; |
| 2713 | } | 2739 | } |
| @@ -2721,16 +2747,14 @@ allocate_vector_from_block (size_t nbytes) | |||
| 2721 | { | 2747 | { |
| 2722 | /* This vector is larger than requested. */ | 2748 | /* This vector is larger than requested. */ |
| 2723 | vector = vector_free_lists[index]; | 2749 | vector = vector_free_lists[index]; |
| 2724 | vector_free_lists[index] = vector->header.next.vector; | 2750 | vector_free_lists[index] = next_in_free_list (vector); |
| 2725 | vector->header.next.nbytes = nbytes; | ||
| 2726 | total_free_vector_slots -= nbytes / word_size; | 2751 | total_free_vector_slots -= nbytes / word_size; |
| 2727 | 2752 | ||
| 2728 | /* Excess bytes are used for the smaller vector, | 2753 | /* Excess bytes are used for the smaller vector, |
| 2729 | which should be set on an appropriate free list. */ | 2754 | which should be set on an appropriate free list. */ |
| 2730 | restbytes = index * roundup_size + VBLOCK_BYTES_MIN - nbytes; | 2755 | restbytes = index * roundup_size + VBLOCK_BYTES_MIN - nbytes; |
| 2731 | eassert (restbytes % roundup_size == 0); | 2756 | eassert (restbytes % roundup_size == 0); |
| 2732 | rest = ADVANCE (vector, nbytes); | 2757 | SETUP_ON_FREE_LIST (ADVANCE (vector, nbytes), restbytes, index); |
| 2733 | SETUP_ON_FREE_LIST (rest, restbytes, index); | ||
| 2734 | return vector; | 2758 | return vector; |
| 2735 | } | 2759 | } |
| 2736 | 2760 | ||
| @@ -2739,7 +2763,6 @@ allocate_vector_from_block (size_t nbytes) | |||
| 2739 | 2763 | ||
| 2740 | /* New vector will be at the beginning of this block. */ | 2764 | /* New vector will be at the beginning of this block. */ |
| 2741 | vector = (struct Lisp_Vector *) block->data; | 2765 | vector = (struct Lisp_Vector *) block->data; |
| 2742 | vector->header.next.nbytes = nbytes; | ||
| 2743 | 2766 | ||
| 2744 | /* If the rest of space from this block is large enough | 2767 | /* If the rest of space from this block is large enough |
| 2745 | for one-slot vector at least, set up it on a free list. */ | 2768 | for one-slot vector at least, set up it on a free list. */ |
| @@ -2747,11 +2770,10 @@ allocate_vector_from_block (size_t nbytes) | |||
| 2747 | if (restbytes >= VBLOCK_BYTES_MIN) | 2770 | if (restbytes >= VBLOCK_BYTES_MIN) |
| 2748 | { | 2771 | { |
| 2749 | eassert (restbytes % roundup_size == 0); | 2772 | eassert (restbytes % roundup_size == 0); |
| 2750 | rest = ADVANCE (vector, nbytes); | 2773 | SETUP_ON_FREE_LIST (ADVANCE (vector, nbytes), restbytes, index); |
| 2751 | SETUP_ON_FREE_LIST (rest, restbytes, index); | ||
| 2752 | } | 2774 | } |
| 2753 | return vector; | 2775 | return vector; |
| 2754 | } | 2776 | } |
| 2755 | 2777 | ||
| 2756 | /* Nonzero if VECTOR pointer is valid pointer inside BLOCK. */ | 2778 | /* Nonzero if VECTOR pointer is valid pointer inside BLOCK. */ |
| 2757 | 2779 | ||
| @@ -2759,15 +2781,30 @@ allocate_vector_from_block (size_t nbytes) | |||
| 2759 | ((char *) (vector) <= (block)->data \ | 2781 | ((char *) (vector) <= (block)->data \ |
| 2760 | + VECTOR_BLOCK_BYTES - VBLOCK_BYTES_MIN) | 2782 | + VECTOR_BLOCK_BYTES - VBLOCK_BYTES_MIN) |
| 2761 | 2783 | ||
| 2762 | /* Number of bytes used by vector-block-allocated object. This is the only | 2784 | /* Return the memory footprint of V in bytes. */ |
| 2763 | place where we actually use the `nbytes' field of the vector-header. | ||
| 2764 | I.e. we could get rid of the `nbytes' field by computing it based on the | ||
| 2765 | vector-type. */ | ||
| 2766 | 2785 | ||
| 2767 | #define PSEUDOVECTOR_NBYTES(vector) \ | 2786 | static ptrdiff_t |
| 2768 | (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FREE) \ | 2787 | vector_nbytes (struct Lisp_Vector *v) |
| 2769 | ? vector->header.size & PSEUDOVECTOR_SIZE_MASK \ | 2788 | { |
| 2770 | : vector->header.next.nbytes) | 2789 | ptrdiff_t size = v->header.size & ~ARRAY_MARK_FLAG; |
| 2790 | |||
| 2791 | if (size & PSEUDOVECTOR_FLAG) | ||
| 2792 | { | ||
| 2793 | if (PSEUDOVECTOR_TYPEP (&v->header, PVEC_BOOL_VECTOR)) | ||
| 2794 | size = (bool_header_size | ||
| 2795 | + (((struct Lisp_Bool_Vector *) v)->size | ||
| 2796 | + BOOL_VECTOR_BITS_PER_CHAR - 1) | ||
| 2797 | / BOOL_VECTOR_BITS_PER_CHAR); | ||
| 2798 | else | ||
| 2799 | size = (header_size | ||
| 2800 | + ((size & PSEUDOVECTOR_SIZE_MASK) | ||
| 2801 | + ((size & PSEUDOVECTOR_REST_MASK) | ||
| 2802 | >> PSEUDOVECTOR_SIZE_BITS)) * word_size); | ||
| 2803 | } | ||
| 2804 | else | ||
| 2805 | size = header_size + size * word_size; | ||
| 2806 | return vroundup (size); | ||
| 2807 | } | ||
| 2771 | 2808 | ||
| 2772 | /* Reclaim space used by unmarked vectors. */ | 2809 | /* Reclaim space used by unmarked vectors. */ |
| 2773 | 2810 | ||
| @@ -2775,7 +2812,8 @@ static void | |||
| 2775 | sweep_vectors (void) | 2812 | sweep_vectors (void) |
| 2776 | { | 2813 | { |
| 2777 | struct vector_block *block = vector_blocks, **bprev = &vector_blocks; | 2814 | struct vector_block *block = vector_blocks, **bprev = &vector_blocks; |
| 2778 | struct Lisp_Vector *vector, *next, **vprev = &large_vectors; | 2815 | struct large_vector *lv, **lvprev = &large_vectors; |
| 2816 | struct Lisp_Vector *vector, *next; | ||
| 2779 | 2817 | ||
| 2780 | total_vectors = total_vector_slots = total_free_vector_slots = 0; | 2818 | total_vectors = total_vector_slots = total_free_vector_slots = 0; |
| 2781 | memset (vector_free_lists, 0, sizeof (vector_free_lists)); | 2819 | memset (vector_free_lists, 0, sizeof (vector_free_lists)); |
| @@ -2785,6 +2823,7 @@ sweep_vectors (void) | |||
| 2785 | for (block = vector_blocks; block; block = *bprev) | 2823 | for (block = vector_blocks; block; block = *bprev) |
| 2786 | { | 2824 | { |
| 2787 | bool free_this_block = 0; | 2825 | bool free_this_block = 0; |
| 2826 | ptrdiff_t nbytes; | ||
| 2788 | 2827 | ||
| 2789 | for (vector = (struct Lisp_Vector *) block->data; | 2828 | for (vector = (struct Lisp_Vector *) block->data; |
| 2790 | VECTOR_IN_BLOCK (vector, block); vector = next) | 2829 | VECTOR_IN_BLOCK (vector, block); vector = next) |
| @@ -2793,14 +2832,16 @@ sweep_vectors (void) | |||
| 2793 | { | 2832 | { |
| 2794 | VECTOR_UNMARK (vector); | 2833 | VECTOR_UNMARK (vector); |
| 2795 | total_vectors++; | 2834 | total_vectors++; |
| 2796 | total_vector_slots += vector->header.next.nbytes / word_size; | 2835 | nbytes = vector_nbytes (vector); |
| 2797 | next = ADVANCE (vector, vector->header.next.nbytes); | 2836 | total_vector_slots += nbytes / word_size; |
| 2837 | next = ADVANCE (vector, nbytes); | ||
| 2798 | } | 2838 | } |
| 2799 | else | 2839 | else |
| 2800 | { | 2840 | { |
| 2801 | ptrdiff_t nbytes = PSEUDOVECTOR_NBYTES (vector); | 2841 | ptrdiff_t total_bytes; |
| 2802 | ptrdiff_t total_bytes = nbytes; | ||
| 2803 | 2842 | ||
| 2843 | nbytes = vector_nbytes (vector); | ||
| 2844 | total_bytes = nbytes; | ||
| 2804 | next = ADVANCE (vector, nbytes); | 2845 | next = ADVANCE (vector, nbytes); |
| 2805 | 2846 | ||
| 2806 | /* While NEXT is not marked, try to coalesce with VECTOR, | 2847 | /* While NEXT is not marked, try to coalesce with VECTOR, |
| @@ -2810,7 +2851,7 @@ sweep_vectors (void) | |||
| 2810 | { | 2851 | { |
| 2811 | if (VECTOR_MARKED_P (next)) | 2852 | if (VECTOR_MARKED_P (next)) |
| 2812 | break; | 2853 | break; |
| 2813 | nbytes = PSEUDOVECTOR_NBYTES (next); | 2854 | nbytes = vector_nbytes (next); |
| 2814 | total_bytes += nbytes; | 2855 | total_bytes += nbytes; |
| 2815 | next = ADVANCE (next, nbytes); | 2856 | next = ADVANCE (next, nbytes); |
| 2816 | } | 2857 | } |
| @@ -2844,8 +2885,9 @@ sweep_vectors (void) | |||
| 2844 | 2885 | ||
| 2845 | /* Sweep large vectors. */ | 2886 | /* Sweep large vectors. */ |
| 2846 | 2887 | ||
| 2847 | for (vector = large_vectors; vector; vector = *vprev) | 2888 | for (lv = large_vectors; lv; lv = *lvprev) |
| 2848 | { | 2889 | { |
| 2890 | vector = &lv->v; | ||
| 2849 | if (VECTOR_MARKED_P (vector)) | 2891 | if (VECTOR_MARKED_P (vector)) |
| 2850 | { | 2892 | { |
| 2851 | VECTOR_UNMARK (vector); | 2893 | VECTOR_UNMARK (vector); |
| @@ -2867,12 +2909,12 @@ sweep_vectors (void) | |||
| 2867 | else | 2909 | else |
| 2868 | total_vector_slots | 2910 | total_vector_slots |
| 2869 | += header_size / word_size + vector->header.size; | 2911 | += header_size / word_size + vector->header.size; |
| 2870 | vprev = &vector->header.next.vector; | 2912 | lvprev = &lv->next.vector; |
| 2871 | } | 2913 | } |
| 2872 | else | 2914 | else |
| 2873 | { | 2915 | { |
| 2874 | *vprev = vector->header.next.vector; | 2916 | *lvprev = lv->next.vector; |
| 2875 | lisp_free (vector); | 2917 | lisp_free (lv); |
| 2876 | } | 2918 | } |
| 2877 | } | 2919 | } |
| 2878 | } | 2920 | } |
| @@ -2904,9 +2946,12 @@ allocate_vectorlike (ptrdiff_t len) | |||
| 2904 | p = allocate_vector_from_block (vroundup (nbytes)); | 2946 | p = allocate_vector_from_block (vroundup (nbytes)); |
| 2905 | else | 2947 | else |
| 2906 | { | 2948 | { |
| 2907 | p = lisp_malloc (nbytes, MEM_TYPE_VECTORLIKE); | 2949 | struct large_vector *lv |
| 2908 | p->header.next.vector = large_vectors; | 2950 | = lisp_malloc (sizeof (*lv) + (len - 1) * word_size, |
| 2909 | large_vectors = p; | 2951 | MEM_TYPE_VECTORLIKE); |
| 2952 | lv->next.vector = large_vectors; | ||
| 2953 | large_vectors = lv; | ||
| 2954 | p = &lv->v; | ||
| 2910 | } | 2955 | } |
| 2911 | 2956 | ||
| 2912 | #ifdef DOUG_LEA_MALLOC | 2957 | #ifdef DOUG_LEA_MALLOC |
| @@ -2943,16 +2988,21 @@ allocate_vector (EMACS_INT len) | |||
| 2943 | /* Allocate other vector-like structures. */ | 2988 | /* Allocate other vector-like structures. */ |
| 2944 | 2989 | ||
| 2945 | struct Lisp_Vector * | 2990 | struct Lisp_Vector * |
| 2946 | allocate_pseudovector (int memlen, int lisplen, int tag) | 2991 | allocate_pseudovector (int memlen, int lisplen, enum pvec_type tag) |
| 2947 | { | 2992 | { |
| 2948 | struct Lisp_Vector *v = allocate_vectorlike (memlen); | 2993 | struct Lisp_Vector *v = allocate_vectorlike (memlen); |
| 2949 | int i; | 2994 | int i; |
| 2950 | 2995 | ||
| 2996 | /* Catch bogus values. */ | ||
| 2997 | eassert (tag <= PVEC_FONT); | ||
| 2998 | eassert (memlen - lisplen <= (1 << PSEUDOVECTOR_REST_BITS) - 1); | ||
| 2999 | eassert (lisplen <= (1 << PSEUDOVECTOR_SIZE_BITS) - 1); | ||
| 3000 | |||
| 2951 | /* Only the first lisplen slots will be traced normally by the GC. */ | 3001 | /* Only the first lisplen slots will be traced normally by the GC. */ |
| 2952 | for (i = 0; i < lisplen; ++i) | 3002 | for (i = 0; i < lisplen; ++i) |
| 2953 | v->contents[i] = Qnil; | 3003 | v->contents[i] = Qnil; |
| 2954 | 3004 | ||
| 2955 | XSETPVECTYPESIZE (v, tag, lisplen); | 3005 | XSETPVECTYPESIZE (v, tag, lisplen, memlen - lisplen); |
| 2956 | return v; | 3006 | return v; |
| 2957 | } | 3007 | } |
| 2958 | 3008 | ||
| @@ -2961,10 +3011,9 @@ allocate_buffer (void) | |||
| 2961 | { | 3011 | { |
| 2962 | struct buffer *b = lisp_malloc (sizeof *b, MEM_TYPE_BUFFER); | 3012 | struct buffer *b = lisp_malloc (sizeof *b, MEM_TYPE_BUFFER); |
| 2963 | 3013 | ||
| 2964 | XSETPVECTYPESIZE (b, PVEC_BUFFER, (offsetof (struct buffer, own_text) | 3014 | BUFFER_PVEC_INIT (b); |
| 2965 | - header_size) / word_size); | ||
| 2966 | /* Put B on the chain of all buffers including killed ones. */ | 3015 | /* Put B on the chain of all buffers including killed ones. */ |
| 2967 | b->header.next.buffer = all_buffers; | 3016 | b->next = all_buffers; |
| 2968 | all_buffers = b; | 3017 | all_buffers = b; |
| 2969 | /* Note that the rest fields of B are not initialized. */ | 3018 | /* Note that the rest fields of B are not initialized. */ |
| 2970 | return b; | 3019 | return b; |
| @@ -4068,16 +4117,15 @@ live_vector_p (struct mem_node *m, void *p) | |||
| 4068 | while (VECTOR_IN_BLOCK (vector, block) | 4117 | while (VECTOR_IN_BLOCK (vector, block) |
| 4069 | && vector <= (struct Lisp_Vector *) p) | 4118 | && vector <= (struct Lisp_Vector *) p) |
| 4070 | { | 4119 | { |
| 4071 | if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FREE)) | 4120 | if (!PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FREE) && vector == p) |
| 4072 | vector = ADVANCE (vector, (vector->header.size | ||
| 4073 | & PSEUDOVECTOR_SIZE_MASK)); | ||
| 4074 | else if (vector == p) | ||
| 4075 | return 1; | 4121 | return 1; |
| 4076 | else | 4122 | else |
| 4077 | vector = ADVANCE (vector, vector->header.next.nbytes); | 4123 | vector = ADVANCE (vector, vector_nbytes (vector)); |
| 4078 | } | 4124 | } |
| 4079 | } | 4125 | } |
| 4080 | else if (m->type == MEM_TYPE_VECTORLIKE && p == m->start) | 4126 | else if (m->type == MEM_TYPE_VECTORLIKE |
| 4127 | && (char *) p == ((char *) m->start | ||
| 4128 | + offsetof (struct large_vector, v))) | ||
| 4081 | /* This memory node corresponds to a large vector. */ | 4129 | /* This memory node corresponds to a large vector. */ |
| 4082 | return 1; | 4130 | return 1; |
| 4083 | return 0; | 4131 | return 0; |
| @@ -5687,7 +5735,7 @@ mark_object (Lisp_Object arg) | |||
| 5687 | 5735 | ||
| 5688 | if (ptr->header.size & PSEUDOVECTOR_FLAG) | 5736 | if (ptr->header.size & PSEUDOVECTOR_FLAG) |
| 5689 | pvectype = ((ptr->header.size & PVEC_TYPE_MASK) | 5737 | pvectype = ((ptr->header.size & PVEC_TYPE_MASK) |
| 5690 | >> PSEUDOVECTOR_SIZE_BITS); | 5738 | >> PSEUDOVECTOR_AREA_BITS); |
| 5691 | else | 5739 | else |
| 5692 | pvectype = PVEC_NORMAL_VECTOR; | 5740 | pvectype = PVEC_NORMAL_VECTOR; |
| 5693 | 5741 | ||
| @@ -5766,6 +5814,9 @@ mark_object (Lisp_Object arg) | |||
| 5766 | struct Lisp_Hash_Table *h = (struct Lisp_Hash_Table *) ptr; | 5814 | struct Lisp_Hash_Table *h = (struct Lisp_Hash_Table *) ptr; |
| 5767 | 5815 | ||
| 5768 | mark_vectorlike (ptr); | 5816 | mark_vectorlike (ptr); |
| 5817 | mark_object (h->test.name); | ||
| 5818 | mark_object (h->test.user_hash_function); | ||
| 5819 | mark_object (h->test.user_cmp_function); | ||
| 5769 | /* If hash table is not weak, mark all keys and values. | 5820 | /* If hash table is not weak, mark all keys and values. |
| 5770 | For weak tables, mark only the vector. */ | 5821 | For weak tables, mark only the vector. */ |
| 5771 | if (NILP (h->weak)) | 5822 | if (NILP (h->weak)) |
| @@ -6317,7 +6368,7 @@ gc_sweep (void) | |||
| 6317 | for (buffer = all_buffers; buffer; buffer = *bprev) | 6368 | for (buffer = all_buffers; buffer; buffer = *bprev) |
| 6318 | if (!VECTOR_MARKED_P (buffer)) | 6369 | if (!VECTOR_MARKED_P (buffer)) |
| 6319 | { | 6370 | { |
| 6320 | *bprev = buffer->header.next.buffer; | 6371 | *bprev = buffer->next; |
| 6321 | lisp_free (buffer); | 6372 | lisp_free (buffer); |
| 6322 | } | 6373 | } |
| 6323 | else | 6374 | else |
| @@ -6326,7 +6377,7 @@ gc_sweep (void) | |||
| 6326 | /* Do not use buffer_(set|get)_intervals here. */ | 6377 | /* Do not use buffer_(set|get)_intervals here. */ |
| 6327 | buffer->text->intervals = balance_intervals (buffer->text->intervals); | 6378 | buffer->text->intervals = balance_intervals (buffer->text->intervals); |
| 6328 | total_buffers++; | 6379 | total_buffers++; |
| 6329 | bprev = &buffer->header.next.buffer; | 6380 | bprev = &buffer->next; |
| 6330 | } | 6381 | } |
| 6331 | } | 6382 | } |
| 6332 | 6383 | ||